From 59a20773f8f7b45a7558e5442aa506c752353d35 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 20 Jul 2004 05:21:00 +0000 Subject: [PATCH] Implement Transforms/InstCombine/IntPtrCast.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15029 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 27ba7ab1633..376222ffe27 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1966,7 +1966,7 @@ static CastType getCastType(const Type *Src, const Type *Dest) { // instruction. // static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy, - const Type *DstTy) { + 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 @@ -1974,6 +1974,15 @@ static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy, if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy)) return true; + // If the source and destination types are pointer types, and the intermediate + // is an integer type bigger than a pointer, eliminate the casts. + if (isa(SrcTy) && isa(DstTy)) { + if (isa(MidTy)) return true; + + if (MidTy->isInteger() && MidTy->getPrimitiveSize() >= TD->getPointerSize()) + return true; + } + // Allow free casting and conversion of sizes as long as the sign doesn't // change... if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) { @@ -2010,18 +2019,14 @@ static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy, return true; } } - - // Otherwise, we cannot succeed. Specifically we do not want to allow things - // like: short -> ushort -> uint, because this can create wrong results if - // the input short is negative! - // return false; } -static bool ValueRequiresCast(const Value *V, const Type *Ty) { +static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) { if (V->getType() == Ty || isa(V)) return false; if (const CastInst *CI = dyn_cast(V)) - if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty)) + if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty, + TD)) return false; return true; } @@ -2056,7 +2061,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // if (CastInst *CSrc = dyn_cast(Src)) { if (isEliminableCastOfCast(CSrc->getOperand(0)->getType(), - CSrc->getType(), CI.getType())) { + CSrc->getType(), CI.getType(), TD)) { // This instruction now refers directly to the cast's src operand. This // has a good chance of making CSrc dead. CI.setOperand(0, CSrc->getOperand(0)); @@ -2153,8 +2158,8 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // Don't insert two casts if they cannot be eliminated. We allow two // casts to be inserted if the sizes are the same. This could only be // converting signedness, which is a noop. - if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy) || - !ValueRequiresCast(Op0, DestTy)) { + if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy,TD) || + !ValueRequiresCast(Op0, DestTy, TD)) { Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); return BinaryOperator::create(cast(SrcI)