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

Reid Spencer reid at x10sys.com
Sun Oct 22 01:59:32 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.520.2.6 -> 1.520.2.7
PredicateSimplifier.cpp updated: 1.20.2.1 -> 1.20.2.2
Reassociate.cpp updated: 1.62.2.2 -> 1.62.2.3
---
Log message:

Implement the FDIV instruction for floating point divide.


---
Diffs of the changes:  (+93 -79)

 InstructionCombining.cpp |  170 +++++++++++++++++++++++++----------------------
 PredicateSimplifier.cpp  |    1 
 Reassociate.cpp          |    1 
 3 files changed, 93 insertions(+), 79 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.6 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.7
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.6	Sat Oct 21 21:04:31 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Oct 22 03:59:00 2006
@@ -131,8 +131,11 @@
     Instruction *visitAdd(BinaryOperator &I);
     Instruction *visitSub(BinaryOperator &I);
     Instruction *visitMul(BinaryOperator &I);
+    Instruction *commonDivTransforms(BinaryOperator &I);
+    Instruction *commonIDivTransforms(BinaryOperator &I);
     Instruction *visitUDiv(BinaryOperator &I);
     Instruction *visitSDiv(BinaryOperator &I);
+    Instruction *visitFDiv(BinaryOperator &I);
     Instruction *visitRem(BinaryOperator &I);
     Instruction *visitAnd(BinaryOperator &I);
     Instruction *visitOr (BinaryOperator &I);
@@ -2159,15 +2162,19 @@
   return Changed ? &I : 0;
 }
 
-Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
+Instruction* InstCombiner::commonDivTransforms(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   if (isa<UndefValue>(Op0))              // undef / X -> 0
     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
   if (isa<UndefValue>(Op1))
     return ReplaceInstUsesWith(I, Op1);  // X / undef -> undef
+  return 0;
+}
+
+Instruction* InstCombiner::commonIDivTransforms(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  // If right hand side is a constant intger ..
   if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
     // div X, 1 == X
     if (RHS->equalsInt(1))
@@ -2180,25 +2187,14 @@
     // (X / C1) / C2  -> X / (C1*C2)
     if (Instruction *LHS = dyn_cast<Instruction>(Op0))
       if (LHS->getOpcode() == Instruction::SDiv || 
-          LHS->getOpcode()==Instruction::UDiv)
+          LHS->getOpcode()==Instruction::UDiv ||
+          LHS->getOpcode()==Instruction::FDiv)
         if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
           return BinaryOperator::create(
             Instruction::BinaryOps(LHS->getOpcode()), LHS->getOperand(0),
                                           ConstantExpr::getMul(RHS, LHSRHS));
         }
 
-    // Check to see if this is an unsigned division with an exact power of 2,
-    // if so, convert to a right shift.
-    // X udiv C^2 -> X >> C
-    if (ConstantInt *C = dyn_cast<ConstantInt>(RHS)) 
-      if (uint64_t Val = C->getZExtValue())    // Don't break X / 0
-        if (isPowerOf2_64(Val)) {
-          uint64_t C = Log2_64(Val);
-          return new ShiftInst(Instruction::Shr, Op0,
-                               ConstantInt::get(Type::UByteTy, C));
-        }
-
-  
     if (!RHS->isNullValue()) { // avoid X udiv 0
       if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
         if (Instruction *R = FoldOpIntoSelect(I, SI, this))
@@ -2268,7 +2264,32 @@
     if (LHS->equalsInt(0))
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
-  // Known to be an unsigned division.
+  return 0;
+}
+
+Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  Instruction* common = commonDivTransforms(I);
+  if (common)
+    return common;
+
+  common = commonIDivTransforms(I);
+  if (common)
+    return common;
+
+  // Check to see if this is an unsigned division with an exact power of 2,
+  // if so, convert to a right shift.
+  // X udiv C^2 -> X >> C
+  if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
+    if (uint64_t Val = C->getZExtValue())    // Don't break X / 0
+      if (isPowerOf2_64(Val)) {
+        uint64_t C = Log2_64(Val);
+        return new ShiftInst(Instruction::Shr, Op0,
+                             ConstantInt::get(Type::UByteTy, C));
+      }
+  }
+
   if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) {
     // Turn A / (C1 << N), where C1 is "1<<C2" into A >> (N+C2) [udiv only].
     if (RHSI->getOpcode() == Instruction::Shl &&
@@ -2294,35 +2315,66 @@
 Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  if (isa<UndefValue>(Op0))              // undef / X -> 0
-    return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
-  if (isa<UndefValue>(Op1))
-    return ReplaceInstUsesWith(I, Op1);  // X / undef -> undef
+  Instruction* common = commonDivTransforms(I);
+  if (common)
+    return common;
+
+  common = commonIDivTransforms(I);
+  if (common)
+    return common;
 
   if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
+    // -X/C -> X/-C
+    if (Value *LHSNeg = dyn_castNegVal(Op0))
+      return BinaryOperator::createSDiv(LHSNeg, ConstantExpr::getNeg(RHS));
+  }
+
+  // If the sign bits of both operands are zero (i.e. we can prove they are
+  // unsigned inputs), turn this into a udiv.
+  uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+  if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
+    const Type *NTy = Op0->getType()->getUnsignedVersion();
+    Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
+    InsertNewInstBefore(LHS, I);
+    Value *RHS;
+    if (Constant *R = dyn_cast<Constant>(Op1))
+      RHS = ConstantExpr::getCast(R, NTy);
+    else
+      RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I);
+    Instruction *Div = BinaryOperator::createUDiv(LHS, RHS, I.getName());
+    InsertNewInstBefore(Div, I);
+    return new CastInst(Div, I.getType());
+  }      
+  
+  return 0;
+}
+
+Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  Instruction* common = commonDivTransforms(I);
+  if (common)
+    return common;
+
+  // If right hand side is a constant floating point ...
+  if (ConstantFP *RHS = dyn_cast<ConstantFP>(Op1)) {
     // div X, 1 == X
-    if (RHS->equalsInt(1))
+    if (RHS->isExactlyValue(1.0))
       return ReplaceInstUsesWith(I, Op0);
 
     // div X, -1 == -X
-    if (RHS->isAllOnesValue())
+    if (RHS->isExactlyValue(-1.0))
       return BinaryOperator::createNeg(Op0);
 
     // (X / C1) / C2  -> X / (C1*C2)
     if (Instruction *LHS = dyn_cast<Instruction>(Op0))
-      if (LHS->getOpcode() == Instruction::SDiv || 
-          LHS->getOpcode()==Instruction::UDiv)
-        if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
-          return BinaryOperator::create(
-            Instruction::BinaryOps(LHS->getOpcode()), LHS->getOperand(0),
+      if (LHS->getOpcode()==Instruction::FDiv)
+        if (ConstantFP *LHSRHS = dyn_cast<ConstantFP>(LHS->getOperand(1))) {
+          return BinaryOperator::create(Instruction::FDiv, LHS->getOperand(0),
                                           ConstantExpr::getMul(RHS, LHSRHS));
         }
 
-    // -X/C -> X/-C
-    if (Value *LHSNeg = dyn_castNegVal(Op0))
-      return BinaryOperator::createSDiv(LHSNeg, ConstantExpr::getNeg(RHS));
-
-    if (!RHS->isNullValue()) {
+    if (!RHS->isNullValue()) { // avoid X fdiv 0
       if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
         if (Instruction *R = FoldOpIntoSelect(I, SI, this))
           return R;
@@ -2332,6 +2384,11 @@
     }
   }
 
+  // 0 / X == 0
+  if (ConstantFP *LHS = dyn_cast<ConstantFP>(Op0))
+    if (LHS->isExactlyValue(0))
+      return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
   // Handle div X, Cond?Y:Z
   if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) {
     // div X, (Cond ? 0 : Y) -> div X, Y.  If the div and the select are in the
@@ -2350,6 +2407,7 @@
           UpdateValueUsesWith(SI, SI->getOperand(2));
         return &I;
       }
+
     // Likewise for: div X, (Cond ? Y : 0) -> div X, Y
     if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
       if (ST->isNullValue()) {
@@ -2362,58 +2420,11 @@
           UpdateValueUsesWith(SI, SI->getOperand(1));
         return &I;
       }
-
-    // If this is 'udiv X, (Cond ? C1, C2)' where C1&C2 are powers of two,
-    // transform this into: '(Cond ? (udiv X, C1) : (udiv X, C2))'.
-    if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1)))
-      if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) 
-        if (STO->getType()->isUnsigned() && SFO->getType()->isUnsigned()) {
-          // STO == 0 and SFO == 0 handled above.
-          uint64_t TVA = STO->getZExtValue(), FVA = SFO->getZExtValue();
-          if (isPowerOf2_64(TVA) && isPowerOf2_64(FVA)) {
-            unsigned TSA = Log2_64(TVA), FSA = Log2_64(FVA);
-            Constant *TC = ConstantInt::get(Type::UByteTy, TSA);
-            Instruction *TSI = new ShiftInst(Instruction::Shr, Op0,
-                                             TC, SI->getName()+".t");
-            TSI = InsertNewInstBefore(TSI, I);
-
-            Constant *FC = ConstantInt::get(Type::UByteTy, FSA);
-            Instruction *FSI = new ShiftInst(Instruction::Shr, Op0,
-                                             FC, SI->getName()+".f");
-            FSI = InsertNewInstBefore(FSI, I);
-            return new SelectInst(SI->getOperand(0), TSI, FSI);
-          }
-        }
   }
 
-  // 0 / X == 0, we don't need to preserve faults!
-  if (ConstantInt *LHS = dyn_cast<ConstantInt>(Op0))
-    if (LHS->equalsInt(0))
-      return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
-
-  // Known to be signed div
-  
-  // If the sign bits of both operands are zero (i.e. we can prove they are
-  // unsigned inputs), turn this into a udiv.
-  uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
-  if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
-    const Type *NTy = Op0->getType()->getUnsignedVersion();
-    Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
-    InsertNewInstBefore(LHS, I);
-    Value *RHS;
-    if (Constant *R = dyn_cast<Constant>(Op1))
-      RHS = ConstantExpr::getCast(R, NTy);
-    else
-      RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I);
-    Instruction *Div = BinaryOperator::createUDiv(LHS, RHS, I.getName());
-    InsertNewInstBefore(Div, I);
-    return new CastInst(Div, I.getType());
-  }      
-  
   return 0;
 }
 
-
 /// GetFactor - If we can prove that the specified value is at least a multiple
 /// of some factor, return that factor.
 static Constant *GetFactor(Value *V) {
@@ -4486,6 +4497,7 @@
 
       case Instruction::SDiv:
       case Instruction::UDiv:
+      case Instruction::FDiv:
         // Fold: (div X, C1) op C2 -> range check
         if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
           // Fold this div into the comparison, producing a range check.


Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.1 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2
--- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.1	Fri Oct 20 03:19:49 2006
+++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp	Sun Oct 22 03:59:01 2006
@@ -728,6 +728,7 @@
   switch (ops) {
     case Instruction::UDiv:
     case Instruction::SDiv:
+    case Instruction::FDiv:
     case Instruction::Rem: {
       Value *Divisor = BO.getOperand(1);
       KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor);


Index: llvm/lib/Transforms/Scalar/Reassociate.cpp
diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.2 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3
--- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.2	Fri Oct 20 03:19:49 2006
+++ llvm/lib/Transforms/Scalar/Reassociate.cpp	Sun Oct 22 03:59:01 2006
@@ -115,6 +115,7 @@
       I->getOpcode() == Instruction::Call ||
       I->getOpcode() == Instruction::UDiv || 
       I->getOpcode() == Instruction::SDiv ||
+      I->getOpcode() == Instruction::FDiv ||
       I->getOpcode() == Instruction::Rem)
     return true;
   return false;






More information about the llvm-commits mailing list