diff options
author | Bob Wilson <bob.wilson@apple.com> | 2013-11-15 19:09:27 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2013-11-15 19:09:27 +0000 |
commit | cc7052343e5e955d4e2f48885c06360f9003390a (patch) | |
tree | 8832fd14ebae789ee88bab5009cc33fbc89e3ec7 /lib/CodeGen/SelectionDAG | |
parent | 5cddda6d13ab66c462ccbd61255ad6e6f95e9f6f (diff) | |
download | external_llvm-cc7052343e5e955d4e2f48885c06360f9003390a.zip external_llvm-cc7052343e5e955d4e2f48885c06360f9003390a.tar.gz external_llvm-cc7052343e5e955d4e2f48885c06360f9003390a.tar.bz2 |
Avoid illegal integer promotion in fastisel
Stop folding constant adds into GEP when the type size doesn't match.
Otherwise, the adds' operands are effectively being promoted, changing the
conditions of an overflow. Results are different when:
sext(a) + sext(b) != sext(a + b)
Problem originally found on x86-64, but also fixed issues with ARM and PPC,
which used similar code.
<rdar://problem/15292280>
Patch by Duncan Exon Smith!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194840 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG')
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index fb798c1..a6f7461 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1571,4 +1571,19 @@ bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) { return tryToFoldLoadIntoMI(User, RI.getOperandNo(), LI); } +bool FastISel::canFoldAddIntoGEP(const User *GEP, const Value *Add) { + // Must be an add. + if (!isa<AddOperator>(Add)) + return false; + // Type size needs to match. + if (TD.getTypeSizeInBits(GEP->getType()) != + TD.getTypeSizeInBits(Add->getType())) + return false; + // Must be in the same basic block. + if (isa<Instruction>(Add) && + FuncInfo.MBBMap[cast<Instruction>(Add)->getParent()] != FuncInfo.MBB) + return false; + // Must have a constant operand. + return isa<ConstantInt>(cast<AddOperator>(Add)->getOperand(1)); +} |