Skip to content

Commit 1d7d26c

Browse files
committed
[InstCombine] Support ptrtoaddr of gep fold
This fold can be directly reused for ptrtoaddr. One caveat is that for an inttoptr base, it currently won't work for pointers with non-address bits. It's possible to support this case.
1 parent c4040f2 commit 1d7d26c

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,7 +2148,7 @@ Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
21482148
return nullptr;
21492149
}
21502150

2151-
Value *InstCombinerImpl::foldPtrToIntOfGEP(Type *IntTy, Value *Ptr) {
2151+
Value *InstCombinerImpl::foldPtrToIntOrAddrOfGEP(Type *IntTy, Value *Ptr) {
21522152
// Look through chain of one-use GEPs.
21532153
Type *PtrTy = Ptr->getType();
21542154
SmallVector<GEPOperator *> GEPs;
@@ -2210,7 +2210,7 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
22102210
Mask->getType() == Ty)
22112211
return BinaryOperator::CreateAnd(Builder.CreatePtrToInt(Ptr, Ty), Mask);
22122212

2213-
if (Value *V = foldPtrToIntOfGEP(Ty, SrcOp))
2213+
if (Value *V = foldPtrToIntOrAddrOfGEP(Ty, SrcOp))
22142214
return replaceInstUsesWith(CI, V);
22152215

22162216
Value *Vec, *Scalar, *Index;
@@ -2240,6 +2240,9 @@ Instruction *InstCombinerImpl::visitPtrToAddr(PtrToAddrInst &CI) {
22402240
Mask->getType() == Ty)
22412241
return BinaryOperator::CreateAnd(Builder.CreatePtrToAddr(Ptr), Mask);
22422242

2243+
if (Value *V = foldPtrToIntOrAddrOfGEP(Ty, SrcOp))
2244+
return replaceInstUsesWith(CI, V);
2245+
22432246
// FIXME: Implement variants of ptrtoint folds.
22442247
return commonCastTransforms(CI);
22452248
}

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
700700
/// folded operation.
701701
void PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN);
702702

703-
Value *foldPtrToIntOfGEP(Type *IntTy, Value *Ptr);
703+
Value *foldPtrToIntOrAddrOfGEP(Type *IntTy, Value *Ptr);
704704
Instruction *foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, CmpPredicate Cond,
705705
Instruction &I);
706706
Instruction *foldSelectICmp(CmpPredicate Pred, SelectInst *SI, Value *RHS,

llvm/test/Transforms/InstCombine/ptrtoaddr.ll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,51 @@ define i32 @ptrtoaddr_of_ptrmask_addrsize(ptr addrspace(1) %p, i32 %mask) {
261261
%addr = ptrtoaddr ptr addrspace(1) %masked to i32
262262
ret i32 %addr
263263
}
264+
265+
define i64 @ptrtoaddr_of_gep_of_inttoptr(i64 %int, i64 %offset) {
266+
; CHECK-LABEL: define i64 @ptrtoaddr_of_gep_of_inttoptr(
267+
; CHECK-SAME: i64 [[INT:%.*]], i64 [[OFFSET:%.*]]) {
268+
; CHECK-NEXT: [[ADDR:%.*]] = add i64 [[INT]], [[OFFSET]]
269+
; CHECK-NEXT: ret i64 [[ADDR]]
270+
;
271+
%ptr = inttoptr i64 %int to ptr
272+
%gep = getelementptr i8, ptr %ptr, i64 %offset
273+
%addr = ptrtoaddr ptr %gep to i64
274+
ret i64 %addr
275+
}
276+
277+
; FIXME: This could be supported by truncating %int before performing the
278+
; arithmetic.
279+
define i32 @ptrtoaddr_of_gep_of_inttoptr_addrsize(i64 %int, i32 %offset) {
280+
; CHECK-LABEL: define i32 @ptrtoaddr_of_gep_of_inttoptr_addrsize(
281+
; CHECK-SAME: i64 [[INT:%.*]], i32 [[OFFSET:%.*]]) {
282+
; CHECK-NEXT: [[PTR:%.*]] = inttoptr i64 [[INT]] to ptr addrspace(1)
283+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[PTR]], i32 [[OFFSET]]
284+
; CHECK-NEXT: [[ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[GEP]] to i32
285+
; CHECK-NEXT: ret i32 [[ADDR]]
286+
;
287+
%ptr = inttoptr i64 %int to ptr addrspace(1)
288+
%gep = getelementptr i8, ptr addrspace(1) %ptr, i32 %offset
289+
%addr = ptrtoaddr ptr addrspace(1) %gep to i32
290+
ret i32 %addr
291+
}
292+
293+
define i64 @ptrtoaddr_of_gep_of_null(i64 %offset) {
294+
; CHECK-LABEL: define i64 @ptrtoaddr_of_gep_of_null(
295+
; CHECK-SAME: i64 [[OFFSET:%.*]]) {
296+
; CHECK-NEXT: ret i64 [[OFFSET]]
297+
;
298+
%gep = getelementptr i8, ptr null, i64 %offset
299+
%addr = ptrtoaddr ptr %gep to i64
300+
ret i64 %addr
301+
}
302+
303+
define i32 @ptrtoaddr_of_gep_of_null_addrsize(i32 %offset) {
304+
; CHECK-LABEL: define i32 @ptrtoaddr_of_gep_of_null_addrsize(
305+
; CHECK-SAME: i32 [[OFFSET:%.*]]) {
306+
; CHECK-NEXT: ret i32 [[OFFSET]]
307+
;
308+
%gep = getelementptr i8, ptr addrspace(1) null, i32 %offset
309+
%addr = ptrtoaddr ptr addrspace(1) %gep to i32
310+
ret i32 %addr
311+
}

0 commit comments

Comments
 (0)