summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-24 18:35:40 +0000
committerChris Lattner <sabre@nondot.org>2009-03-24 18:35:40 +0000
commita0e6969bbe1c4de13b0c4635df03c354c3993ef7 (patch)
tree9c28e116ffbfc49880477ec1fc624bc5403413b3
parent1f8c564d7df985082d7e728330979781f384d0e9 (diff)
downloadllvm-a0e6969bbe1c4de13b0c4635df03c354c3993ef7.tar.gz
llvm-a0e6969bbe1c4de13b0c4635df03c354c3993ef7.tar.bz2
llvm-a0e6969bbe1c4de13b0c4635df03c354c3993ef7.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67638 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp42
-rw-r--r--test/Transforms/InstCombine/ptr-int-cast.ll16
2 files changed, 53 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index e4e7971549..17ac5b7d8d 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/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;
diff --git a/test/Transforms/InstCombine/ptr-int-cast.ll b/test/Transforms/InstCombine/ptr-int-cast.ll
new file mode 100644
index 0000000000..5c15439777
--- /dev/null
+++ b/test/Transforms/InstCombine/ptr-int-cast.ll
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t
+
+define i1 @test1(i32 *%x) nounwind {
+entry:
+; RUN: grep {ptrtoint i32\\* %x to i64} %t
+ %tmp = ptrtoint i32* %x to i1
+ ret i1 %tmp
+}
+
+define i32* @test2(i128 %x) nounwind {
+entry:
+; RUN: grep {inttoptr i64 %.mp1 to i32\\*} %t
+ %tmp = inttoptr i128 %x to i32*
+ ret i32* %tmp
+}
+