[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