diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-03-24 18:35:40 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-03-24 18:35:40 +0000 |
| commit | 306813cbbb043c42575eecd5ccb545a66a5d7b2d (patch) | |
| tree | 54e22a8ef587e98ab380af90e4ab56560f3650e8 /llvm/lib/Transforms | |
| parent | 4d7e4ee799440218761fa27a09d119849c8a84ad (diff) | |
| download | bcm5719-llvm-306813cbbb043c42575eecd5ccb545a66a5d7b2d.tar.gz bcm5719-llvm-306813cbbb043c42575eecd5ccb545a66a5d7b2d.zip | |
canonicalize inttoptr and ptrtoint instructions which cast pointers
to/from integer types that are not intptr_t to convert to intptr_t
then do an integer conversion to the dest type. This exposes the
cast to the optimizer.
llvm-svn: 67638
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index e4e7971549e..17ac5b7d8d5 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -218,7 +218,7 @@ namespace { Instruction *visitFPToSI(FPToSIInst &FI); Instruction *visitUIToFP(CastInst &CI); Instruction *visitSIToFP(CastInst &CI); - Instruction *visitPtrToInt(CastInst &CI); + Instruction *visitPtrToInt(PtrToIntInst &CI); Instruction *visitIntToPtr(IntToPtrInst &CI); Instruction *visitBitCast(BitCastInst &CI); Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI, @@ -474,9 +474,16 @@ isEliminableCastPair( Instruction::CastOps firstOp = Instruction::CastOps(CI->getOpcode()); Instruction::CastOps secondOp = Instruction::CastOps(opcode); - return Instruction::CastOps( - CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, - DstTy, TD->getIntPtrType())); + unsigned Res = CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, + DstTy, TD->getIntPtrType()); + + // We don't want to form an inttoptr or ptrtoint that converts to an integer + // type that differs from the pointer size. + if ((Res == Instruction::IntToPtr && SrcTy != TD->getIntPtrType()) || + (Res == Instruction::PtrToInt && DstTy != TD->getIntPtrType())) + Res = 0; + + return Instruction::CastOps(Res); } /// ValueRequiresCast - Return true if the cast from "V to Ty" actually results @@ -8536,11 +8543,36 @@ Instruction *InstCombiner::visitSIToFP(CastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombiner::visitPtrToInt(CastInst &CI) { +Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) { + // If the destination integer type is smaller than the intptr_t type for + // this target, do a ptrtoint to intptr_t then do a trunc. This allows the + // trunc to be exposed to other transforms. Don't do this for extending + // ptrtoint's, because we don't know if the target sign or zero extends its + // pointers. + if (CI.getType()->getPrimitiveSizeInBits() < TD->getPointerSizeInBits()) { + Value *P = InsertNewInstBefore(new PtrToIntInst(CI.getOperand(0), + TD->getIntPtrType(), + "tmp"), CI); + return new TruncInst(P, CI.getType()); + } + return commonPointerCastTransforms(CI); } Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) { + // If the source integer type is larger than the intptr_t type for + // this target, do a trunc to the intptr_t type, then inttoptr of it. This + // allows the trunc to be exposed to other transforms. Don't do this for + // extending inttoptr's, because we don't know if the target sign or zero + // extends to pointers. + if (CI.getOperand(0)->getType()->getPrimitiveSizeInBits() > + TD->getPointerSizeInBits()) { + Value *P = InsertNewInstBefore(new TruncInst(CI.getOperand(0), + TD->getIntPtrType(), + "tmp"), CI); + return new IntToPtrInst(P, CI.getType()); + } + if (Instruction *I = commonCastTransforms(CI)) return I; |

