]> granicus.if.org Git - llvm/commitdiff
[InstCombine] allow vector types for constant folding / computeKnownBits (PR24942)
authorSanjay Patel <spatel@rotateright.com>
Fri, 16 Sep 2016 21:20:36 +0000 (21:20 +0000)
committerSanjay Patel <spatel@rotateright.com>
Fri, 16 Sep 2016 21:20:36 +0000 (21:20 +0000)
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
lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/and.ll
test/Transforms/InstCombine/trunc.ll

index e3ac4bb78311daacafa3c1f38a1b9b66e7ea084c..df86a015569c25d9d466d080bce1664e622a7bbf 100644 (file)
@@ -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<ConstantInt>(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;
   }
index 12c42ce6472d96533b8f7238a7fab430f222c627..54f8b722b7e95250802a1b2fc4381d311960e792 100644 (file)
@@ -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');
 
index cf2390c4bd1c56902f0eccd11b8a2de355a84903..e45012878ed5ddb3ce08083b6fff9696f0d81b78 100644 (file)
@@ -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, <i32 31, i32 31>
+  %and = and <2 x i32> %lshr, <i32 2, i32 2>
+  ret <2 x i32> %and
+}
+
index 66bec7db5be47f256fcfa3d6ada89839fb2330b0..eaa45bbb286c8d2012fa11c6db5422efec2e4b0c 100644 (file)
@@ -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, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
-; 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, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
   %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, <i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17>
-; 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, <i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17>
   %conv = trunc <8 x i32> %shl to <8 x i16>