[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Jun 8 23:30:01 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.206 -> 1.207
---
Log message:
Implement select.ll:test14*
---
Diffs of the changes: (+59 -35)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.206 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.207
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.206 Thu May 27 12:30:27 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jun 8 23:24:29 2004
@@ -1471,44 +1471,68 @@
return BinaryOperator::create(Instruction::Or, Not, Op1);
}
- // Check to see if we are doing one of many comparisons against constant
- // integers at the end of their ranges...
- //
+ // See if we are doing a comparison between a constant and an instruction that
+ // can be folded into the comparison.
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
- if (LHSI->hasOneUse() && LHSI->getNumOperands() == 2 &&
- isa<ConstantInt>(LHSI->getOperand(1))) {
- // If this is: (X >> C1) & C2 != C3 (where any shift and any compare
- // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This
- // happens a LOT in code produced by the C front-end, for bitfield
- // access.
- if (LHSI->getOpcode() == Instruction::And &&
- LHSI->getOperand(0)->hasOneUse())
- if (ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0)))
- if (ConstantUInt *ShAmt =
- dyn_cast<ConstantUInt>(Shift->getOperand(1))) {
- ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
-
- // We can fold this as long as we can't shift unknown bits into
- // the mask. This can only happen with signed shift rights, as
- // they sign-extend.
- const Type *Ty = Shift->getType();
- if (Shift->getOpcode() != Instruction::Shr ||
- Shift->getType()->isUnsigned() ||
- // To test for the bad case of the signed shr, see if any of
- // the bits shifted in could be tested after the mask.
- ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) {
- unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl
- ? Instruction::Shr : Instruction::Shl;
- I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt));
- LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST, ShAmt));
- LHSI->setOperand(0, Shift->getOperand(0));
- WorkList.push_back(Shift); // Shift is probably dead.
- AddUsesToWorkList(I);
- return &I;
+ if (LHSI->hasOneUse())
+ if (LHSI->getNumOperands() == 2 &&
+ isa<ConstantInt>(LHSI->getOperand(1))) {
+ // If this is: (X >> C1) & C2 != C3 (where any shift and any compare
+ // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This
+ // happens a LOT in code produced by the C front-end, for bitfield
+ // access.
+ if (LHSI->getOpcode() == Instruction::And &&
+ LHSI->getOperand(0)->hasOneUse())
+ if (ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0)))
+ if (ConstantUInt *ShAmt =
+ dyn_cast<ConstantUInt>(Shift->getOperand(1))) {
+ ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
+
+ // We can fold this as long as we can't shift unknown bits into
+ // the mask. This can only happen with signed shift rights, as
+ // they sign-extend.
+ const Type *Ty = Shift->getType();
+ if (Shift->getOpcode() != Instruction::Shr ||
+ Shift->getType()->isUnsigned() ||
+ // To test for the bad case of the signed shr, see if any of
+ // the bits shifted in could be tested after the mask.
+ ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) {
+ unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl
+ ? Instruction::Shr : Instruction::Shl;
+ I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt));
+ LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST,ShAmt));
+ LHSI->setOperand(0, Shift->getOperand(0));
+ WorkList.push_back(Shift); // Shift is probably dead.
+ AddUsesToWorkList(I);
+ return &I;
+ }
}
- }
- }
+
+ } else if (SelectInst *SI = dyn_cast<SelectInst>(LHSI)) {
+ // If either operand of the select is a constant, we can fold the
+ // comparison into the select arms, which will cause one to be
+ // constant folded and the select turned into a bitwise or.
+ Value *Op1 = 0, *Op2 = 0;
+ if (Constant *C = dyn_cast<Constant>(SI->getOperand(1))) {
+ // Fold the known value into the constant operand.
+ Op1 = ConstantExpr::get(I.getOpcode(), C, CI);
+ // Insert a new SetCC of the other select operand.
+ Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
+ SI->getOperand(2), CI,
+ I.getName()), I);
+ } else if (Constant *C = dyn_cast<Constant>(SI->getOperand(2))) {
+ // Fold the known value into the constant operand.
+ Op2 = ConstantExpr::get(I.getOpcode(), C, CI);
+ // Insert a new SetCC of the other select operand.
+ Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
+ SI->getOperand(1), CI,
+ I.getName()), I);
+ }
+
+ if (Op1)
+ return new SelectInst(SI->getCondition(), Op1, Op2);
+ }
// Simplify seteq and setne instructions...
if (I.getOpcode() == Instruction::SetEQ ||
More information about the llvm-commits
mailing list