[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Jul 21 12:50:55 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.229 -> 1.230
---
Log message:
Make cast-cast code a bit more defensive
"simplify" a bit of code for comparison/and folding
---
Diffs of the changes: (+42 -32)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.229 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.230
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.229 Tue Jul 20 23:27:24 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Jul 21 14:50:44 2004
@@ -1453,38 +1453,42 @@
if (LHSI->hasOneUse())
switch (LHSI->getOpcode()) {
case Instruction::And:
- if (isa<ConstantInt>(LHSI->getOperand(1))) {
-
-
+ if (isa<ConstantInt>(LHSI->getOperand(1)) &&
+ LHSI->getOperand(0)->hasOneUse()) {
// 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->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));
+ ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
+ ConstantUInt *ShAmt;
+ ShAmt = Shift ? dyn_cast<ConstantUInt>(Shift->getOperand(1)) : 0;
+ ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
+ const Type *Ty = LHSI->getType();
- // 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;
- }
- }
+ // 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.
+ if (ShAmt) {
+ bool CanFold = Shift->getOpcode() != Instruction::Shr ||
+ Shift->getType()->isUnsigned();
+ if (!CanFold &&
+ // 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()) {
+ CanFold = true;
+ }
+
+ if (CanFold) {
+ 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 dead.
+ AddUsesToWorkList(I);
+ return &I;
+ }
+ }
}
break;
case Instruction::Div:
@@ -1970,7 +1974,7 @@
// It is legal to eliminate the instruction if casting A->B->A if the sizes
// are identical and the bits don't get reinterpreted (for example
- // int->float->int would not be allowed)
+ // int->float->int would not be allowed).
if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy))
return true;
@@ -1994,9 +1998,9 @@
// First cast is a truncate
1, 1, 4, 4, // trunc->extend is not safe to eliminate
// First cast is a sign ext
- 2, 5, 2, 4, // signext->trunc always ok, signext->zeroext never ok
+ 2, 5, 2, 4, // signext->zeroext never ok
// First cast is a zero ext
- 3, 5, 3, 3, // zeroext->trunc always ok
+ 3, 5, 3, 3,
};
unsigned Result = CastResult[FirstCast*4+SecondCast];
@@ -2012,8 +2016,14 @@
case 4:
return false; // Not possible to eliminate this here.
case 5:
- // Sign or zero extend followed by truncate is always ok
- return true;
+ // Sign or zero extend followed by truncate is always ok if the result
+ // is a truncate or noop.
+ CastType ResultCast = getCastType(SrcTy, DstTy);
+ if (ResultCast == Noop || ResultCast == Truncate)
+ return true;
+ // Otherwise we are still growing the value, we are only safe if the
+ // result will match the sign/zeroextendness of the result.
+ return ResultCast == FirstCast;
}
}
return false;
More information about the llvm-commits
mailing list