summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp17
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp23
-rw-r--r--llvm/test/Transforms/InstCombine/pr20678.ll8
3 files changed, 39 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index ebe8a27999f..677c3d92d02 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -78,20 +78,23 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
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);
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index a0a294db521..aca760810ef 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1405,8 +1405,7 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
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.
@@ -1420,6 +1419,26 @@ void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
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;
+ }
+
// Start out not knowing anything.
KnownZero.clearAllBits(); KnownOne.clearAllBits();
diff --git a/llvm/test/Transforms/InstCombine/pr20678.ll b/llvm/test/Transforms/InstCombine/pr20678.ll
new file mode 100644
index 00000000000..4b5fac79449
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pr20678.ll
@@ -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
OpenPOWER on IntegriCloud