Skip to content

Commit e360e21

Browse files
committed
[InstCombine] fold sub(zext(ptrtoint),zext(ptrtoint))
On a 32-bit target if pointer arithmetic is used in i64 computation, the missed folding in InstCombine results to suboptimal performance, unlike same code compiled for 64bit target
1 parent 17d9565 commit e360e21

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,8 +2618,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
26182618
// Optimize pointer differences into the same array into a size. Consider:
26192619
// &A[10] - &A[0]: we should compile this to "10".
26202620
Value *LHSOp, *RHSOp;
2621-
if (match(Op0, m_PtrToInt(m_Value(LHSOp))) &&
2622-
match(Op1, m_PtrToInt(m_Value(RHSOp))))
2621+
if (match(Op0, m_ZExtOrSelf(m_PtrToInt(m_Value(LHSOp)))) &&
2622+
match(Op1, m_ZExtOrSelf(m_PtrToInt(m_Value(RHSOp)))))
26232623
if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(),
26242624
I.hasNoUnsignedWrap()))
26252625
return replaceInstUsesWith(I, Res);

llvm/test/Transforms/InstCombine/sub-gep.ll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,36 @@ define i64 @test25(ptr %P, i64 %A){
270270
ret i64 %G
271271
}
272272

273+
define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) {
274+
; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint(
275+
; CHECK-NEXT: %1 = sext i32 %offset to i64
276+
; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1
277+
; CHECK-NEXT: %2 = ptrtoint ptr %A to i64
278+
; CHECK-NEXT: %C = and i64 %2, 4294967294
279+
; CHECK-NEXT: %D = sub i64 %C, ptrtoint (ptr @Arr to i64)
280+
; CHECK-NEXT: ret i64 %D
281+
%A = getelementptr bfloat, ptr @Arr, i32 %offset
282+
%B = ptrtoint ptr %A to i32
283+
%C = zext i32 %B to i64
284+
%D = sub i64 %C, ptrtoint (ptr @Arr to i64)
285+
ret i64 %D
286+
}
287+
288+
define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) {
289+
; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint(
290+
; CHECK-NEXT: %1 = sext i32 %offset to i64
291+
; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1
292+
; CHECK-NEXT: %2 = ptrtoint ptr %A to i64
293+
; CHECK-NEXT: %C = and i64 %2, 4294967294
294+
; CHECK-NEXT: %D = sub i64 ptrtoint (ptr @Arr to i64), %C
295+
; CHECK-NEXT: ret i64 %D
296+
%A = getelementptr bfloat, ptr @Arr, i32 %offset
297+
%B = ptrtoint ptr %A to i32
298+
%C = zext i32 %B to i64
299+
%D = sub i64 ptrtoint (ptr @Arr to i64), %C
300+
ret i64 %D
301+
}
302+
273303
@Arr_as1 = external addrspace(1) global [42 x i16]
274304

275305
define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) {
@@ -285,6 +315,32 @@ define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) {
285315
ret i16 %G
286316
}
287317

318+
define i64 @zext_ptrtoint_sub_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) {
319+
; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint_as1(
320+
; CHECK-NEXT: %1 = trunc i32 %offset to i16
321+
; CHECK-NEXT: %A.idx = shl i16 %1, 1
322+
; CHECK-NEXT: %D = sext i16 %A.idx to i64
323+
; CHECK-NEXT: ret i64 %D
324+
%A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset
325+
%B = ptrtoint ptr addrspace(1) %A to i32
326+
%C = zext i32 %B to i64
327+
%D = sub i64 %C, ptrtoint (ptr addrspace(1) @Arr_as1 to i64)
328+
ret i64 %D
329+
}
330+
331+
define i64 @ptrtoint_sub_zext_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) {
332+
; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint_as1(
333+
; CHECK-NEXT: %1 = trunc i32 %offset to i16
334+
; CHECK-NEXT: %A.idx.neg = mul i16 %1, -2
335+
; CHECK-NEXT: %D = sext i16 %A.idx.neg to i64
336+
; CHECK-NEXT: ret i64 %D
337+
%A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset
338+
%B = ptrtoint ptr addrspace(1) %A to i32
339+
%C = zext i32 %B to i64
340+
%D = sub i64 ptrtoint (ptr addrspace(1) @Arr_as1 to i64), %C
341+
ret i64 %D
342+
}
343+
288344
define i64 @test30(ptr %foo, i64 %i, i64 %j) {
289345
; CHECK-LABEL: @test30(
290346
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2

0 commit comments

Comments
 (0)