[llvm-commits] [llvm] r92427 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/load-cmp.ll
Chris Lattner
sabre at nondot.org
Sat Jan 2 14:08:39 PST 2010
Author: lattner
Date: Sat Jan 2 16:08:28 2010
New Revision: 92427
URL: http://llvm.org/viewvc/llvm-project?rev=92427&view=rev
Log:
teach instcombine to optimize idioms like A[i]&42 == 0. This
occurs in 403.gcc in mode_mask_array, in safe-ctype.c (which
is copied in multiple apps) in _sch_istable, etc.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/load-cmp.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=92427&r1=92426&r2=92427&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Jan 2 16:08:28 2010
@@ -259,7 +259,8 @@
Instruction *FoldFCmp_IntToFP_Cst(FCmpInst &I, Instruction *LHSI,
Constant *RHSC);
Instruction *FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
- GlobalVariable *GV, CmpInst &ICI);
+ GlobalVariable *GV, CmpInst &ICI,
+ ConstantInt *AndCst = 0);
Instruction *visitFCmpInst(FCmpInst &I);
Instruction *visitICmpInst(ICmpInst &I);
Instruction *visitICmpInstWithCastAndCast(ICmpInst &ICI);
@@ -6022,9 +6023,12 @@
/// where GV is a global variable with a constant initializer. Try to simplify
/// this into some simple computation that does not need the load. For example
/// we can optimize "icmp eq (load (gep "foo", 0, i)), 0" into "icmp eq i, 3".
+///
+/// If AndCst is non-null, then the loaded value is masked with that constant
+/// before doing the comparison. This handles cases like "A[i]&4 == 0".
Instruction *InstCombiner::
FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
- CmpInst &ICI) {
+ CmpInst &ICI, ConstantInt *AndCst) {
// There are many forms of this optimization we can handle, for now, just do
// the simple index into a single-dimensional array.
@@ -6070,9 +6074,13 @@
// Scan the array and see if one of our patterns matches.
Constant *CompareRHS = cast<Constant>(ICI.getOperand(1));
for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
+ Constant *Elt = Init->getOperand(i);
+
+ // If the element is masked, handle it.
+ if (AndCst) Elt = ConstantExpr::getAnd(Elt, AndCst);
+
// Find out if the comparison would be true or false for the i'th element.
- Constant *C = ConstantFoldCompareInstOperands(ICI.getPredicate(),
- Init->getOperand(i),
+ Constant *C = ConstantFoldCompareInstOperands(ICI.getPredicate(), Elt,
CompareRHS, TD);
// If the result is undef for this element, ignore it.
if (isa<UndefValue>(C)) {
@@ -6236,7 +6244,6 @@
return new ICmpInst(ICmpInst::ICMP_NE, V, ConstantInt::get(Ty, 0));
}
- // TODO: A[i]&4 == 0
// TODO: GEP 0, i, 4
return 0;
@@ -6333,7 +6340,7 @@
!cast<LoadInst>(LHSI)->isVolatile())
if (Instruction *Res = FoldCmpLoadFromIndexedGlobal(GEP, GV, I))
return Res;
- //errs() << "NOT HANDLED: " << *GV << "\n";
+ //errs() << "NOT HANDLED FP: " << *GV << "\n";
//errs() << "\t" << *GEP << "\n";
//errs() << "\t " << I << "\n\n\n";
}
@@ -6719,6 +6726,7 @@
break;
case Instruction::Load:
+ // Try to optimize things like "A[i] > 4" to index computations.
if (GetElementPtrInst *GEP =
dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
@@ -6726,7 +6734,7 @@
!cast<LoadInst>(LHSI)->isVolatile())
if (Instruction *Res = FoldCmpLoadFromIndexedGlobal(GEP, GV, I))
return Res;
- //errs() << "NOT HANDLED: " << *GV << "\n";
+ //errs() << "NOT HANDLED INT: " << *GV << "\n";
//errs() << "\t" << *GEP << "\n";
//errs() << "\t " << I << "\n\n\n";
}
@@ -7382,6 +7390,22 @@
return &ICI;
}
}
+
+ // Try to optimize things like "A[i]&42 == 0" to index computations.
+ if (LoadInst *LI = dyn_cast<LoadInst>(LHSI->getOperand(0))) {
+ if (GetElementPtrInst *GEP =
+ dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
+ if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
+ !LI->isVolatile() && isa<ConstantInt>(LHSI->getOperand(1))) {
+ ConstantInt *C = cast<ConstantInt>(LHSI->getOperand(1));
+ if (Instruction *Res = FoldCmpLoadFromIndexedGlobal(GEP, GV,ICI, C))
+ return Res;
+ //errs() << "NOT HANDLED INT: " << *GV << "\n";
+ //errs() << "\t" << *GEP << "\n";
+ //errs() << "\t " << I << "\n\n\n";
+ }
+ }
break;
case Instruction::Or: {
Modified: llvm/trunk/test/Transforms/InstCombine/load-cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/load-cmp.ll?rev=92427&r1=92426&r2=92427&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/load-cmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/load-cmp.ll Sat Jan 2 16:08:28 2010
@@ -80,3 +80,15 @@
; CHECK-NEXT: %R = icmp ugt i32 {{.*}}, 2
; CHECK-NEXT: ret i1 %R
}
+
+define i1 @test8(i32 %X) {
+ %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
+ %Q = load i16* %P
+ %R = and i16 %Q, 3
+ %S = icmp eq i16 %R, 0
+ ret i1 %S
+; CHECK: @test8
+; CHECK-NEXT: add i32 %X, -8
+; CHECK-NEXT: %S = icmp ult i32 {{.*}}, 2
+; CHECK-NEXT: ret i1 %S
+}
More information about the llvm-commits
mailing list