From 59183b91752aa6eda326d85f2e47584bf00a0ff7 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 16 Sep 2016 21:20:36 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281777 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ValueTracking.cpp | 7 ++++--- lib/Transforms/InstCombine/InstructionCombining.cpp | 7 ++++--- test/Transforms/InstCombine/and.ll | 11 +++++++++++ test/Transforms/InstCombine/trunc.ll | 8 ++------ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index e3ac4bb7831..df86a015569 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/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/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 12c42ce6472..54f8b722b7e 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/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/test/Transforms/InstCombine/and.ll b/test/Transforms/InstCombine/and.ll index cf2390c4bd1..e45012878ed 100644 --- a/test/Transforms/InstCombine/and.ll +++ b/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/test/Transforms/InstCombine/trunc.ll b/test/Transforms/InstCombine/trunc.ll index 66bec7db5be..eaa45bbb286 100644 --- a/test/Transforms/InstCombine/trunc.ll +++ b/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>