[llvm-commits] CVS: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp

Nick Lewycky nicholas at mxc.ca
Wed Mar 21 19:03:11 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

PredicateSimplifier.cpp updated: 1.60 -> 1.61
---
Log message:

Fix broken optimization disabled by a logic bug.

Analyze GEPs. If the indices are all zero, transfer whether the pointer is
known to be not null through the GEP.

Add a few more cases for xor and shift instructions.


---
Diffs of the changes:  (+51 -10)

 PredicateSimplifier.cpp |   61 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 51 insertions(+), 10 deletions(-)


Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.60 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.61
--- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.60	Sun Mar 18 17:58:46 2007
+++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp	Wed Mar 21 21:02:51 2007
@@ -1516,13 +1516,27 @@
             add(SI->getCondition(), ConstantInt::getFalse(),
                 ICmpInst::ICMP_EQ, NewContext);
         }
+      } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+        for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
+             OE = GEPI->idx_end(); OI != OE; ++OI) {
+          ConstantInt *Op = dyn_cast<ConstantInt>(IG.canonicalize(*OI, Top));
+          if (!Op || !Op->isZero()) return;
+        }
+        // TODO: The GEPI indices are all zero. Copy from definition to operand,
+        // jumping the type plane as needed.
+        if (isRelatedBy(GEPI, Constant::getNullValue(GEPI->getType()),
+                        ICmpInst::ICMP_NE)) {
+          Value *Ptr = GEPI->getPointerOperand();
+          add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
+              NewContext);
+        }
       }
       // TODO: CastInst "%a = cast ... %b" where %a is EQ or NE a constant.
     }
 
     /// opsToDef - A new relationship was discovered involving one of this
     /// instruction's operands. Find any new relationship involving the
-    /// definition.
+    /// definition, or another operand.
     void opsToDef(Instruction *I) {
       Instruction *NewContext = below(I) ? I : TopInst;
 
@@ -1551,6 +1565,9 @@
 
         switch (Opcode) {
           default: break;
+          case Instruction::LShr:
+          case Instruction::AShr:
+          case Instruction::Shl:
           case Instruction::Sub:
             if (Op1 == Zero) {
               add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
@@ -1562,6 +1579,7 @@
               add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
               return;
             } // fall-through
+          case Instruction::Xor:
           case Instruction::Add:
             if (Op0 == Zero) {
               add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
@@ -1589,25 +1607,32 @@
         }
 
         // "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
-        // "%x = mul i32 %y, %z" and %x EQ %y then %z EQ 1
-        // 1. Repeat all of the above, with order of operands reversed.
+        // "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
+        // "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
         // "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1
 
-        Value *Known = Op0, *Unknown = Op1;
-        if (Known != BO) std::swap(Known, Unknown);
-        if (Known == BO) {
+        Value *Known = Op0, *Unknown = Op1,
+              *TheBO = IG.canonicalize(BO, Top);
+        if (Known != TheBO) std::swap(Known, Unknown);
+        if (Known == TheBO) {
           switch (Opcode) {
             default: break;
+            case Instruction::LShr:
+            case Instruction::AShr:
+            case Instruction::Shl:
+              if (!isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) break;
+              // otherwise, fall-through.
+            case Instruction::Sub:
+              if (Unknown == Op1) break;
+              // otherwise, fall-through.
             case Instruction::Xor:
             case Instruction::Add:
-            case Instruction::Sub:
               add(Unknown, Zero, ICmpInst::ICMP_EQ, NewContext);
               break;
             case Instruction::UDiv:
             case Instruction::SDiv:
-              if (Unknown == Op0) break; // otherwise, fallthrough
-            case Instruction::Mul:
-              if (isa<ConstantInt>(Unknown)) {
+              if (Unknown == Op1) break;
+              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
                 Constant *One = ConstantInt::get(Ty, 1);
                 add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
               }
@@ -1633,6 +1658,8 @@
         }
 
       } else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
+        if (I->getType()->isFPOrFPVector()) return;
+
         // Given: "%a = select i1 %x, i32 %b, i32 %c"
         // %x EQ true  then %a EQ %b
         // %x EQ false then %a EQ %c
@@ -1658,6 +1685,20 @@
         }
 
         // TODO: "%a = cast ... %b" where %b is NE/LT/GT a constant.
+      } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+        for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
+             OE = GEPI->idx_end(); OI != OE; ++OI) {
+          ConstantInt *Op = dyn_cast<ConstantInt>(IG.canonicalize(*OI, Top));
+          if (!Op || !Op->isZero()) return;
+        }
+        // TODO: The GEPI indices are all zero. Copy from operand to definition,
+        // jumping the type plane as needed.
+        Value *Ptr = GEPI->getPointerOperand();
+        if (isRelatedBy(Ptr, Constant::getNullValue(Ptr->getType()),
+                        ICmpInst::ICMP_NE)) {
+          add(GEPI, Constant::getNullValue(GEPI->getType()), ICmpInst::ICMP_NE,
+              NewContext);
+        }
       }
     }
 






More information about the llvm-commits mailing list