Skip to content

Commit fb31f08

Browse files
committed
[InstCombine] Split GEPs with multiple variable indices
Split GEPs that have more than one variable index into two. This is in preparation for the ptradd migration, which will not support multi-index GEPs.
1 parent 3264290 commit fb31f08

File tree

9 files changed

+120
-61
lines changed

9 files changed

+120
-61
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,6 +2570,12 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
25702570
Indices.append(GEP.idx_begin()+1, GEP.idx_end());
25712571
}
25722572

2573+
// Don't create GEPs with more than one variable index.
2574+
unsigned NumVarIndices =
2575+
count_if(Indices, [](Value *Idx) { return !isa<Constant>(Idx); });
2576+
if (NumVarIndices > 1)
2577+
return nullptr;
2578+
25732579
if (!Indices.empty())
25742580
return replaceInstUsesWith(
25752581
GEP, Builder.CreateGEP(
@@ -2996,6 +3002,30 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
29963002
return replaceInstUsesWith(GEP, NewGEP);
29973003
}
29983004

3005+
bool SeenVarIndex = false;
3006+
for (auto [IdxNum, Idx] : enumerate(Indices)) {
3007+
if (isa<Constant>(Idx))
3008+
continue;
3009+
3010+
if (!SeenVarIndex) {
3011+
SeenVarIndex = true;
3012+
continue;
3013+
}
3014+
3015+
// GEP has multiple variable indices: Split it.
3016+
ArrayRef<Value *> FrontIndices = ArrayRef(Indices).take_front(IdxNum);
3017+
Value *FrontGEP =
3018+
Builder.CreateGEP(GEPEltType, PtrOp, FrontIndices,
3019+
GEP.getName() + ".split", GEP.getNoWrapFlags());
3020+
3021+
SmallVector<Value *> BackIndices;
3022+
BackIndices.push_back(Constant::getNullValue(NewScalarIndexTy));
3023+
append_range(BackIndices, drop_begin(Indices, IdxNum));
3024+
return GetElementPtrInst::Create(
3025+
GetElementPtrInst::getIndexedType(GEPEltType, FrontIndices), FrontGEP,
3026+
BackIndices, GEP.getNoWrapFlags());
3027+
}
3028+
29993029
// Check to see if the inputs to the PHI node are getelementptr instructions.
30003030
if (auto *PN = dyn_cast<PHINode>(PtrOp)) {
30013031
if (Value *NewPtrOp = foldGEPOfPhi(GEP, PN, Builder))

llvm/test/Transforms/InstCombine/canonicalize-gep-constglob.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ define ptr @xzy(i64 %x, i64 %y, i64 %z) {
3535
; CHECK-LABEL: define ptr @xzy(
3636
; CHECK-SAME: i64 [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]) {
3737
; CHECK-NEXT: entry:
38-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr getelementptr inbounds nuw (i8, ptr @glob, i64 40), i64 0, i64 [[X]], i64 [[Z]], i64 [[Y]]
38+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr getelementptr inbounds nuw (i8, ptr @glob, i64 40), i64 0, i64 [[X]]
39+
; CHECK-NEXT: [[GEP_SPLIT1:%.*]] = getelementptr inbounds [10 x [10 x i32]], ptr [[GEP_SPLIT]], i64 0, i64 [[Z]]
40+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [10 x i32], ptr [[GEP_SPLIT1]], i64 0, i64 [[Y]]
3941
; CHECK-NEXT: ret ptr [[GEP]]
4042
;
4143
entry:

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ define <2 x ptr> @vectorindex3() {
3131

3232
define ptr @bitcast_vec_to_array_gep(ptr %x, i64 %y, i64 %z) {
3333
; CHECK-LABEL: @bitcast_vec_to_array_gep(
34-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [7 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
34+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr [7 x i32], ptr [[X:%.*]], i64 [[Y:%.*]]
35+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [7 x i32], ptr [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
3536
; CHECK-NEXT: ret ptr [[GEP]]
3637
;
3738
%gep = getelementptr [7 x i32], ptr %x, i64 %y, i64 %z
@@ -42,7 +43,8 @@ define ptr @bitcast_vec_to_array_gep(ptr %x, i64 %y, i64 %z) {
4243

4344
define ptr @bitcast_array_to_vec_gep(ptr %x, i64 %y, i64 %z) {
4445
; CHECK-LABEL: @bitcast_array_to_vec_gep(
45-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds <3 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
46+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr inbounds <3 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]]
47+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds <3 x i32>, ptr [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
4648
; CHECK-NEXT: ret ptr [[GEP]]
4749
;
4850
%gep = getelementptr inbounds <3 x i32>, ptr %x, i64 %y, i64 %z
@@ -53,7 +55,8 @@ define ptr @bitcast_array_to_vec_gep(ptr %x, i64 %y, i64 %z) {
5355

5456
define ptr @bitcast_vec_to_array_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
5557
; CHECK-LABEL: @bitcast_vec_to_array_gep_matching_alloc_size(
56-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
58+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr [4 x i32], ptr [[X:%.*]], i64 [[Y:%.*]]
59+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i32], ptr [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
5760
; CHECK-NEXT: ret ptr [[GEP]]
5861
;
5962
%gep = getelementptr [4 x i32], ptr %x, i64 %y, i64 %z
@@ -64,7 +67,8 @@ define ptr @bitcast_vec_to_array_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z)
6467

6568
define ptr @bitcast_array_to_vec_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
6669
; CHECK-LABEL: @bitcast_array_to_vec_gep_matching_alloc_size(
67-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds <4 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
70+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr inbounds <4 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]]
71+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds <4 x i32>, ptr [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
6872
; CHECK-NEXT: ret ptr [[GEP]]
6973
;
7074
%gep = getelementptr inbounds <4 x i32>, ptr %x, i64 %y, i64 %z
@@ -76,7 +80,8 @@ define ptr @bitcast_array_to_vec_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z)
7680
define ptr addrspace(3) @bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
7781
; CHECK-LABEL: @bitcast_vec_to_array_addrspace(
7882
; CHECK-NEXT: [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
79-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
83+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]]
84+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [7 x i32], ptr addrspace(3) [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
8085
; CHECK-NEXT: ret ptr addrspace(3) [[GEP]]
8186
;
8287
%asc = addrspacecast ptr %x to ptr addrspace(3)
@@ -89,7 +94,8 @@ define ptr addrspace(3) @bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z)
8994
define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
9095
; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace(
9196
; CHECK-NEXT: [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
92-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
97+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr inbounds [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]]
98+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [7 x i32], ptr addrspace(3) [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
9399
; CHECK-NEXT: ret ptr addrspace(3) [[GEP]]
94100
;
95101
%asc = addrspacecast ptr %x to ptr addrspace(3)
@@ -102,7 +108,8 @@ define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace(ptr %x, i64 %y,
102108
define ptr addrspace(3) @bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
103109
; CHECK-LABEL: @bitcast_vec_to_array_addrspace_matching_alloc_size(
104110
; CHECK-NEXT: [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
105-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
111+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]]
112+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i32], ptr addrspace(3) [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
106113
; CHECK-NEXT: ret ptr addrspace(3) [[GEP]]
107114
;
108115
%asc = addrspacecast ptr %x to ptr addrspace(3)
@@ -115,7 +122,8 @@ define ptr addrspace(3) @bitcast_vec_to_array_addrspace_matching_alloc_size(ptr
115122
define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
116123
; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(
117124
; CHECK-NEXT: [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
118-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
125+
; CHECK-NEXT: [[GEP_SPLIT:%.*]] = getelementptr inbounds [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]]
126+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr addrspace(3) [[GEP_SPLIT]], i64 0, i64 [[Z:%.*]]
119127
; CHECK-NEXT: ret ptr addrspace(3) [[GEP]]
120128
;
121129
%asc = addrspacecast ptr %x to ptr addrspace(3)

llvm/test/Transforms/InstCombine/getelementptr.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,7 +1387,7 @@ define ptr @gep_of_gep_multiuse_var_and_var(ptr %p, i64 %idx, i64 %idx2) {
13871387
; CHECK-LABEL: @gep_of_gep_multiuse_var_and_var(
13881388
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr [4 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]
13891389
; CHECK-NEXT: call void @use(ptr [[GEP1]])
1390-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr [4 x i32], ptr [[P]], i64 [[IDX]], i64 [[IDX2:%.*]]
1390+
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr [4 x i32], ptr [[GEP1]], i64 0, i64 [[IDX2:%.*]]
13911391
; CHECK-NEXT: ret ptr [[GEP2]]
13921392
;
13931393
%gep1 = getelementptr [4 x i32], ptr %p, i64 %idx
@@ -1929,8 +1929,9 @@ define ptr @gep_merge_nusw(ptr %p, i64 %x, i64 %y) {
19291929

19301930
define ptr @gep_merge_nuw_add_zero(ptr %p, i64 %idx, i64 %idx2) {
19311931
; CHECK-LABEL: @gep_merge_nuw_add_zero(
1932-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 [[IDX2:%.*]]
1933-
; CHECK-NEXT: ret ptr [[GEP]]
1932+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nuw [2 x i32], ptr [[GEP_SPLIT:%.*]], i64 [[IDX2:%.*]]
1933+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw [2 x i32], ptr [[GEP]], i64 0, i64 [[IDX3:%.*]]
1934+
; CHECK-NEXT: ret ptr [[GEP1]]
19341935
;
19351936
%gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx
19361937
%gep = getelementptr nuw [2 x i32], ptr %gep1, i64 0, i64 %idx2
@@ -1942,7 +1943,8 @@ define ptr @gep_merge_nuw_add_zero(ptr %p, i64 %idx, i64 %idx2) {
19421943
; after the merge.
19431944
define ptr @gep_merge_nusw_add_zero(ptr %p, i64 %idx, i64 %idx2) {
19441945
; CHECK-LABEL: @gep_merge_nusw_add_zero(
1945-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 [[IDX2:%.*]]
1946+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nusw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]
1947+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw [2 x i32], ptr [[GEP1]], i64 0, i64 [[IDX2:%.*]]
19461948
; CHECK-NEXT: ret ptr [[GEP]]
19471949
;
19481950
%gep1 = getelementptr nusw [2 x i32], ptr %p, i64 %idx

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -658,13 +658,11 @@ define i1 @test_scalable_ij(ptr %foo, i64 %i, i64 %j) {
658658

659659
define i1 @gep_nuw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
660660
; CHECK-LABEL: @gep_nuw(
661-
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[A:%.*]], 2
662-
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = shl nuw i64 [[B:%.*]], 1
663-
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP1_IDX1]]
664-
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[C:%.*]], 3
665-
; CHECK-NEXT: [[GEP2_IDX2:%.*]] = shl nuw i64 [[D:%.*]], 2
666-
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nuw i64 [[GEP2_IDX]], [[GEP2_IDX2]]
667-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
661+
; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr nuw [2 x i16], ptr [[P:%.*]], i64 [[A:%.*]]
662+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw [2 x i16], ptr [[GEP1_SPLIT]], i64 0, i64 [[B:%.*]]
663+
; CHECK-NEXT: [[GEP2_SPLIT:%.*]] = getelementptr nuw [2 x i32], ptr [[P]], i64 [[C:%.*]]
664+
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw [2 x i32], ptr [[GEP2_SPLIT]], i64 0, i64 [[D:%.*]]
665+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP1]], [[GEP2]]
668666
; CHECK-NEXT: ret i1 [[CMP]]
669667
;
670668
%gep1 = getelementptr nuw [2 x i16], ptr %p, i64 %a, i64 %b
@@ -675,13 +673,11 @@ define i1 @gep_nuw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
675673

676674
define i1 @gep_nusw(ptr %p, i64 %a, i64 %b, i64 %c, i64 %d) {
677675
; CHECK-LABEL: @gep_nusw(
678-
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[A:%.*]], 2
679-
; CHECK-NEXT: [[GEP1_IDX1:%.*]] = shl nsw i64 [[B:%.*]], 1
680-
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[GEP1_IDX]], [[GEP1_IDX1]]
681-
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[C:%.*]], 3
682-
; CHECK-NEXT: [[GEP2_IDX2:%.*]] = shl nsw i64 [[D:%.*]], 2
683-
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[GEP2_IDX]], [[GEP2_IDX2]]
684-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_OFFS]], [[GEP2_OFFS]]
676+
; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr nusw [2 x i16], ptr [[P:%.*]], i64 [[A:%.*]]
677+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nusw [2 x i16], ptr [[GEP1_SPLIT]], i64 0, i64 [[B:%.*]]
678+
; CHECK-NEXT: [[GEP2_SPLIT:%.*]] = getelementptr nusw [2 x i32], ptr [[P]], i64 [[C:%.*]]
679+
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw [2 x i32], ptr [[GEP2_SPLIT]], i64 0, i64 [[D:%.*]]
680+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP1]], [[GEP2]]
685681
; CHECK-NEXT: ret i1 [[CMP]]
686682
;
687683
%gep1 = getelementptr nusw [2 x i16], ptr %p, i64 %a, i64 %b

llvm/test/Transforms/InstCombine/loadstore-alignment.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ define <2 x i64> @hem_2d(i32 %i, i32 %j) {
3333
; CHECK-LABEL: @hem_2d(
3434
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[I:%.*]] to i64
3535
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[J:%.*]] to i64
36-
; CHECK-NEXT: [[T:%.*]] = getelementptr [13 x <2 x i64>], ptr @xx, i64 [[TMP1]], i64 [[TMP2]]
36+
; CHECK-NEXT: [[T_SPLIT:%.*]] = getelementptr [13 x <2 x i64>], ptr @xx, i64 [[TMP1]]
37+
; CHECK-NEXT: [[T:%.*]] = getelementptr [13 x <2 x i64>], ptr [[T_SPLIT]], i64 0, i64 [[TMP2]]
3738
; CHECK-NEXT: [[L:%.*]] = load <2 x i64>, ptr [[T]], align 1
3839
; CHECK-NEXT: ret <2 x i64> [[L]]
3940
;
@@ -90,7 +91,8 @@ define void @hem_2d_store(i32 %i, i32 %j, <2 x i64> %y) {
9091
; CHECK-LABEL: @hem_2d_store(
9192
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[I:%.*]] to i64
9293
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[J:%.*]] to i64
93-
; CHECK-NEXT: [[T:%.*]] = getelementptr [13 x <2 x i64>], ptr @xx, i64 [[TMP1]], i64 [[TMP2]]
94+
; CHECK-NEXT: [[T_SPLIT:%.*]] = getelementptr [13 x <2 x i64>], ptr @xx, i64 [[TMP1]]
95+
; CHECK-NEXT: [[T:%.*]] = getelementptr [13 x <2 x i64>], ptr [[T_SPLIT]], i64 0, i64 [[TMP2]]
9496
; CHECK-NEXT: store <2 x i64> [[Y:%.*]], ptr [[T]], align 1
9597
; CHECK-NEXT: ret void
9698
;

llvm/test/Transforms/InstCombine/pr58901.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ define ptr @f1(ptr %arg, i64 %arg1) {
1515
define ptr @f2(ptr %arg, i64 %arg1) {
1616
; CHECK-LABEL: @f2(
1717
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[ARG:%.*]], i64 72
18-
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [6 x i32], ptr [[TMP1]], i64 [[ARG1:%.*]], i64 [[ARG1]]
18+
; CHECK-NEXT: [[DOTSPLIT:%.*]] = getelementptr [6 x i32], ptr [[TMP1]], i64 [[ARG1:%.*]]
19+
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [6 x i32], ptr [[DOTSPLIT]], i64 0, i64 [[ARG1]]
1920
; CHECK-NEXT: ret ptr [[TMP2]]
2021
;
2122
%1 = getelementptr [6 x i32], ptr %arg, i64 3

llvm/test/Transforms/InstCombine/ptrtoint-nullgep.ll

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,10 @@ define i64 @fold_ptrtoint_nested_array_two_vars(i64 %x, i64 %y) {
548548
;
549549
; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars
550550
; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
551-
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[X]], 2
552-
; INSTCOMBINE-NEXT: [[PTR_IDX1:%.*]] = shl i64 [[Y]], 1
553-
; INSTCOMBINE-NEXT: [[PTR_OFFS:%.*]] = add i64 [[PTR_IDX]], [[PTR_IDX1]]
554-
; INSTCOMBINE-NEXT: ret i64 [[PTR_OFFS]]
551+
; INSTCOMBINE-NEXT: [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 2
552+
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[Y]], 1
553+
; INSTCOMBINE-NEXT: [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_IDX]]
554+
; INSTCOMBINE-NEXT: ret i64 [[RET]]
555555
;
556556

557557
%ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 %x, i64 %y
@@ -574,10 +574,10 @@ define i64 @fold_ptrtoint_nested_array_two_vars_plus_zero(i64 %x, i64 %y) {
574574
;
575575
; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_zero
576576
; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
577-
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[X]], 3
578-
; INSTCOMBINE-NEXT: [[PTR_IDX1:%.*]] = shl i64 [[Y]], 2
579-
; INSTCOMBINE-NEXT: [[PTR_OFFS:%.*]] = add i64 [[PTR_IDX]], [[PTR_IDX1]]
580-
; INSTCOMBINE-NEXT: ret i64 [[PTR_OFFS]]
577+
; INSTCOMBINE-NEXT: [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 3
578+
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[Y]], 2
579+
; INSTCOMBINE-NEXT: [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_IDX]]
580+
; INSTCOMBINE-NEXT: ret i64 [[RET]]
581581
;
582582
%ptr = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 %x, i64 %y, i64 0
583583
%ret = ptrtoint ptr addrspace(1) %ptr to i64
@@ -599,11 +599,11 @@ define i64 @fold_ptrtoint_nested_array_two_vars_plus_const(i64 %x, i64 %y) {
599599
;
600600
; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_array_two_vars_plus_const
601601
; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
602-
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[X]], 3
603-
; INSTCOMBINE-NEXT: [[PTR_IDX1:%.*]] = shl i64 [[Y]], 2
604-
; INSTCOMBINE-NEXT: [[PTR_OFFS:%.*]] = add i64 [[PTR_IDX]], [[PTR_IDX1]]
605-
; INSTCOMBINE-NEXT: [[PTR_OFFS2:%.*]] = or disjoint i64 [[PTR_OFFS]], 2
606-
; INSTCOMBINE-NEXT: ret i64 [[PTR_OFFS2]]
602+
; INSTCOMBINE-NEXT: [[PTR_SPLIT_IDX:%.*]] = shl i64 [[X]], 3
603+
; INSTCOMBINE-NEXT: [[PTR_IDX:%.*]] = shl i64 [[Y]], 2
604+
; INSTCOMBINE-NEXT: [[PTR_OFFS:%.*]] = or disjoint i64 [[PTR_IDX]], 2
605+
; INSTCOMBINE-NEXT: [[RET:%.*]] = add i64 [[PTR_SPLIT_IDX]], [[PTR_OFFS]]
606+
; INSTCOMBINE-NEXT: ret i64 [[RET]]
607607
;
608608
%ptr = getelementptr [2 x [2 x i16]], ptr addrspace(1) null, i64 %x, i64 %y, i64 1
609609
%ret = ptrtoint ptr addrspace(1) %ptr to i64
@@ -612,12 +612,27 @@ define i64 @fold_ptrtoint_nested_array_two_vars_plus_const(i64 %x, i64 %y) {
612612

613613
; Negative test -- should not be folded since there are multiple GEP uses
614614
define i64 @fold_ptrtoint_nested_nullgep_array_variable_multiple_uses(i64 %x, i64 %y) {
615-
; ALL-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses
616-
; ALL-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
617-
; ALL-NEXT: [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]
618-
; ALL-NEXT: call void @use_ptr(ptr addrspace(1) [[PTR]])
619-
; ALL-NEXT: [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
620-
; ALL-NEXT: ret i64 [[RET]]
615+
; LLPARSER-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses
616+
; LLPARSER-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
617+
; LLPARSER-NEXT: [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]
618+
; LLPARSER-NEXT: call void @use_ptr(ptr addrspace(1) [[PTR]])
619+
; LLPARSER-NEXT: [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
620+
; LLPARSER-NEXT: ret i64 [[RET]]
621+
;
622+
; INSTSIMPLIFY-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses
623+
; INSTSIMPLIFY-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
624+
; INSTSIMPLIFY-NEXT: [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]], i64 [[Y]]
625+
; INSTSIMPLIFY-NEXT: call void @use_ptr(ptr addrspace(1) [[PTR]])
626+
; INSTSIMPLIFY-NEXT: [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
627+
; INSTSIMPLIFY-NEXT: ret i64 [[RET]]
628+
;
629+
; INSTCOMBINE-LABEL: define {{[^@]+}}@fold_ptrtoint_nested_nullgep_array_variable_multiple_uses
630+
; INSTCOMBINE-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
631+
; INSTCOMBINE-NEXT: [[PTR_SPLIT:%.*]] = getelementptr [2 x i16], ptr addrspace(1) null, i64 [[X]]
632+
; INSTCOMBINE-NEXT: [[PTR:%.*]] = getelementptr [2 x i16], ptr addrspace(1) [[PTR_SPLIT]], i64 0, i64 [[Y]]
633+
; INSTCOMBINE-NEXT: call void @use_ptr(ptr addrspace(1) [[PTR]])
634+
; INSTCOMBINE-NEXT: [[RET:%.*]] = ptrtoint ptr addrspace(1) [[PTR]] to i64
635+
; INSTCOMBINE-NEXT: ret i64 [[RET]]
621636
;
622637
%ptr = getelementptr [2 x i16], ptr addrspace(1) null, i64 %x, i64 %y
623638
call void @use_ptr(ptr addrspace(1) %ptr)

0 commit comments

Comments
 (0)