[llvm] r194840 - Avoid illegal integer promotion in fastisel
Bob Wilson
bob.wilson at apple.com
Fri Nov 15 11:09:27 PST 2013
Author: bwilson
Date: Fri Nov 15 13:09:27 2013
New Revision: 194840
URL: http://llvm.org/viewvc/llvm-project?rev=194840&view=rev
Log:
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!
Added:
llvm/trunk/test/CodeGen/ARM/fastisel-gep-promote-before-add.ll
llvm/trunk/test/CodeGen/PowerPC/fastisel-gep-promote-before-add.ll
llvm/trunk/test/CodeGen/X86/fastisel-gep-promote-before-add.ll
Modified:
llvm/trunk/include/llvm/CodeGen/FastISel.h
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
llvm/trunk/lib/Target/X86/X86FastISel.cpp
Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=194840&r1=194839&r2=194840&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Fri Nov 15 13:09:27 2013
@@ -358,6 +358,15 @@ protected:
return 0;
}
+ /// \brief Check if \c Add is an add that can be safely folded into \c GEP.
+ ///
+ /// \c Add can be folded into \c GEP if:
+ /// - \c Add is an add,
+ /// - \c Add's size matches \c GEP's,
+ /// - \c Add is in the same basic block as \c GEP, and
+ /// - \c Add has a constant operand.
+ bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
+
private:
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=194840&r1=194839&r2=194840&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Fri Nov 15 13:09:27 2013
@@ -1571,4 +1571,19 @@ bool FastISel::tryToFoldLoad(const LoadI
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));
+}
Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=194840&r1=194839&r2=194840&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Fri Nov 15 13:09:27 2013
@@ -900,13 +900,8 @@ bool ARMFastISel::ARMComputeAddress(cons
TmpOffset += CI->getSExtValue() * S;
break;
}
- if (isa<AddOperator>(Op) &&
- (!isa<Instruction>(Op) ||
- FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()]
- == FuncInfo.MBB) &&
- isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
- // An add (in the same block) with a constant operand. Fold the
- // constant.
+ if (canFoldAddIntoGEP(U, Op)) {
+ // A compatible add with a constant operand. Fold the constant.
ConstantInt *CI =
cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
TmpOffset += CI->getSExtValue() * S;
Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=194840&r1=194839&r2=194840&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Fri Nov 15 13:09:27 2013
@@ -336,13 +336,8 @@ bool PPCFastISel::PPCComputeAddress(cons
TmpOffset += CI->getSExtValue() * S;
break;
}
- if (isa<AddOperator>(Op) &&
- (!isa<Instruction>(Op) ||
- FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()]
- == FuncInfo.MBB) &&
- isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
- // An add (in the same block) with a constant operand. Fold the
- // constant.
+ if (canFoldAddIntoGEP(U, Op)) {
+ // A compatible add with a constant operand. Fold the constant.
ConstantInt *CI =
cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
TmpOffset += CI->getSExtValue() * S;
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=194840&r1=194839&r2=194840&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Fri Nov 15 13:09:27 2013
@@ -561,13 +561,8 @@ redo_gep:
Disp += CI->getSExtValue() * S;
break;
}
- if (isa<AddOperator>(Op) &&
- (!isa<Instruction>(Op) ||
- FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()]
- == FuncInfo.MBB) &&
- isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
- // An add (in the same block) with a constant operand. Fold the
- // constant.
+ if (canFoldAddIntoGEP(U, Op)) {
+ // A compatible add with a constant operand. Fold the constant.
ConstantInt *CI =
cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
Disp += CI->getSExtValue() * S;
Added: llvm/trunk/test/CodeGen/ARM/fastisel-gep-promote-before-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fastisel-gep-promote-before-add.ll?rev=194840&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/fastisel-gep-promote-before-add.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/fastisel-gep-promote-before-add.ll Fri Nov 15 13:09:27 2013
@@ -0,0 +1,18 @@
+; fastisel should not fold add with non-pointer bitwidth
+; sext(a) + sext(b) != sext(a + b)
+; RUN: llc -mtriple=armv7-apple-ios %s -O0 -o - | FileCheck %s
+
+define zeroext i8 @gep_promotion(i8* %ptr) nounwind uwtable ssp {
+entry:
+ %ptr.addr = alloca i8*, align 8
+ %add = add i8 64, 64 ; 0x40 + 0x40
+ %0 = load i8** %ptr.addr, align 8
+
+ ; CHECK-LABEL: _gep_promotion:
+ ; CHECK: ldrb {{r[0-9]+}}, {{\[r[0-9]+\]}}
+ %arrayidx = getelementptr inbounds i8* %0, i8 %add
+
+ %1 = load i8* %arrayidx, align 1
+ ret i8 %1
+}
+
Added: llvm/trunk/test/CodeGen/PowerPC/fastisel-gep-promote-before-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fastisel-gep-promote-before-add.ll?rev=194840&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fastisel-gep-promote-before-add.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/fastisel-gep-promote-before-add.ll Fri Nov 15 13:09:27 2013
@@ -0,0 +1,17 @@
+; fastisel should not fold add with non-pointer bitwidth
+; sext(a) + sext(b) != sext(a + b)
+; RUN: llc -mtriple=powerpc64-unknown-freebsd10.0 %s -O0 -o - | FileCheck %s
+
+define zeroext i8 @gep_promotion(i8* %ptr) nounwind uwtable ssp {
+entry:
+ %ptr.addr = alloca i8*, align 8
+ %add = add i8 64, 64 ; 0x40 + 0x40
+ %0 = load i8** %ptr.addr, align 8
+
+ ; CHECK-LABEL: gep_promotion:
+ ; CHECK: lbz {{[0-9]+}}, 0({{.*}})
+ %arrayidx = getelementptr inbounds i8* %0, i8 %add
+
+ %1 = load i8* %arrayidx, align 1
+ ret i8 %1
+}
Added: llvm/trunk/test/CodeGen/X86/fastisel-gep-promote-before-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fastisel-gep-promote-before-add.ll?rev=194840&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fastisel-gep-promote-before-add.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fastisel-gep-promote-before-add.ll Fri Nov 15 13:09:27 2013
@@ -0,0 +1,37 @@
+; fastisel should not fold add with non-pointer bitwidth
+; sext(a) + sext(b) != sext(a + b)
+; RUN: llc -mtriple=x86_64-apple-darwin %s -O0 -o - | FileCheck %s
+
+define zeroext i8 @gep_promotion(i8* %ptr) nounwind uwtable ssp {
+entry:
+ %ptr.addr = alloca i8*, align 8
+ %add = add i8 64, 64 ; 0x40 + 0x40
+ %0 = load i8** %ptr.addr, align 8
+
+ ; CHECK-LABEL: _gep_promotion:
+ ; CHECK: movzbl ({{.*}})
+ %arrayidx = getelementptr inbounds i8* %0, i8 %add
+
+ %1 = load i8* %arrayidx, align 1
+ ret i8 %1
+}
+
+define zeroext i8 @gep_promotion_nonconst(i8 %i, i8* %ptr) nounwind uwtable ssp {
+entry:
+ %i.addr = alloca i8, align 4
+ %ptr.addr = alloca i8*, align 8
+ store i8 %i, i8* %i.addr, align 4
+ store i8* %ptr, i8** %ptr.addr, align 8
+ %0 = load i8* %i.addr, align 4
+ ; CHECK-LABEL: _gep_promotion_nonconst:
+ ; CHECK: movzbl ({{.*}})
+ %xor = xor i8 %0, -128 ; %0 ^ 0x80
+ %add = add i8 %xor, -127 ; %xor + 0x81
+ %1 = load i8** %ptr.addr, align 8
+
+ %arrayidx = getelementptr inbounds i8* %1, i8 %add
+
+ %2 = load i8* %arrayidx, align 1
+ ret i8 %2
+}
+
More information about the llvm-commits
mailing list