[llvm] r268479 - [ConstantFolding, ValueTracking] Fold constants involving bitcasts of ConstantVector

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue May 3 23:13:34 PDT 2016


Author: majnemer
Date: Wed May  4 01:13:33 2016
New Revision: 268479

URL: http://llvm.org/viewvc/llvm-project?rev=268479&view=rev
Log:
[ConstantFolding, ValueTracking] Fold constants involving bitcasts of ConstantVector

We assumed that ConstantVectors would be rather uninteresting from the
perspective of analysis.  However, this is not the case due to a quirk
of how LLVM handles vectors of i1.  Vectors of i1 are not
ConstantDataVectors like vectors of i8, i16, i32 or i64 because i1's
SizeInBits differs from it's StoreSizeInBytes.  This leads to it being
categorized as a ConstantVector instead of a ConstantDataVector.

Instead, treat ConstantVector more uniformly.

This fixes PR27591.

Added:
    llvm/trunk/test/Transforms/InstCombine/pr20678.ll
Modified:
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/lib/Analysis/ValueTracking.cpp

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=268479&r1=268478&r2=268479&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Wed May  4 01:13:33 2016
@@ -78,20 +78,23 @@ Constant *FoldBitCast(Constant *C, Type
       C = ConstantExpr::getBitCast(C, SrcIVTy);
     }
 
-    ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(C);
-    if (!CDV)
-      return ConstantExpr::getBitCast(C, DestTy);
-
     // Now that we know that the input value is a vector of integers, just shift
     // and insert them into our result.
     unsigned BitShift = DL.getTypeAllocSizeInBits(SrcEltTy);
     APInt Result(IT->getBitWidth(), 0);
     for (unsigned i = 0; i != NumSrcElts; ++i) {
-      Result <<= BitShift;
+      Constant *Element;
       if (DL.isLittleEndian())
-        Result |= CDV->getElementAsInteger(NumSrcElts-i-1);
+        Element = C->getAggregateElement(NumSrcElts-i-1);
       else
-        Result |= CDV->getElementAsInteger(i);
+        Element = C->getAggregateElement(i);
+
+      auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
+      if (!ElementCI)
+        return ConstantExpr::getBitCast(C, DestTy);
+
+      Result <<= BitShift;
+      Result |= ElementCI->getValue().zextOrSelf(IT->getBitWidth());
     }
 
     return ConstantInt::get(IT, Result);

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=268479&r1=268478&r2=268479&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Wed May  4 01:13:33 2016
@@ -1405,8 +1405,7 @@ void computeKnownBits(Value *V, APInt &K
     return;
   }
   // Handle a constant vector by taking the intersection of the known bits of
-  // each element.  There is no real need to handle ConstantVector here, because
-  // we don't handle undef in any particularly useful way.
+  // each element.
   if (ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) {
     // We know that CDS must be a vector of integers. Take the intersection of
     // each element.
@@ -1417,6 +1416,26 @@ void computeKnownBits(Value *V, APInt &K
       KnownZero &= ~Elt;
       KnownOne &= Elt;
     }
+    return;
+  }
+
+  if (auto *CV = dyn_cast<ConstantVector>(V)) {
+    // We know that CV must be a vector of integers. Take the intersection of
+    // each element.
+    KnownZero.setAllBits(); KnownOne.setAllBits();
+    APInt Elt(KnownZero.getBitWidth(), 0);
+    for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
+      Constant *Element = CV->getAggregateElement(i);
+      auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
+      if (!ElementCI) {
+        KnownZero.clearAllBits();
+        KnownOne.clearAllBits();
+        return;
+      }
+      Elt = ElementCI->getValue();
+      KnownZero &= ~Elt;
+      KnownOne &= Elt;
+    }
     return;
   }
 

Added: llvm/trunk/test/Transforms/InstCombine/pr20678.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr20678.ll?rev=268479&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/pr20678.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/pr20678.ll Wed May  4 01:13:33 2016
@@ -0,0 +1,8 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+define i1 @test1() {
+entry:
+  ret i1 icmp ne (i16 bitcast (<16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false> to i16), i16 0)
+}
+; CHECK-LABEL: define i1 @test1(
+; CHECK:  ret i1 true




More information about the llvm-commits mailing list