summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-08-30 18:29:25 +0000
committerdim <dim@FreeBSD.org>2013-08-30 18:29:25 +0000
commit8477c7824ca5deadf4314381a5fe5d0c3bfbab99 (patch)
tree6ec2fc4a8cfc2c5248b16436c3838ab1fc373993 /contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
parenteab5b536cd4a17efa23c34b3183d0a2e133df859 (diff)
downloadFreeBSD-src-8477c7824ca5deadf4314381a5fe5d0c3bfbab99.zip
FreeBSD-src-8477c7824ca5deadf4314381a5fe5d0c3bfbab99.tar.gz
Pull in r189672 from upstream llvm trunk:
InstCombine: Check for zero shift amounts before subtracting one causing integer overflow. PR17026. Also avoid undefined shifts and shift amounts larger than 64 bits (those are always undef because we can't represent integer types that large). This should fix assertion failures when building the emulators/xmame port. Reported by: bapt
Diffstat (limited to 'contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
-rw-r--r--contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp25
1 files changed, 15 insertions, 10 deletions
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 8add1ea..60d672b 100644
--- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -845,21 +845,26 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
Value *InstCombiner::SimplifyShrShlDemandedBits(Instruction *Shr,
Instruction *Shl, APInt DemandedMask, APInt &KnownZero, APInt &KnownOne) {
- unsigned ShlAmt = cast<ConstantInt>(Shl->getOperand(1))->getZExtValue();
- unsigned ShrAmt = cast<ConstantInt>(Shr->getOperand(1))->getZExtValue();
+ const APInt &ShlOp1 = cast<ConstantInt>(Shl->getOperand(1))->getValue();
+ const APInt &ShrOp1 = cast<ConstantInt>(Shr->getOperand(1))->getValue();
+ if (!ShlOp1 || !ShrOp1)
+ return 0; // Noop.
+
+ Value *VarX = Shr->getOperand(0);
+ Type *Ty = VarX->getType();
+ unsigned BitWidth = Ty->getIntegerBitWidth();
+ if (ShlOp1.uge(BitWidth) || ShrOp1.uge(BitWidth))
+ return 0; // Undef.
+
+ unsigned ShlAmt = ShlOp1.getZExtValue();
+ unsigned ShrAmt = ShrOp1.getZExtValue();
KnownOne.clearAllBits();
KnownZero = APInt::getBitsSet(KnownZero.getBitWidth(), 0, ShlAmt-1);
KnownZero &= DemandedMask;
- if (ShlAmt == 0 || ShrAmt == 0)
- return 0;
-
- Value *VarX = Shr->getOperand(0);
- Type *Ty = VarX->getType();
-
- APInt BitMask1(APInt::getAllOnesValue(Ty->getIntegerBitWidth()));
- APInt BitMask2(APInt::getAllOnesValue(Ty->getIntegerBitWidth()));
+ APInt BitMask1(APInt::getAllOnesValue(BitWidth));
+ APInt BitMask2(APInt::getAllOnesValue(BitWidth));
bool isLshr = (Shr->getOpcode() == Instruction::LShr);
BitMask1 = isLshr ? (BitMask1.lshr(ShrAmt) << ShlAmt) :
OpenPOWER on IntegriCloud