From e9f7fa83d54cbb77e48b26685433a6777f613017 Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Sat, 17 Mar 2018 08:04:00 +0000 Subject: [PATCH] [SelectionDAG] Handle big endian target BITCAST in computeKnownBits() 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 llvm-svn: 327764 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 11 +++++----- llvm/test/CodeGen/SystemZ/dag-combine-03.ll | 29 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 llvm/test/CodeGen/SystemZ/dag-combine-03.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index aac7907..db355cf 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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) { @@ -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); } } @@ -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. diff --git a/llvm/test/CodeGen/SystemZ/dag-combine-03.ll b/llvm/test/CodeGen/SystemZ/dag-combine-03.ll new file mode 100644 index 0000000..bcb7528 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/dag-combine-03.ll @@ -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, + %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 +} -- 2.7.4