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

Reid Spencer reid at x10sys.com
Wed Mar 21 16:20:08 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.670 -> 1.671
---
Log message:

For PR1248: http://llvm.org/PR1248 :
* Fix some indentation and comments in InsertRangeTest
* Add an "IsSigned" parameter to AddWithOverflow and make it handle signed
  additions. Also, APIntify this function so it works with any bitwidth.
* For the icmp pred ([us]div %X, C1), C2 transforms, exit early if the
  div instruction's RHS is zero.
* Finally, for icmp pred (sdiv %X, C1), -C2, fix an off-by-one error. The
  HiBound needs to be incremented in order to get the range test correct.


---
Diffs of the changes:  (+26 -18)

 InstructionCombining.cpp |   44 ++++++++++++++++++++++++++------------------
 1 files changed, 26 insertions(+), 18 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.670 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.671
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.670	Tue Mar 20 07:49:06 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Wed Mar 21 18:19:50 2007
@@ -3773,7 +3773,7 @@
 
     // V >= Min && V < Hi --> V < Hi
     if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) {
-    ICmpInst::Predicate pred = (isSigned ? 
+      ICmpInst::Predicate pred = (isSigned ? 
         ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT);
       return new ICmpInst(pred, V, Hi);
     }
@@ -3789,7 +3789,7 @@
   if (Lo == Hi)  // Trivially true.
     return new ICmpInst(ICmpInst::ICMP_EQ, V, V);
 
-  // V < Min || V >= Hi ->'V > Hi-1'
+  // V < Min || V >= Hi -> V > Hi-1
   Hi = SubOne(cast<ConstantInt>(Hi));
   if (cast<ConstantInt>(Lo)->isMinValue(isSigned)) {
     ICmpInst::Predicate pred = (isSigned ? 
@@ -3797,8 +3797,9 @@
     return new ICmpInst(pred, V, Hi);
   }
 
-  // Emit V-Lo > Hi-1-Lo
-  Constant *NegLo = ConstantExpr::getNeg(Lo);
+  // Emit V-Lo >u Hi-1-Lo
+  // Note that Hi has already had one subtracted from it, above.
+  ConstantInt *NegLo = cast<ConstantInt>(ConstantExpr::getNeg(Lo));
   Instruction *Add = BinaryOperator::createAdd(V, NegLo, V->getName()+".off");
   InsertNewInstBefore(Add, IB);
   Constant *LowerBound = ConstantExpr::getAdd(NegLo, Hi);
@@ -4918,11 +4919,16 @@
 /// AddWithOverflow - Compute Result = In1+In2, returning true if the result
 /// overflowed for this type.
 static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
-                            ConstantInt *In2) {
+                            ConstantInt *In2, bool IsSigned = false) {
   Result = cast<ConstantInt>(ConstantExpr::getAdd(In1, In2));
 
-  return cast<ConstantInt>(Result)->getZExtValue() <
-         cast<ConstantInt>(In1)->getZExtValue();
+  if (IsSigned)
+    if (In2->getValue().isNegative())
+      return Result->getValue().sgt(In1->getValue());
+    else
+      return Result->getValue().slt(In1->getValue());
+  else
+    return Result->getValue().ult(In1->getValue());
 }
 
 /// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
@@ -5664,6 +5670,8 @@
           bool DivIsSigned = LHSI->getOpcode() == Instruction::SDiv;
           if (!I.isEquality() && DivIsSigned != I.isSignedPredicate())
             break;
+          if (DivRHS->isZero())
+            break; // Don't hack on div by zero
 
           // Initialize the variables that will indicate the nature of the
           // range check.
@@ -5680,19 +5688,17 @@
           // Determine if the product overflows by seeing if the product is
           // not equal to the divide. Make sure we do the same kind of divide
           // as in the LHS instruction that we're folding. 
-          bool ProdOV = !DivRHS->isNullValue() && 
-            (DivIsSigned ?  ConstantExpr::getSDiv(Prod, DivRHS) :
-              ConstantExpr::getUDiv(Prod, DivRHS)) != CI;
+          bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) :
+                                     ConstantExpr::getUDiv(Prod, DivRHS)) != CI;
 
           // Get the ICmp opcode
           ICmpInst::Predicate predicate = I.getPredicate();
 
-          if (DivRHS->isNullValue()) {  
-            // Don't hack on divide by zeros!
-          } else if (!DivIsSigned) {  // udiv
+          if (!DivIsSigned) {  // udiv
             LoBound = Prod;
             LoOverflow = ProdOV;
-            HiOverflow = ProdOV || AddWithOverflow(HiBound, LoBound, DivRHS);
+            HiOverflow = ProdOV || 
+                         AddWithOverflow(HiBound, LoBound, DivRHS, false);
           } else if (DivRHS->getValue().isPositive()) { // Divisor is > 0.
             if (CI->isNullValue()) {       // (X / pos) op 0
               // Can't overflow.
@@ -5701,12 +5707,13 @@
             } else if (CI->getValue().isPositive()) {   // (X / pos) op pos
               LoBound = Prod;
               LoOverflow = ProdOV;
-              HiOverflow = ProdOV || AddWithOverflow(HiBound, Prod, DivRHS);
+              HiOverflow = ProdOV || 
+                           AddWithOverflow(HiBound, Prod, DivRHS, true);
             } else {                       // (X / pos) op neg
               Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS));
               LoOverflow = AddWithOverflow(LoBound, Prod,
-                                           cast<ConstantInt>(DivRHSH));
-              HiBound = Prod;
+                                           cast<ConstantInt>(DivRHSH), true);
+              HiBound = AddOne(Prod);
               HiOverflow = ProdOV;
             }
           } else {                         // Divisor is < 0.
@@ -5718,7 +5725,8 @@
             } else if (CI->getValue().isPositive()) {   // (X / neg) op pos
               HiOverflow = LoOverflow = ProdOV;
               if (!LoOverflow)
-                LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS));
+                LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS),
+                                             true);
               HiBound = AddOne(Prod);
             } else {                       // (X / neg) op neg
               LoBound = Prod;






More information about the llvm-commits mailing list