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

Zhou Sheng zhousheng00 at gmail.com
Mon Oct 23 11:13:58 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.520.2.8 -> 1.520.2.9
PredicateSimplifier.cpp updated: 1.20.2.2 -> 1.20.2.3
Reassociate.cpp updated: 1.62.2.3 -> 1.62.2.4
---
Log message:



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

 InstructionCombining.cpp |  271 +++++++++++++++++++++++++++++++----------------
 PredicateSimplifier.cpp  |    4 
 Reassociate.cpp          |    4 
 3 files changed, 186 insertions(+), 93 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.8 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.9
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.8	Sun Oct 22 18:27:20 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Mon Oct 23 13:13:27 2006
@@ -131,12 +131,16 @@
     Instruction *visitAdd(BinaryOperator &I);
     Instruction *visitSub(BinaryOperator &I);
     Instruction *visitMul(BinaryOperator &I);
+    Instruction *visitURem(BinaryOperator &I);
+    Instruction *visitSRem(BinaryOperator &I);
+    Instruction *visitFRem(BinaryOperator &I);
+    Instruction *commonRemTransforms(BinaryOperator &I);
+    Instruction *commonIRemTransforms(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);
     Instruction *visitXor(BinaryOperator &I);
@@ -2431,9 +2435,9 @@
   return Result;
 }
 
-Instruction *InstCombiner::visitRem(BinaryOperator &I) {
+Instruction *InstCombiner::commonRemTransforms(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-  
+
   // 0 % X == 0, we don't need to preserve faults!
   if (Constant *LHS = dyn_cast<Constant>(Op0))
     if (LHS->isNullValue())
@@ -2443,34 +2447,11 @@
     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
   if (isa<UndefValue>(Op1))
     return ReplaceInstUsesWith(I, Op1);  // X % undef -> undef
-  
-  if (I.getType()->isSigned()) {
-    if (Value *RHSNeg = dyn_castNegVal(Op1))
-      if (!isa<ConstantInt>(RHSNeg) || !RHSNeg->getType()->isSigned() ||
-          cast<ConstantInt>(RHSNeg)->getSExtValue() > 0) {
-        // X % -Y -> X % Y
-        AddUsesToWorkList(I);
-        I.setOperand(1, RHSNeg);
-        return &I;
-      }
-   
-    // If the top bits of both operands are zero (i.e. we can prove they are
-    // unsigned inputs), turn this into a urem.
-    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 *Rem = BinaryOperator::createRem(LHS, RHS, I.getName());
-      InsertNewInstBefore(Rem, I);
-      return new CastInst(Rem, I.getType());
-    }
-  }
+  return 0;
+}
+
+Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
     // X % 0 == undef, we don't need to preserve faults!
@@ -2480,13 +2461,6 @@
     if (RHS->equalsInt(1))  // X % 1 == 0
       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
-    // Check to see if this is an unsigned remainder with an exact power of 2,
-    // if so, convert to a bitwise and.
-    if (ConstantInt *C = dyn_cast<ConstantInt>(RHS))
-      if (RHS->getType()->isUnsigned())
-        if (isPowerOf2_64(C->getZExtValue()))
-          return BinaryOperator::createAnd(Op0, SubOne(C));
-
     if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
       if (SelectInst *SI = dyn_cast<SelectInst>(Op0I)) {
         if (Instruction *R = FoldOpIntoSelect(I, SI, this))
@@ -2495,17 +2469,90 @@
         if (Instruction *NV = FoldOpIntoPhi(I))
           return NV;
       }
+    }
+  }
+
+  // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two,
+  // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'.
+  if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) {
+    // rem X, (Cond ? 0 : Y) -> rem X, Y.  If the rem and the select are in
+    // the same basic block, then we replace the select with Y, and the
+    // condition of the select with false (if the cond value is in the same
+    // BB).  If the select has uses other than the div, this allows them to be
+    // simplified also.
+    if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
+      if (ST->isNullValue()) {
+        Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
+        if (CondI && CondI->getParent() == I.getParent())
+          UpdateValueUsesWith(CondI, ConstantBool::getFalse());
+        else if (I.getParent() != SI->getParent() || SI->hasOneUse())
+          I.setOperand(1, SI->getOperand(2));
+        else
+          UpdateValueUsesWith(SI, SI->getOperand(2));
+        return &I;
+      }
+    // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y
+    if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
+      if (ST->isNullValue()) {
+        Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
+        if (CondI && CondI->getParent() == I.getParent())
+          UpdateValueUsesWith(CondI, ConstantBool::getTrue());
+        else if (I.getParent() != SI->getParent() || SI->hasOneUse())
+          I.setOperand(1, SI->getOperand(1));
+        else
+          UpdateValueUsesWith(SI, SI->getOperand(1));
+        return &I;
+      }
+
       
+    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.
+          if (isPowerOf2_64(STO->getZExtValue()) && 
+              isPowerOf2_64(SFO->getZExtValue())) {
+            Value *TrueAnd = InsertNewInstBefore(
+              BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"),
+                I);
+            Value *FalseAnd = InsertNewInstBefore(
+              BinaryOperator::createAnd(Op0, SubOne(SFO), SI->getName()+".f"),
+                I);
+            return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd);
+          }
+        }
+  }
+
+  return 0;
+}
+
+Instruction *InstCombiner::visitURem(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  Instruction* common = commonRemTransforms(I);
+  if (common)
+    return common;
+
+  common = commonIRemTransforms(I);
+  if (common)
+    return common;
+  
+  if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
+    // Check to see if this is an unsigned remainder with an exact power of 2,
+    // if so, convert to a bitwise and.
+    if (ConstantInt *C = dyn_cast<ConstantInt>(RHS))
+      if (isPowerOf2_64(C->getZExtValue()))
+        return BinaryOperator::createAnd(Op0, SubOne(C));
+
+    if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
       // X*C1%C2 --> 0  iff  C1%C2 == 0
-      if (ConstantExpr::getRem(GetFactor(Op0I), RHS)->isNullValue())
+      if (ConstantExpr::getURem(GetFactor(Op0I), RHS)->isNullValue())
         return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
     }
   }
 
   if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) {
     // Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only].
-    if (I.getType()->isUnsigned() && 
-        RHSI->getOpcode() == Instruction::Shl &&
+    if (RHSI->getOpcode() == Instruction::Shl &&
         isa<ConstantInt>(RHSI->getOperand(0)) && 
         RHSI->getOperand(0)->getType()->isUnsigned()) {
       unsigned C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue();
@@ -2517,57 +2564,97 @@
       }
     }
     
-    // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two,
-    // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'.
-    if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) {
-      // rem X, (Cond ? 0 : Y) -> rem X, Y.  If the rem and the select are in
-      // the same basic block, then we replace the select with Y, and the
-      // condition of the select with false (if the cond value is in the same
-      // BB).  If the select has uses other than the div, this allows them to be
-      // simplified also.
-      if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
-        if (ST->isNullValue()) {
-          Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
-          if (CondI && CondI->getParent() == I.getParent())
-            UpdateValueUsesWith(CondI, ConstantBool::getFalse());
-          else if (I.getParent() != SI->getParent() || SI->hasOneUse())
-            I.setOperand(1, SI->getOperand(2));
-          else
-            UpdateValueUsesWith(SI, SI->getOperand(2));
-          return &I;
-        }
-      // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y
-      if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
-        if (ST->isNullValue()) {
-          Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
-          if (CondI && CondI->getParent() == I.getParent())
-            UpdateValueUsesWith(CondI, ConstantBool::getTrue());
-          else if (I.getParent() != SI->getParent() || SI->hasOneUse())
-            I.setOperand(1, SI->getOperand(1));
-          else
-            UpdateValueUsesWith(SI, SI->getOperand(1));
-          return &I;
-        }
+  }
+  
+  return 0;
+}
 
-      
-      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.
-            if (isPowerOf2_64(STO->getZExtValue()) && 
-                isPowerOf2_64(SFO->getZExtValue())) {
-              Value *TrueAnd = InsertNewInstBefore(
-                BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"),
-                  I);
-              Value *FalseAnd = InsertNewInstBefore(
-                BinaryOperator::createAnd(Op0, SubOne(SFO), SI->getName()+".f"),
-                  I);
-              return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd);
-            }
-          }
+Instruction *InstCombiner::visitSRem(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  Instruction *common = commonRemTransforms(I);
+  if (common)
+    return common;
+
+  common = commonIRemTransforms(I);
+  if (common)
+    return common;
+  
+  if (Value *RHSNeg = dyn_castNegVal(Op1))
+    if (!isa<ConstantInt>(RHSNeg) || !RHSNeg->getType()->isSigned() ||
+        cast<ConstantInt>(RHSNeg)->getSExtValue() > 0) {
+      // X % -Y -> X % Y
+      AddUsesToWorkList(I);
+      I.setOperand(1, RHSNeg);
+      return &I;
+    }
+ 
+  // If the top bits of both operands are zero (i.e. we can prove they are
+  // unsigned inputs), turn this into a urem.
+  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 *URem = BinaryOperator::createURem(LHS, RHS, I.getName());
+    InsertNewInstBefore(URem, I);
+    return new CastInst(URem, I.getType());
+  }
+
+  if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
+    if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
+      // X*C1%C2 --> 0  iff  C1%C2 == 0
+      if (ConstantExpr::getSRem(GetFactor(Op0I), RHS)->isNullValue())
+        return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
     }
   }
-  
+
+  return 0;
+}
+
+Instruction *InstCombiner::visitFRem(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+
+  Instruction *common = commonRemTransforms(I);
+  if (common)
+    return common;
+
+  if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) {
+    // rem X, (Cond ? 0 : Y) -> rem X, Y.  If the rem and the select are in
+    // the same basic block, then we replace the select with Y, and the
+    // condition of the select with false (if the cond value is in the same
+    // BB).  If the select has uses other than the div, this allows them to be
+    // simplified also.
+    if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1)))
+      if (ST->isNullValue()) {
+        Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
+        if (CondI && CondI->getParent() == I.getParent())
+          UpdateValueUsesWith(CondI, ConstantBool::getFalse());
+        else if (I.getParent() != SI->getParent() || SI->hasOneUse())
+          I.setOperand(1, SI->getOperand(2));
+        else
+          UpdateValueUsesWith(SI, SI->getOperand(2));
+        return &I;
+      }
+    // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y
+    if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2)))
+      if (ST->isNullValue()) {
+        Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0));
+        if (CondI && CondI->getParent() == I.getParent())
+          UpdateValueUsesWith(CondI, ConstantBool::getTrue());
+        else if (I.getParent() != SI->getParent() || SI->hasOneUse())
+          I.setOperand(1, SI->getOperand(1));
+        else
+          UpdateValueUsesWith(SI, SI->getOperand(1));
+        return &I;
+      }
+  }
+
   return 0;
 }
 
@@ -4585,7 +4672,9 @@
           break;
 #endif
 
-        case Instruction::Rem:
+        case Instruction::URem:
+          break;
+        case Instruction::SRem:
           // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
           if (CI->isNullValue() && isa<ConstantInt>(BO->getOperand(1)) &&
               BO->hasOneUse() && BO->getOperand(1)->getType()->isSigned()) {
@@ -4596,7 +4685,7 @@
               Value *NewX = InsertNewInstBefore(new CastInst(BO->getOperand(0),
                                                              UTy, "tmp"), I);
               Constant *RHSCst = ConstantInt::get(UTy, 1ULL << L2);
-              Value *NewRem =InsertNewInstBefore(BinaryOperator::createRem(NewX,
+              Value *NewRem =InsertNewInstBefore(BinaryOperator::createURem(NewX,
                                                     RHSCst, BO->getName()), I);
               return BinaryOperator::create(I.getOpcode(), NewRem,
                                             Constant::getNullValue(UTy));


Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.3
--- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2	Sun Oct 22 03:59:01 2006
+++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp	Mon Oct 23 13:13:27 2006
@@ -726,10 +726,12 @@
   Instruction::BinaryOps ops = BO.getOpcode();
 
   switch (ops) {
+    case Instruction::URem:
+    case Instruction::SRem:
     case Instruction::UDiv:
     case Instruction::SDiv:
     case Instruction::FDiv:
-    case Instruction::Rem: {
+    case Instruction::FRem: {
       Value *Divisor = BO.getOperand(1);
       KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor);
       break;


Index: llvm/lib/Transforms/Scalar/Reassociate.cpp
diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.4
--- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3	Sun Oct 22 03:59:01 2006
+++ llvm/lib/Transforms/Scalar/Reassociate.cpp	Mon Oct 23 13:13:27 2006
@@ -113,10 +113,12 @@
       I->getOpcode() == Instruction::Malloc ||
       I->getOpcode() == Instruction::Invoke ||
       I->getOpcode() == Instruction::Call ||
+      I->getOpcode() == Instruction::URem ||
+      I->getOpcode() == Instruction::SRem ||
       I->getOpcode() == Instruction::UDiv || 
       I->getOpcode() == Instruction::SDiv ||
       I->getOpcode() == Instruction::FDiv ||
-      I->getOpcode() == Instruction::Rem)
+      I->getOpcode() == Instruction::FRem)
     return true;
   return false;
 }






More information about the llvm-commits mailing list