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

Chris Lattner lattner at cs.uiuc.edu
Sun Feb 22 23:43:02 PST 2004


Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.156 -> 1.157

---
Log message:

Implement InstCombine/mul.ll:test10, which is a case that occurs when dealing
with "predication"


---
Diffs of the changes:  (+40 -0)

Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.156 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.157
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.156	Sat Feb 21 23:25:17 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Sun Feb 22 23:39:21 2004
@@ -599,6 +599,46 @@
     if (Value *Op1v = dyn_castNegVal(I.getOperand(1)))
       return BinaryOperator::create(Instruction::Mul, Op0v, Op1v);
 
+  // If one of the operands of the multiply is a cast from a boolean value, then
+  // we know the bool is either zero or one, so this is a 'masking' multiply.
+  // See if we can simplify things based on how the boolean was originally
+  // formed.
+  CastInst *BoolCast = 0;
+  if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(0)))
+    if (CI->getOperand(0)->getType() == Type::BoolTy)
+      BoolCast = CI;
+  if (!BoolCast)
+    if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(1)))
+      if (CI->getOperand(0)->getType() == Type::BoolTy)
+        BoolCast = CI;
+  if (BoolCast) {
+    if (SetCondInst *SCI = dyn_cast<SetCondInst>(BoolCast->getOperand(0))) {
+      Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
+      const Type *SCOpTy = SCIOp0->getType();
+
+      // If the source is X < 0, and X is a signed integer type, convert this
+      // multiply into a shift/and combination.
+      if (SCI->getOpcode() == Instruction::SetLT &&
+          isa<Constant>(SCIOp1) && cast<Constant>(SCIOp1)->isNullValue() &&
+          SCOpTy->isInteger() && SCOpTy->isSigned()) {
+
+        // Shift the X value right to turn it into "all signbits".
+        Constant *Amt = ConstantUInt::get(Type::UByteTy,
+                                          SCOpTy->getPrimitiveSize()*8-1);
+        Value *V = new ShiftInst(Instruction::Shr, SCIOp0, Amt,
+                                 BoolCast->getName()+".mask", &I);
+
+        // If the multiply type is not the same as the source type, sign extend
+        // or truncate to the multiply type.
+        if (I.getType() != V->getType())
+          V = new CastInst(V, I.getType(), V->getName(), &I);
+        
+        Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0;
+        return BinaryOperator::create(Instruction::And, V, OtherOp);
+      }
+    }
+  }
+
   return Changed ? &I : 0;
 }
 





More information about the llvm-commits mailing list