From e360e21ee174ac7fb59a3e6df1bb345eae5ed11e Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Thu, 7 Nov 2024 15:19:39 -0500 Subject: [PATCH 1/6] [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 --- .../InstCombine/InstCombineAddSub.cpp | 4 +- llvm/test/Transforms/InstCombine/sub-gep.ll | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 21588aca51275..d931f89b9af42 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2618,8 +2618,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { // Optimize pointer differences into the same array into a size. Consider: // &A[10] - &A[0]: we should compile this to "10". Value *LHSOp, *RHSOp; - if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && - match(Op1, m_PtrToInt(m_Value(RHSOp)))) + if (match(Op0, m_ZExtOrSelf(m_PtrToInt(m_Value(LHSOp)))) && + match(Op1, m_ZExtOrSelf(m_PtrToInt(m_Value(RHSOp))))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), I.hasNoUnsignedWrap())) return replaceInstUsesWith(I, Res); diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index b773d106b2c98..ee18fd607823a 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -270,6 +270,36 @@ define i64 @test25(ptr %P, i64 %A){ ret i64 %G } +define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { +; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint( +; CHECK-NEXT: %1 = sext i32 %offset to i64 +; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 +; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 +; CHECK-NEXT: %C = and i64 %2, 4294967294 +; CHECK-NEXT: %D = sub i64 %C, ptrtoint (ptr @Arr to i64) +; CHECK-NEXT: ret i64 %D + %A = getelementptr bfloat, ptr @Arr, i32 %offset + %B = ptrtoint ptr %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 %C, ptrtoint (ptr @Arr to i64) + ret i64 %D +} + +define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) { +; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint( +; CHECK-NEXT: %1 = sext i32 %offset to i64 +; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 +; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 +; CHECK-NEXT: %C = and i64 %2, 4294967294 +; CHECK-NEXT: %D = sub i64 ptrtoint (ptr @Arr to i64), %C +; CHECK-NEXT: ret i64 %D + %A = getelementptr bfloat, ptr @Arr, i32 %offset + %B = ptrtoint ptr %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 ptrtoint (ptr @Arr to i64), %C + ret i64 %D +} + @Arr_as1 = external addrspace(1) global [42 x i16] define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { @@ -285,6 +315,32 @@ define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { ret i16 %G } +define i64 @zext_ptrtoint_sub_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) { +; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint_as1( +; CHECK-NEXT: %1 = trunc i32 %offset to i16 +; CHECK-NEXT: %A.idx = shl i16 %1, 1 +; CHECK-NEXT: %D = sext i16 %A.idx to i64 +; CHECK-NEXT: ret i64 %D + %A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset + %B = ptrtoint ptr addrspace(1) %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 %C, ptrtoint (ptr addrspace(1) @Arr_as1 to i64) + ret i64 %D +} + +define i64 @ptrtoint_sub_zext_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) { +; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint_as1( +; CHECK-NEXT: %1 = trunc i32 %offset to i16 +; CHECK-NEXT: %A.idx.neg = mul i16 %1, -2 +; CHECK-NEXT: %D = sext i16 %A.idx.neg to i64 +; CHECK-NEXT: ret i64 %D + %A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset + %B = ptrtoint ptr addrspace(1) %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 ptrtoint (ptr addrspace(1) @Arr_as1 to i64), %C + ret i64 %D +} + define i64 @test30(ptr %foo, i64 %i, i64 %j) { ; CHECK-LABEL: @test30( ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 From 5c692fdb697e70ec7df72709910f6a5acd26cdd3 Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Fri, 8 Nov 2024 17:24:30 -0500 Subject: [PATCH 2/6] Changed pattern matching --- .../InstCombine/InstCombineAddSub.cpp | 16 +++++++- llvm/test/Transforms/InstCombine/sub-gep.ll | 39 ++++++++++--------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index d931f89b9af42..4f14b1eb57785 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2618,8 +2618,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { // Optimize pointer differences into the same array into a size. Consider: // &A[10] - &A[0]: we should compile this to "10". Value *LHSOp, *RHSOp; - if (match(Op0, m_ZExtOrSelf(m_PtrToInt(m_Value(LHSOp)))) && - match(Op1, m_ZExtOrSelf(m_PtrToInt(m_Value(RHSOp))))) + if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && + match(Op1, m_PtrToInt(m_Value(RHSOp)))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(), I.hasNoUnsignedWrap())) return replaceInstUsesWith(I, Res); @@ -2631,6 +2631,18 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { /* IsNUW */ false)) return replaceInstUsesWith(I, Res); + if (match(Op0, m_ZExt(m_PtrToInt(m_Value(LHSOp)))) && + match(Op1, m_PtrToInt(m_Value(RHSOp))) && isa(RHSOp)) { + Value *Offset; + if (match(LHSOp, m_GEP(m_Specific(RHSOp), m_Value(Offset)))) { + auto *GEP = cast(LHSOp); + if (GEP->isInBounds()) { + Value *Res = Builder.CreateZExt(EmitGEPOffset(GEP), I.getType()); + return replaceInstUsesWith(I, Res); + } + } + } + // Canonicalize a shifty way to code absolute value to the common pattern. // There are 2 potential commuted variants. // We're relying on the fact that we only do this transform when the shift has diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index ee18fd607823a..e07539f4d20f3 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=instcombine < %s | FileCheck %s -target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-p2:32:32" define i64 @test_inbounds(ptr %base, i64 %idx) { ; CHECK-LABEL: @test_inbounds( @@ -271,7 +271,7 @@ define i64 @test25(ptr %P, i64 %A){ } define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { -; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint( +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint( ; CHECK-NEXT: %1 = sext i32 %offset to i64 ; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 ; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 @@ -286,7 +286,7 @@ define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { } define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) { -; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint( +; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint( ; CHECK-NEXT: %1 = sext i32 %offset to i64 ; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 ; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 @@ -315,29 +315,30 @@ define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { ret i16 %G } -define i64 @zext_ptrtoint_sub_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) { -; CHECK-LABLE: @zext_ptrtoint_sub_ptrtoint_as1( -; CHECK-NEXT: %1 = trunc i32 %offset to i16 -; CHECK-NEXT: %A.idx = shl i16 %1, 1 -; CHECK-NEXT: %D = sext i16 %A.idx to i64 +@Arr_as2 = external addrspace(2) global [42 x i16] +define i64 @zext_ptrtoint_sub_ptrtoint_as2(ptr addrspace(1) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2( +; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 +; CHECK-NEXT: %D = zext i32 %A.idx to i64 ; CHECK-NEXT: ret i64 %D - %A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset - %B = ptrtoint ptr addrspace(1) %A to i32 + %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 - %D = sub i64 %C, ptrtoint (ptr addrspace(1) @Arr_as1 to i64) + %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) ret i64 %D } -define i64 @ptrtoint_sub_zext_ptrtoint_as1(ptr addrspace(1) %p, i32 %offset) { -; CHECK-LABLE: @ptrtoint_sub_zext_ptrtoint_as1( -; CHECK-NEXT: %1 = trunc i32 %offset to i16 -; CHECK-NEXT: %A.idx.neg = mul i16 %1, -2 -; CHECK-NEXT: %D = sext i16 %A.idx.neg to i64 +define i64 @ptrtoint_sub_zext_ptrtoint_as2(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2( +; CHECK-NEXT: %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset +; CHECK-NEXT: %B = ptrtoint ptr addrspace(2) %A to i32 +; CHECK-NEXT: %C = zext i32 %B to i64 +; CHECK-NEXT: %D = sub nsw i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C ; CHECK-NEXT: ret i64 %D - %A = getelementptr bfloat, ptr addrspace(1) @Arr_as1, i32 %offset - %B = ptrtoint ptr addrspace(1) %A to i32 + %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 - %D = sub i64 ptrtoint (ptr addrspace(1) @Arr_as1 to i64), %C + %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C ret i64 %D } From a2b3e0358f21c0dc97703023930bcb4dfc8aafd7 Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Wed, 13 Nov 2024 18:15:01 -0500 Subject: [PATCH 3/6] Addressed comments --- .../InstCombine/InstCombineAddSub.cpp | 17 ++++--- llvm/test/Transforms/InstCombine/sub-gep.ll | 44 +++++++++++++++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 4f14b1eb57785..40172bf2cd1eb 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2632,13 +2632,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { return replaceInstUsesWith(I, Res); if (match(Op0, m_ZExt(m_PtrToInt(m_Value(LHSOp)))) && - match(Op1, m_PtrToInt(m_Value(RHSOp))) && isa(RHSOp)) { - Value *Offset; - if (match(LHSOp, m_GEP(m_Specific(RHSOp), m_Value(Offset)))) { - auto *GEP = cast(LHSOp); - if (GEP->isInBounds()) { - Value *Res = Builder.CreateZExt(EmitGEPOffset(GEP), I.getType()); - return replaceInstUsesWith(I, Res); + match(Op1, m_ZExtOrSelf(m_PtrToInt(m_Value(RHSOp))))) { + if (auto *GEP = dyn_cast(LHSOp)) { + if (GEP->getPointerOperand() == RHSOp) { + if (GEP->hasNoUnsignedWrap() || GEP->hasNoUnsignedSignedWrap()) { + Value *Offset = EmitGEPOffset(GEP); + Value *Res = GEP->hasNoUnsignedWrap() + ? Builder.CreateZExt(Offset, I.getType()) + : Builder.CreateSExt(Offset, I.getType()); + return replaceInstUsesWith(I, Res); + } } } } diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index e07539f4d20f3..3a566b4193116 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -316,19 +316,57 @@ define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { } @Arr_as2 = external addrspace(2) global [42 x i16] -define i64 @zext_ptrtoint_sub_ptrtoint_as2(ptr addrspace(1) %p, i32 %offset) { +define i64 @zext_ptrtoint_sub_ptrtoint_as2(i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2( ; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 +; CHECK-NEXT: %D = sext i32 %A.idx to i64 +; CHECK-NEXT: ret i64 %D + %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw( +; CHECK-NEXT: %A.idx = shl nuw i32 %offset, 1 ; CHECK-NEXT: %D = zext i32 %A.idx to i64 ; CHECK-NEXT: ret i64 %D - %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) ret i64 %D } -define i64 @ptrtoint_sub_zext_ptrtoint_as2(ptr addrspace(2) %p, i32 %offset) { +define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2( +; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 +; CHECK-NEXT: %E = sext i32 %A.idx to i64 +; CHECK-NEXT: ret i64 %E + %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64 + %E = sub i64 %C, %D + ret i64 %E +} + +define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw( +; CHECK-NEXT: %A.idx = shl nuw i32 %offset, 1 +; CHECK-NEXT: %E = zext i32 %A.idx to i64 +; CHECK-NEXT: ret i64 %E + %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %D = zext i32 ptrtoint (ptr addrspace(2) @Arr_as2 to i32) to i64 + %E = sub i64 %C, %D + ret i64 %E +} + +define i64 @ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2( ; CHECK-NEXT: %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset ; CHECK-NEXT: %B = ptrtoint ptr addrspace(2) %A to i32 From fa83e47d6ab7138b37f708ea948baeba3c18cbed Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Wed, 13 Nov 2024 21:45:01 -0500 Subject: [PATCH 4/6] Addressed comments --- .../InstCombine/InstCombineAddSub.cpp | 6 +++-- llvm/test/Transforms/InstCombine/sub-gep.ll | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 40172bf2cd1eb..fe5e478ef371d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2631,14 +2631,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) { /* IsNUW */ false)) return replaceInstUsesWith(I, Res); - if (match(Op0, m_ZExt(m_PtrToInt(m_Value(LHSOp)))) && + if (match(Op0, m_ZExt(m_PtrToIntSameSize(DL, m_Value(LHSOp)))) && match(Op1, m_ZExtOrSelf(m_PtrToInt(m_Value(RHSOp))))) { if (auto *GEP = dyn_cast(LHSOp)) { if (GEP->getPointerOperand() == RHSOp) { if (GEP->hasNoUnsignedWrap() || GEP->hasNoUnsignedSignedWrap()) { Value *Offset = EmitGEPOffset(GEP); Value *Res = GEP->hasNoUnsignedWrap() - ? Builder.CreateZExt(Offset, I.getType()) + ? Builder.CreateZExt( + Offset, I.getType(), "", + /*IsNonNeg=*/GEP->hasNoUnsignedSignedWrap()) : Builder.CreateSExt(Offset, I.getType()); return replaceInstUsesWith(I, Res); } diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index 3a566b4193116..e6ea0867d7c5e 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -340,6 +340,18 @@ define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { ret i64 %D } +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw( +; CHECK-NEXT: %A.idx = shl nuw nsw i32 %offset, 1 +; CHECK-NEXT: %D = zext nneg i32 %A.idx to i64 +; CHECK-NEXT: ret i64 %D + %A = getelementptr nusw nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) + ret i64 %D +} + define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2( ; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 @@ -366,6 +378,21 @@ define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) { ret i64 %E } +define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { + ; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw( + ; CHECK-NEXT: %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + ; CHECK-NEXT: %1 = ptrtoint ptr addrspace(2) %A to i32 + ; CHECK-NEXT: %B.mask = and i32 %1, 65534 + ; CHECK-NEXT: %C = zext nneg i32 %B.mask to i64 + ; CHECK-NEXT: %D = sub nsw i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) + ; CHECK-NEXT: ret i64 %D + %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i16 + %C = zext i16 %B to i64 + %D = sub i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) + ret i64 %D +} + define i64 @ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2( ; CHECK-NEXT: %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset From 11090abde0c3dda63f697cb3b62e3e6d588473fa Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Thu, 14 Nov 2024 17:04:43 -0500 Subject: [PATCH 5/6] Updated test --- llvm/test/Transforms/InstCombine/sub-gep.ll | 146 +++++++++++++------- 1 file changed, 94 insertions(+), 52 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index e6ea0867d7c5e..d711f59ff505e 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -272,12 +272,13 @@ define i64 @test25(ptr %P, i64 %A){ define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint( -; CHECK-NEXT: %1 = sext i32 %offset to i64 -; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 -; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 -; CHECK-NEXT: %C = and i64 %2, 4294967294 -; CHECK-NEXT: %D = sub i64 %C, ptrtoint (ptr @Arr to i64) -; CHECK-NEXT: ret i64 %D +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64 +; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294 +; CHECK-NEXT: [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64) +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr bfloat, ptr @Arr, i32 %offset %B = ptrtoint ptr %A to i32 %C = zext i32 %B to i64 @@ -287,12 +288,13 @@ define i64 @zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) { ; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint( -; CHECK-NEXT: %1 = sext i32 %offset to i64 -; CHECK-NEXT: %A = getelementptr bfloat, ptr @Arr, i64 %1 -; CHECK-NEXT: %2 = ptrtoint ptr %A to i64 -; CHECK-NEXT: %C = and i64 %2, 4294967294 -; CHECK-NEXT: %D = sub i64 ptrtoint (ptr @Arr to i64), %C -; CHECK-NEXT: ret i64 %D +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64 +; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 4294967294 +; CHECK-NEXT: [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]] +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr bfloat, ptr @Arr, i32 %offset %B = ptrtoint ptr %A to i32 %C = zext i32 %B to i64 @@ -300,6 +302,38 @@ define i64 @ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) { ret i64 %D } +define i64 @negative_zext_ptrtoint_sub_ptrtoint(ptr %p, i32 %offset) { +; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint( +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64 +; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534 +; CHECK-NEXT: [[D:%.*]] = sub i64 [[C]], ptrtoint (ptr @Arr to i64) +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr bfloat, ptr @Arr, i32 %offset + %B = ptrtoint ptr %A to i16 + %C = zext i16 %B to i64 + %D = sub i64 %C, ptrtoint (ptr @Arr to i64) + ret i64 %D +} + +define i64 @negative_ptrtoint_sub_zext_ptrtoint(ptr %p, i32 %offset) { +; CHECK-LABEL: @negative_ptrtoint_sub_zext_ptrtoint( +; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[OFFSET:%.*]] to i64 +; CHECK-NEXT: [[A:%.*]] = getelementptr bfloat, ptr @Arr, i64 [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[A]] to i64 +; CHECK-NEXT: [[C:%.*]] = and i64 [[TMP2]], 65534 +; CHECK-NEXT: [[D:%.*]] = sub i64 ptrtoint (ptr @Arr to i64), [[C]] +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr bfloat, ptr @Arr, i32 %offset + %B = ptrtoint ptr %A to i16 + %C = zext i16 %B to i64 + %D = sub i64 ptrtoint (ptr @Arr to i64), %C + ret i64 %D +} + @Arr_as1 = external addrspace(1) global [42 x i16] define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { @@ -316,11 +350,28 @@ define i16 @test25_as1(ptr addrspace(1) %P, i64 %A) { } @Arr_as2 = external addrspace(2) global [42 x i16] -define i64 @zext_ptrtoint_sub_ptrtoint_as2(i32 %offset) { -; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2( -; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 -; CHECK-NEXT: %D = sext i32 %A.idx to i64 -; CHECK-NEXT: ret i64 %D + +define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds(i32 %offset) { +; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds( +; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]] +; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 +; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64 +; CHECK-NEXT: [[D:%.*]] = sub nsw i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), [[C]] +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 @@ -330,9 +381,10 @@ define i64 @zext_ptrtoint_sub_ptrtoint_as2(i32 %offset) { define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw( -; CHECK-NEXT: %A.idx = shl nuw i32 %offset, 1 -; CHECK-NEXT: %D = zext i32 %A.idx to i64 -; CHECK-NEXT: ret i64 %D +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 @@ -342,9 +394,10 @@ define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw( -; CHECK-NEXT: %A.idx = shl nuw nsw i32 %offset, 1 -; CHECK-NEXT: %D = zext nneg i32 %A.idx to i64 -; CHECK-NEXT: ret i64 %D +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr nusw nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 @@ -352,11 +405,12 @@ define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw(i32 %offset) { ret i64 %D } -define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { -; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2( -; CHECK-NEXT: %A.idx = shl nsw i32 %offset, 1 -; CHECK-NEXT: %E = sext i32 %A.idx to i64 -; CHECK-NEXT: ret i64 %E +define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw(i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[E]] +; %A = getelementptr nusw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 @@ -367,9 +421,10 @@ define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) { ; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw( -; CHECK-NEXT: %A.idx = shl nuw i32 %offset, 1 -; CHECK-NEXT: %E = zext i32 %A.idx to i64 -; CHECK-NEXT: ret i64 %E +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[E]] +; %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i32 %C = zext i32 %B to i64 @@ -379,13 +434,14 @@ define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw(i32 %offset) { } define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { - ; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw( - ; CHECK-NEXT: %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset - ; CHECK-NEXT: %1 = ptrtoint ptr addrspace(2) %A to i32 - ; CHECK-NEXT: %B.mask = and i32 %1, 65534 - ; CHECK-NEXT: %C = zext nneg i32 %B.mask to i64 - ; CHECK-NEXT: %D = sub nsw i64 %C, ptrtoint (ptr addrspace(2) @Arr_as2 to i64) - ; CHECK-NEXT: ret i64 %D +; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw( +; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 [[OFFSET:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 +; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65534 +; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64 +; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[C]], ptrtoint (ptr addrspace(2) @Arr_as2 to i64) +; CHECK-NEXT: ret i64 [[D]] +; %A = getelementptr nuw bfloat, ptr addrspace(2) @Arr_as2, i32 %offset %B = ptrtoint ptr addrspace(2) %A to i16 %C = zext i16 %B to i64 @@ -393,20 +449,6 @@ define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { ret i64 %D } -define i64 @ptrtoint_sub_zext_ptrtoint_as2(i32 %offset) { -; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2( -; CHECK-NEXT: %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset -; CHECK-NEXT: %B = ptrtoint ptr addrspace(2) %A to i32 -; CHECK-NEXT: %C = zext i32 %B to i64 -; CHECK-NEXT: %D = sub nsw i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C -; CHECK-NEXT: ret i64 %D - %A = getelementptr inbounds bfloat, ptr addrspace(2) @Arr_as2, i32 %offset - %B = ptrtoint ptr addrspace(2) %A to i32 - %C = zext i32 %B to i64 - %D = sub i64 ptrtoint (ptr addrspace(2) @Arr_as2 to i64), %C - ret i64 %D -} - define i64 @test30(ptr %foo, i64 %i, i64 %j) { ; CHECK-LABEL: @test30( ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2 From 987bfd9a3f37959d60a04ee1fd636a3946f657b4 Mon Sep 17 00:00:00 2001 From: Kolya Panchenko Date: Thu, 14 Nov 2024 20:11:16 -0500 Subject: [PATCH 6/6] Added identical test that use non-global ptr --- llvm/test/Transforms/InstCombine/sub-gep.ll | 109 ++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll index d711f59ff505e..f7a54ab2141bd 100644 --- a/llvm/test/Transforms/InstCombine/sub-gep.ll +++ b/llvm/test/Transforms/InstCombine/sub-gep.ll @@ -449,6 +449,115 @@ define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw(i32 %offset) { ret i64 %D } +define i64 @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @ptrtoint_sub_zext_ptrtoint_as2_inbounds_local( +; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]] +; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 +; CHECK-NEXT: [[C:%.*]] = zext i32 [[B]] to i64 +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32 +; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP1]] to i64 +; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[CC]], [[C]] +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr inbounds bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i64 + %D = sub i64 %CC, %C + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_local( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = sext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i64 + %D = sub i64 %C, %CC + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nuw_local( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = zext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i64 + %D = sub i64 %C, %CC + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_ptrtoint_as2_nusw_nuw_local( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[D:%.*]] = zext nneg i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr nusw nuw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i64 + %D = sub i64 %C, %CC + ret i64 %D +} + +define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nusw_local( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[E:%.*]] = sext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[E]] +; + %A = getelementptr nusw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i32 + %D = zext i32 %CC to i64 + %E = sub i64 %C, %D + ret i64 %E +} + +define i64 @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @zext_ptrtoint_sub_zext_ptrtoint_as2_nuw_local( +; CHECK-NEXT: [[A_IDX:%.*]] = shl nuw i32 [[OFFSET:%.*]], 1 +; CHECK-NEXT: [[E:%.*]] = zext i32 [[A_IDX]] to i64 +; CHECK-NEXT: ret i64 [[E]] +; + %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i32 + %C = zext i32 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i32 + %D = zext i32 %CC to i64 + %E = sub i64 %C, %D + ret i64 %E +} + +define i64 @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local(ptr addrspace(2) %p, i32 %offset) { +; CHECK-LABEL: @negative_zext_ptrtoint_sub_ptrtoint_as2_nuw_local( +; CHECK-NEXT: [[A:%.*]] = getelementptr nuw bfloat, ptr addrspace(2) [[P:%.*]], i32 [[OFFSET:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[A]] to i32 +; CHECK-NEXT: [[B_MASK:%.*]] = and i32 [[TMP1]], 65535 +; CHECK-NEXT: [[C:%.*]] = zext nneg i32 [[B_MASK]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr addrspace(2) [[P]] to i32 +; CHECK-NEXT: [[CC:%.*]] = zext i32 [[TMP2]] to i64 +; CHECK-NEXT: [[D:%.*]] = sub nsw i64 [[C]], [[CC]] +; CHECK-NEXT: ret i64 [[D]] +; + %A = getelementptr nuw bfloat, ptr addrspace(2) %p, i32 %offset + %B = ptrtoint ptr addrspace(2) %A to i16 + %C = zext i16 %B to i64 + %CC = ptrtoint ptr addrspace(2) %p to i64 + %D = sub i64 %C, %CC + ret i64 %D +} + define i64 @test30(ptr %foo, i64 %i, i64 %j) { ; CHECK-LABEL: @test30( ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2