[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Feb 27 21:30:57 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.441 -> 1.442
---
Log message:
Rearrange some code, fold "rem X, 0", implementing rem.ll:test6
---
Diffs of the changes: (+39 -38)
InstructionCombining.cpp | 77 +++++++++++++++++++++++------------------------
1 files changed, 39 insertions(+), 38 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.441 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.442
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.441 Sun Feb 26 20:38:23 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Feb 27 23:30:45 2006
@@ -1814,6 +1814,17 @@
Instruction *InstCombiner::visitRem(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())
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
+ 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
+
if (I.getType()->isSigned()) {
if (Value *RHSNeg = dyn_castNegVal(Op1))
if (!isa<ConstantSInt>(RHSNeg) ||
@@ -1842,22 +1853,19 @@
}
}
- 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
-
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
+ // X % 0 == undef, we don't need to preserve faults!
+ if (RHS->equalsInt(0))
+ return ReplaceInstUsesWith(I, UndefValue::get(I.getType()));
+
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 (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
- if (uint64_t Val = C->getValue()) // Don't break X % 0 (divide by zero)
- if (!(Val & (Val-1))) // Power of 2
- return BinaryOperator::createAnd(Op0,
- ConstantUInt::get(I.getType(), Val-1));
+ if (isPowerOf2_64(C->getValue()))
+ return BinaryOperator::createAnd(Op0, SubOne(C));
if (!RHS->isNullValue()) {
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
@@ -1869,35 +1877,6 @@
}
}
- // 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))
- if (ConstantUInt *STO = dyn_cast<ConstantUInt>(SI->getOperand(1)))
- if (ConstantUInt *SFO = dyn_cast<ConstantUInt>(SI->getOperand(2))) {
- if (STO->getValue() == 0) { // Couldn't be this argument.
- I.setOperand(1, SFO);
- return &I;
- } else if (SFO->getValue() == 0) {
- I.setOperand(1, STO);
- return &I;
- }
-
- if (!(STO->getValue() & (STO->getValue()-1)) &&
- !(SFO->getValue() & (SFO->getValue()-1))) {
- 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);
- }
- }
-
- // 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()));
-
-
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() &&
@@ -1911,6 +1890,28 @@
return BinaryOperator::createAnd(Op0, Add);
}
}
+
+ // 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))
+ if (ConstantUInt *STO = dyn_cast<ConstantUInt>(SI->getOperand(1)))
+ if (ConstantUInt *SFO = dyn_cast<ConstantUInt>(SI->getOperand(2))) {
+ if (STO->getValue() == 0) { // Couldn't be this argument.
+ I.setOperand(1, SFO);
+ return &I;
+ } else if (SFO->getValue() == 0) {
+ I.setOperand(1, STO);
+ return &I;
+ }
+
+ if (isPowerOf2_64(STO->getValue()) && isPowerOf2_64(SFO->getValue())){
+ 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;
More information about the llvm-commits
mailing list