[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat May 6 02:00:29 PDT 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.476 -> 1.477
---
Log message:
Move some code around.
Make the "fold (and (cast A), (cast B)) -> (cast (and A, B))" transformation
only apply when both casts really will cause code to be generated. If one or
both doesn't, then this xform doesn't remove a cast.
This fixes Transforms/InstCombine/2006-05-06-Infloop.ll
---
Diffs of the changes: (+140 -124)
InstructionCombining.cpp | 264 ++++++++++++++++++++++++-----------------------
1 files changed, 140 insertions(+), 124 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.476 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.477
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.476 Fri May 5 15:51:30 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat May 6 04:00:16 2006
@@ -304,6 +304,137 @@
return 0;
}
+enum CastType {
+ Noop = 0,
+ Truncate = 1,
+ Signext = 2,
+ Zeroext = 3
+};
+
+/// getCastType - In the future, we will split the cast instruction into these
+/// various types. Until then, we have to do the analysis here.
+static CastType getCastType(const Type *Src, const Type *Dest) {
+ assert(Src->isIntegral() && Dest->isIntegral() &&
+ "Only works on integral types!");
+ unsigned SrcSize = Src->getPrimitiveSizeInBits();
+ unsigned DestSize = Dest->getPrimitiveSizeInBits();
+
+ if (SrcSize == DestSize) return Noop;
+ if (SrcSize > DestSize) return Truncate;
+ if (Src->isSigned()) return Signext;
+ return Zeroext;
+}
+
+
+// isEliminableCastOfCast - Return true if it is valid to eliminate the CI
+// instruction.
+//
+static bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy,
+ const Type *DstTy, TargetData *TD) {
+
+ // 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).
+ if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy))
+ return true;
+
+ // If we are casting between pointer and integer types, treat pointers as
+ // integers of the appropriate size for the code below.
+ if (isa<PointerType>(SrcTy)) SrcTy = TD->getIntPtrType();
+ if (isa<PointerType>(MidTy)) MidTy = TD->getIntPtrType();
+ if (isa<PointerType>(DstTy)) DstTy = TD->getIntPtrType();
+
+ // Allow free casting and conversion of sizes as long as the sign doesn't
+ // change...
+ if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
+ CastType FirstCast = getCastType(SrcTy, MidTy);
+ CastType SecondCast = getCastType(MidTy, DstTy);
+
+ // Capture the effect of these two casts. If the result is a legal cast,
+ // the CastType is stored here, otherwise a special code is used.
+ static const unsigned CastResult[] = {
+ // First cast is noop
+ 0, 1, 2, 3,
+ // 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->zeroext never ok
+ // First cast is a zero ext
+ 3, 5, 3, 3,
+ };
+
+ unsigned Result = CastResult[FirstCast*4+SecondCast];
+ switch (Result) {
+ default: assert(0 && "Illegal table value!");
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ // FIXME: in the future, when LLVM has explicit sign/zeroextends and
+ // truncates, we could eliminate more casts.
+ return (unsigned)getCastType(SrcTy, DstTy) == Result;
+ case 4:
+ return false; // Not possible to eliminate this here.
+ case 5:
+ // 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;
+ }
+ }
+
+ // If this is a cast from 'float -> double -> integer', cast from
+ // 'float -> integer' directly, as the value isn't changed by the
+ // float->double conversion.
+ if (SrcTy->isFloatingPoint() && MidTy->isFloatingPoint() &&
+ DstTy->isIntegral() &&
+ SrcTy->getPrimitiveSize() < MidTy->getPrimitiveSize())
+ return true;
+
+ // Packed type conversions don't modify bits.
+ if (isa<PackedType>(SrcTy) && isa<PackedType>(MidTy) &&isa<PackedType>(DstTy))
+ return true;
+
+ return false;
+}
+
+/// ValueRequiresCast - Return true if the cast from "V to Ty" actually results
+/// in any code being generated. It does not require codegen if V is simple
+/// enough or if the cast can be folded into other casts.
+static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
+ if (V->getType() == Ty || isa<Constant>(V)) return false;
+
+ // If this is a noop cast, it isn't real codegen.
+ if (V->getType()->isLosslesslyConvertibleTo(Ty))
+ return false;
+
+ // If this is another cast that can be elimianted, it isn't codegen either.
+ if (const CastInst *CI = dyn_cast<CastInst>(V))
+ if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty,
+ TD))
+ return false;
+ return true;
+}
+
+/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
+/// InsertBefore instruction. This is specialized a bit to avoid inserting
+/// casts that are known to not do anything...
+///
+Value *InstCombiner::InsertOperandCastBefore(Value *V, const Type *DestTy,
+ Instruction *InsertBefore) {
+ if (V->getType() == DestTy) return V;
+ if (Constant *C = dyn_cast<Constant>(V))
+ return ConstantExpr::getCast(C, DestTy);
+
+ CastInst *CI = new CastInst(V, DestTy, V->getName());
+ InsertNewInstBefore(CI, *InsertBefore);
+ return CI;
+}
+
// SimplifyCommutative - This performs a few simplifications for commutative
// operators:
//
@@ -2645,7 +2776,9 @@
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
- !SrcTy->isLosslesslyConvertibleTo(Op0C->getType())) {
+ // Only do this if the casts both really cause code to be generated.
+ ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createAnd(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -2885,7 +3018,9 @@
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
- !SrcTy->isLosslesslyConvertibleTo(Op0C->getType())) {
+ // Only do this if the casts both really cause code to be generated.
+ ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -3064,7 +3199,9 @@
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
- !SrcTy->isLosslesslyConvertibleTo(Op0C->getType())) {
+ // Only do this if the casts both really cause code to be generated.
+ ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createXor(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -4500,127 +4637,6 @@
return 0;
}
-enum CastType {
- Noop = 0,
- Truncate = 1,
- Signext = 2,
- Zeroext = 3
-};
-
-/// getCastType - In the future, we will split the cast instruction into these
-/// various types. Until then, we have to do the analysis here.
-static CastType getCastType(const Type *Src, const Type *Dest) {
- assert(Src->isIntegral() && Dest->isIntegral() &&
- "Only works on integral types!");
- unsigned SrcSize = Src->getPrimitiveSizeInBits();
- unsigned DestSize = Dest->getPrimitiveSizeInBits();
-
- if (SrcSize == DestSize) return Noop;
- if (SrcSize > DestSize) return Truncate;
- if (Src->isSigned()) return Signext;
- return Zeroext;
-}
-
-
-// isEliminableCastOfCast - Return true if it is valid to eliminate the CI
-// instruction.
-//
-static bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy,
- const Type *DstTy, TargetData *TD) {
-
- // 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).
- if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy))
- return true;
-
- // If we are casting between pointer and integer types, treat pointers as
- // integers of the appropriate size for the code below.
- if (isa<PointerType>(SrcTy)) SrcTy = TD->getIntPtrType();
- if (isa<PointerType>(MidTy)) MidTy = TD->getIntPtrType();
- if (isa<PointerType>(DstTy)) DstTy = TD->getIntPtrType();
-
- // Allow free casting and conversion of sizes as long as the sign doesn't
- // change...
- if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
- CastType FirstCast = getCastType(SrcTy, MidTy);
- CastType SecondCast = getCastType(MidTy, DstTy);
-
- // Capture the effect of these two casts. If the result is a legal cast,
- // the CastType is stored here, otherwise a special code is used.
- static const unsigned CastResult[] = {
- // First cast is noop
- 0, 1, 2, 3,
- // 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->zeroext never ok
- // First cast is a zero ext
- 3, 5, 3, 3,
- };
-
- unsigned Result = CastResult[FirstCast*4+SecondCast];
- switch (Result) {
- default: assert(0 && "Illegal table value!");
- case 0:
- case 1:
- case 2:
- case 3:
- // FIXME: in the future, when LLVM has explicit sign/zeroextends and
- // truncates, we could eliminate more casts.
- return (unsigned)getCastType(SrcTy, DstTy) == Result;
- case 4:
- return false; // Not possible to eliminate this here.
- case 5:
- // 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;
- }
- }
-
- // If this is a cast from 'float -> double -> integer', cast from
- // 'float -> integer' directly, as the value isn't changed by the
- // float->double conversion.
- if (SrcTy->isFloatingPoint() && MidTy->isFloatingPoint() &&
- DstTy->isIntegral() &&
- SrcTy->getPrimitiveSize() < MidTy->getPrimitiveSize())
- return true;
-
- // Packed type conversions don't modify bits.
- if (isa<PackedType>(SrcTy) && isa<PackedType>(MidTy) &&isa<PackedType>(DstTy))
- return true;
-
- return false;
-}
-
-static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
- if (V->getType() == Ty || isa<Constant>(V)) return false;
- if (const CastInst *CI = dyn_cast<CastInst>(V))
- if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty,
- TD))
- return false;
- return true;
-}
-
-/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
-/// InsertBefore instruction. This is specialized a bit to avoid inserting
-/// casts that are known to not do anything...
-///
-Value *InstCombiner::InsertOperandCastBefore(Value *V, const Type *DestTy,
- Instruction *InsertBefore) {
- if (V->getType() == DestTy) return V;
- if (Constant *C = dyn_cast<Constant>(V))
- return ConstantExpr::getCast(C, DestTy);
-
- CastInst *CI = new CastInst(V, DestTy, V->getName());
- InsertNewInstBefore(CI, *InsertBefore);
- return CI;
-}
/// DecomposeSimpleLinearExpr - Analyze 'Val', seeing if it is a simple linear
/// expression. If so, decompose it, returning some value X, such that Val is
More information about the llvm-commits
mailing list