From: Sanjay Patel Date: Fri, 16 Sep 2016 21:20:36 +0000 (+0000) Subject: [InstCombine] allow vector types for constant folding / computeKnownBits (PR24942) X-Git-Tag: llvmorg-4.0.0-rc1~9522 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c96f6db2463451a7e24992e6fe3fed9c7a1f1540;p=platform%2Fupstream%2Fllvm.git [InstCombine] allow vector types for constant folding / computeKnownBits (PR24942) computeKnownBits() already works for integer vectors, so allow vector types when calling that from InstCombine. I don't think the change to use m_APInt in computeKnownBits is strictly necessary because we do check for ConstantVector later, but it's more efficient to handle the splat case without needing to loop on vector elements. This should work with InstSimplify, but doesn't yet, so I made that a FIXME comment on the test for PR24942: https://llvm.org/bugs/show_bug.cgi?id=24942 Differential Revision: https://reviews.llvm.org/D24677 llvm-svn: 281777 --- diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e3ac4bb..df86a01 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1451,9 +1451,10 @@ void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne, KnownOne.getBitWidth() == BitWidth && "V, KnownOne and KnownZero should have same BitWidth"); - if (const ConstantInt *CI = dyn_cast(V)) { - // We know all of the bits for a constant! - KnownOne = CI->getValue(); + const APInt *C; + if (match(V, m_APInt(C))) { + // We know all of the bits for a scalar constant or a splat vector constant! + KnownOne = *C; KnownZero = ~KnownOne; return; } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 12c42ce..54f8b72 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2859,13 +2859,14 @@ bool InstCombiner::run() { // In general, it is possible for computeKnownBits to determine all bits in // a value even when the operands are not all constants. - if (ExpensiveCombines && !I->use_empty() && I->getType()->isIntegerTy()) { - unsigned BitWidth = I->getType()->getScalarSizeInBits(); + Type *Ty = I->getType(); + if (ExpensiveCombines && !I->use_empty() && Ty->isIntOrIntVectorTy()) { + unsigned BitWidth = Ty->getScalarSizeInBits(); APInt KnownZero(BitWidth, 0); APInt KnownOne(BitWidth, 0); computeKnownBits(I, KnownZero, KnownOne, /*Depth*/0, I); if ((KnownZero | KnownOne).isAllOnesValue()) { - Constant *C = ConstantInt::get(I->getContext(), KnownOne); + Constant *C = ConstantInt::get(Ty, KnownOne); DEBUG(dbgs() << "IC: ConstFold (all bits known) to: " << *C << " from: " << *I << '\n'); diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll index cf2390c..e450128 100644 --- a/llvm/test/Transforms/InstCombine/and.ll +++ b/llvm/test/Transforms/InstCombine/and.ll @@ -414,3 +414,14 @@ define i32 @test34(i32 %A, i32 %B) { ret i32 %tmp.4 } +; FIXME: This test should only need -instsimplify (ValueTracking / computeKnownBits), not -instcombine. + +define <2 x i32> @PR24942(<2 x i32> %x) { +; CHECK-LABEL: @PR24942( +; CHECK-NEXT: ret <2 x i32> zeroinitializer +; + %lshr = lshr <2 x i32> %x, + %and = and <2 x i32> %lshr, + ret <2 x i32> %and +} + diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll index 66bec7d..eaa45bb 100644 --- a/llvm/test/Transforms/InstCombine/trunc.ll +++ b/llvm/test/Transforms/InstCombine/trunc.ll @@ -437,9 +437,7 @@ define <8 x i16> @trunc_shl_v8i15_v8i32_15(<8 x i32> %a) { define <8 x i16> @trunc_shl_v8i16_v8i32_16(<8 x i32> %a) { ; CHECK-LABEL: @trunc_shl_v8i16_v8i32_16( -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i32> %a, -; CHECK-NEXT: [[CONV:%.*]] = trunc <8 x i32> [[SHL]] to <8 x i16> -; CHECK-NEXT: ret <8 x i16> [[CONV]] +; CHECK-NEXT: ret <8 x i16> zeroinitializer ; %shl = shl <8 x i32> %a, %conv = trunc <8 x i32> %shl to <8 x i16> @@ -448,9 +446,7 @@ define <8 x i16> @trunc_shl_v8i16_v8i32_16(<8 x i32> %a) { define <8 x i16> @trunc_shl_v8i16_v8i32_17(<8 x i32> %a) { ; CHECK-LABEL: @trunc_shl_v8i16_v8i32_17( -; CHECK-NEXT: [[SHL:%.*]] = shl <8 x i32> %a, -; CHECK-NEXT: [[CONV:%.*]] = trunc <8 x i32> [[SHL]] to <8 x i16> -; CHECK-NEXT: ret <8 x i16> [[CONV]] +; CHECK-NEXT: ret <8 x i16> zeroinitializer ; %shl = shl <8 x i32> %a, %conv = trunc <8 x i32> %shl to <8 x i16>