llvm.org GIT mirror llvm / f9d9e45
Implement PR1795, an instcombine hack for forming GEPs with integer pointer arithmetic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45745 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
2 changed file(s) with 73 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
209209 Instruction *visitUIToFP(CastInst &CI);
210210 Instruction *visitSIToFP(CastInst &CI);
211211 Instruction *visitPtrToInt(CastInst &CI);
212 Instruction *visitIntToPtr(CastInst &CI);
212 Instruction *visitIntToPtr(IntToPtrInst &CI);
213213 Instruction *visitBitCast(BitCastInst &CI);
214214 Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI,
215215 Instruction *FI);
71477147 return commonPointerCastTransforms(CI);
71487148 }
71497149
7150 Instruction *InstCombiner::visitIntToPtr(CastInst &CI) {
7151 return commonCastTransforms(CI);
7150 Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
7151 if (Instruction *I = commonCastTransforms(CI))
7152 return I;
7153
7154 const Type *DestPointee = cast(CI.getType())->getElementType();
7155 if (!DestPointee->isSized()) return 0;
7156
7157 // If this is inttoptr(add (ptrtoint x), cst), try to turn this into a GEP.
7158 ConstantInt *Cst;
7159 Value *X;
7160 if (match(CI.getOperand(0), m_Add(m_Cast(m_Value(X)),
7161 m_ConstantInt(Cst)))) {
7162 // If the source and destination operands have the same type, see if this
7163 // is a single-index GEP.
7164 if (X->getType() == CI.getType()) {
7165 // Get the size of the pointee type.
7166 uint64_t Size = TD->getABITypeSizeInBits(DestPointee);
7167
7168 // Convert the constant to intptr type.
7169 APInt Offset = Cst->getValue();
7170 Offset.sextOrTrunc(TD->getPointerSizeInBits());
7171
7172 // If Offset is evenly divisible by Size, we can do this xform.
7173 if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
7174 Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
7175 return new GetElementPtrInst(X, ConstantInt::get(Offset));
7176 }
7177 }
7178 // TODO: Could handle other cases, e.g. where add is indexing into field of
7179 // struct etc.
7180 } else if (CI.getOperand(0)->hasOneUse() &&
7181 match(CI.getOperand(0), m_Add(m_Value(X), m_ConstantInt(Cst)))) {
7182 // Otherwise, if this is inttoptr(add x, cst), try to turn this into an
7183 // "inttoptr+GEP" instead of "add+intptr".
7184
7185 // Get the size of the pointee type.
7186 uint64_t Size = TD->getABITypeSize(DestPointee);
7187
7188 // Convert the constant to intptr type.
7189 APInt Offset = Cst->getValue();
7190 Offset.sextOrTrunc(TD->getPointerSizeInBits());
7191
7192 // If Offset is evenly divisible by Size, we can do this xform.
7193 if (Size && !APIntOps::srem(Offset, APInt(Offset.getBitWidth(), Size))){
7194 Offset = APIntOps::sdiv(Offset, APInt(Offset.getBitWidth(), Size));
7195
7196 Instruction *P = InsertNewInstBefore(new IntToPtrInst(X, CI.getType(),
7197 "tmp"), CI);
7198 return new GetElementPtrInst(P, ConstantInt::get(Offset), "tmp");
7199 }
7200 }
7201 return 0;
71527202 }
71537203
71547204 Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
11 ; RUN: grep -v OK | not grep add
2
3 ;; Target triple for gep raising case below.
4 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"
5 target triple = "i686-apple-darwin8"
26
37 define i64 @test1(i64 %A, i32 %B) {
48 %tmp12 = zext i32 %B to i64
812 ret i64 %tmp6
913 }
1014
15 ; PR1795
16 define void @test2(i32 %.val24) {
17 EntryBlock:
18 add i32 %.val24, -12
19 inttoptr i32 %0 to i32*
20 store i32 1, i32* %1
21 add i32 %.val24, -16
22 inttoptr i32 %2 to i32*
23 getelementptr i32* %3, i32 1
24 load i32* %4
25 tail call i32 @callee( i32 %5 )
26 ret void
27 }
28
29 declare i32 @callee(i32)
30