[llvm-commits] [llvm] r45745 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/add2.ll
Chris Lattner
sabre at nondot.org
Mon Jan 7 23:23:51 PST 2008
Author: lattner
Date: Tue Jan 8 01:23:51 2008
New Revision: 45745
URL: http://llvm.org/viewvc/llvm-project?rev=45745&view=rev
Log:
Implement PR1795, an instcombine hack for forming GEPs with integer pointer arithmetic.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/add2.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=45745&r1=45744&r2=45745&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jan 8 01:23:51 2008
@@ -210,7 +210,7 @@
Instruction *visitUIToFP(CastInst &CI);
Instruction *visitSIToFP(CastInst &CI);
Instruction *visitPtrToInt(CastInst &CI);
- Instruction *visitIntToPtr(CastInst &CI);
+ Instruction *visitIntToPtr(IntToPtrInst &CI);
Instruction *visitBitCast(BitCastInst &CI);
Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI,
Instruction *FI);
@@ -7148,8 +7148,58 @@
return commonPointerCastTransforms(CI);
}
-Instruction *InstCombiner::visitIntToPtr(CastInst &CI) {
- return commonCastTransforms(CI);
+Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
+ if (Instruction *I = commonCastTransforms(CI))
+ return I;
+
+ const Type *DestPointee = cast<PointerType>(CI.getType())->getElementType();
+ if (!DestPointee->isSized()) return 0;
+
+ // If this is inttoptr(add (ptrtoint x), cst), try to turn this into a GEP.
+ ConstantInt *Cst;
+ Value *X;
+ if (match(CI.getOperand(0), m_Add(m_Cast<PtrToIntInst>(m_Value(X)),
+ m_ConstantInt(Cst)))) {
+ // If the source and destination operands have the same type, see if this
+ // is a single-index GEP.
+ if (X->getType() == CI.getType()) {
+ // Get the size of the pointee type.
+ uint64_t Size = TD->getABITypeSizeInBits(DestPointee);
+
+ // Convert the constant to intptr type.
+ APInt Offset = Cst->getValue();
+ Offset.sextOrTrunc(TD->getPointerSizeInBits());
+
+ // If Offset is evenly divisible by Size, we can do this xform.
+ if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
+ Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
+ return new GetElementPtrInst(X, ConstantInt::get(Offset));
+ }
+ }
+ // TODO: Could handle other cases, e.g. where add is indexing into field of
+ // struct etc.
+ } else if (CI.getOperand(0)->hasOneUse() &&
+ match(CI.getOperand(0), m_Add(m_Value(X), m_ConstantInt(Cst)))) {
+ // Otherwise, if this is inttoptr(add x, cst), try to turn this into an
+ // "inttoptr+GEP" instead of "add+intptr".
+
+ // Get the size of the pointee type.
+ uint64_t Size = TD->getABITypeSize(DestPointee);
+
+ // Convert the constant to intptr type.
+ APInt Offset = Cst->getValue();
+ Offset.sextOrTrunc(TD->getPointerSizeInBits());
+
+ // If Offset is evenly divisible by Size, we can do this xform.
+ if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
+ Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
+
+ Instruction *P = InsertNewInstBefore(new IntToPtrInst(X, CI.getType(),
+ "tmp"), CI);
+ return new GetElementPtrInst(P, ConstantInt::get(Offset), "tmp");
+ }
+ }
+ return 0;
}
Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
Modified: llvm/trunk/test/Transforms/InstCombine/add2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add2.ll?rev=45745&r1=45744&r2=45745&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/add2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/add2.ll Tue Jan 8 01:23:51 2008
@@ -1,6 +1,10 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
; RUN: grep -v OK | not grep add
+;; Target triple for gep raising case below.
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
+
define i64 @test1(i64 %A, i32 %B) {
%tmp12 = zext i32 %B to i64
%tmp3 = shl i64 %tmp12, 32
@@ -9,3 +13,19 @@
ret i64 %tmp6
}
+; PR1795
+define void @test2(i32 %.val24) {
+EntryBlock:
+ add i32 %.val24, -12
+ inttoptr i32 %0 to i32*
+ store i32 1, i32* %1
+ add i32 %.val24, -16
+ inttoptr i32 %2 to i32*
+ getelementptr i32* %3, i32 1
+ load i32* %4
+ tail call i32 @callee( i32 %5 )
+ ret void
+}
+
+declare i32 @callee(i32)
+
More information about the llvm-commits
mailing list