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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92427 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-01-02 22:08:28 +00:00
parent b4f82b4b4f
commit df3d63b896
2 changed files with 43 additions and 7 deletions

View File

@ -259,7 +259,8 @@ namespace {
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 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I,
/// 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 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
// 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 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
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 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
!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 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
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 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
!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 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
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: {

View File

@ -80,3 +80,15 @@ define i1 @test7(i32 %X) {
; 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
}