From: Simon Pilgrim Date: Wed, 15 Mar 2017 16:22:24 +0000 (+0000) Subject: [SelectionDAG] Support BUILD_VECTOR implicit truncation in SelectionDAG::ComputeNumSi... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1d8ce502da4c015c44c4523ceb55ca551c554ed;p=llvm [SelectionDAG] Support BUILD_VECTOR implicit truncation in SelectionDAG::ComputeNumSignBits (PR32273) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297852 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 85747ac623b..026572222ea 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2906,9 +2906,20 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const { } case ISD::BUILD_VECTOR: - Tmp = ComputeNumSignBits(Op.getOperand(0), Depth + 1); - for (unsigned i = 1, e = Op.getNumOperands(); (i < e) && (Tmp > 1); ++i) - Tmp = std::min(Tmp, ComputeNumSignBits(Op.getOperand(i), Depth + 1)); + Tmp = VTBits; + for (unsigned i = 0, e = Op.getNumOperands(); (i < e) && (Tmp > 1); ++i) { + SDValue SrcOp = Op.getOperand(i); + Tmp2 = ComputeNumSignBits(Op.getOperand(i), Depth + 1); + + // BUILD_VECTOR can implicitly truncate sources, we must handle this. + if (SrcOp.getValueSizeInBits() != VTBits) { + assert(SrcOp.getValueSizeInBits() > VTBits && + "Expected BUILD_VECTOR implicit truncation"); + unsigned ExtraBits = SrcOp.getValueSizeInBits() - VTBits; + Tmp2 = (Tmp2 > ExtraBits ? Tmp2 - ExtraBits : 1); + } + Tmp = std::min(Tmp, Tmp2); + } return Tmp; case ISD::SIGN_EXTEND: diff --git a/test/CodeGen/AArch64/dag-numsignbits.ll b/test/CodeGen/AArch64/dag-numsignbits.ll index 246d0e6f2b8..217c3df77c9 100644 --- a/test/CodeGen/AArch64/dag-numsignbits.ll +++ b/test/CodeGen/AArch64/dag-numsignbits.ll @@ -6,10 +6,10 @@ define void @signbits_vXi1(<4 x i16> %a1) { ; CHECK-LABEL: signbits_vXi1 ; CHECK: cmgt v0.4h, v1.4h, v0.4h ; CHECK-NEXT: and v0.8b, v0.8b, v2.8b -; CHECK-NEXT: umov w8, v0.h[0] -; CHECK-NEXT: umov w9, v0.h[3] -; CHECK-NEXT: and w0, w8, #0x1 -; CHECK-NEXT: and w3, w9, #0x1 +; CHECK-NEXT: shl v0.4h, v0.4h, #15 +; CHECK-NEXT: sshr v0.4h, v0.4h, #15 +; CHECK-NEXT: umov w0, v0.h[0] +; CHECK-NEXT: umov w3, v0.h[3] ; CHECK-NEXT: mov w1, wzr ; CHECK-NEXT: mov w2, wzr ; CHECK-NEXT: b foo