diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 23 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/pr20678.ll | 8 |
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 |