Skip to content

Commit

Permalink
[SelectionDAG] Handle big endian target BITCAST in computeKnownBits()
Browse files Browse the repository at this point in the history
The BITCAST handling in computeKnownBits() previously only worked for little
endian.

This patch reverses the iteration over elements for a big endian target which
allows this to work in this case also.

SystemZ test case.

Review: Eli Friedman
https://reviews.llvm.org/D44249

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327764 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
JonPsson committed Mar 17, 2018
1 parent 2755819 commit eb9d4e0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
11 changes: 5 additions & 6 deletions lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2363,10 +2363,7 @@ void SelectionDAG::computeKnownBits(SDValue Op, KnownBits &Known,
break;
}

// Support big-endian targets when it becomes useful.
bool IsLE = getDataLayout().isLittleEndian();
if (!IsLE)
break;

// Bitcast 'small element' vector to 'large element' scalar/vector.
if ((BitWidth % SubBitWidth) == 0) {
Expand All @@ -2385,8 +2382,9 @@ void SelectionDAG::computeKnownBits(SDValue Op, KnownBits &Known,
for (unsigned i = 0; i != SubScale; ++i) {
computeKnownBits(N0, Known2, SubDemandedElts.shl(i),
Depth + 1);
Known.One |= Known2.One.zext(BitWidth).shl(SubBitWidth * i);
Known.Zero |= Known2.Zero.zext(BitWidth).shl(SubBitWidth * i);
unsigned Shifts = IsLE ? i : SubScale - 1 - i;
Known.One |= Known2.One.zext(BitWidth).shl(SubBitWidth * Shifts);
Known.Zero |= Known2.Zero.zext(BitWidth).shl(SubBitWidth * Shifts);
}
}

Expand All @@ -2408,7 +2406,8 @@ void SelectionDAG::computeKnownBits(SDValue Op, KnownBits &Known,
Known.Zero.setAllBits(); Known.One.setAllBits();
for (unsigned i = 0; i != NumElts; ++i)
if (DemandedElts[i]) {
unsigned Offset = (i % SubScale) * BitWidth;
unsigned Shifts = IsLE ? i : NumElts - 1 - i;
unsigned Offset = (Shifts % SubScale) * BitWidth;
Known.One &= Known2.One.lshr(Offset).trunc(BitWidth);
Known.Zero &= Known2.Zero.lshr(Offset).trunc(BitWidth);
// If we don't know any bits, early out.
Expand Down
29 changes: 29 additions & 0 deletions test/CodeGen/SystemZ/dag-combine-03.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
; Test that DAGCombiner gets helped by getKnownBitsForTargetNode() when
; BITCAST nodes are involved on a big-endian target.
;
; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 < %s | FileCheck %s

define void @fun() {
entry:
br label %lab0

lab0:
%phi = phi i64 [ %sel, %lab0 ], [ 0, %entry ]
%add = add nuw nsw i64 %phi, 1
%cmp = icmp eq i64 %add, undef
%ins = insertelement <2 x i1> undef, i1 %cmp, i32 0
%xor = xor <2 x i1> %ins, <i1 true, i1 true>
%extr = extractelement <2 x i1> %xor, i32 0
; The EXTRACT_VECTOR_ELT is done first into an i32, and then AND:ed with
; 1. The AND is not actually necessary since the element contains a CC (i1)
; value. Test that the BITCAST nodes in the DAG when computing KnownBits is
; handled so that the AND is removed. If this succeeds, this results in a CHI
; instead of TMLL.

; CHECK-LABEL: # %bb.0:
; CHECK: chi
; CHECK-NOT: tmll
; CHECK: j
%sel = select i1 %extr, i64 %add, i64 0
br label %lab0
}

0 comments on commit eb9d4e0

Please sign in to comment.