Skip to content

Commit 53137c4

Browse files
committed
[SeparateConstOffsetFromGEP] Support GEP reordering for different types (llvm#90802)
This doesn't show up in existing lit tests, but has an impact on real code -- especially after the canonicalization of GEPs to i8. Alive2 tests for the inbounds handling: Case 1: https://alive2.llvm.org/ce/z/6bfFY3 Case 2: https://alive2.llvm.org/ce/z/DkLMLF Change-Id: I7584e86959b2ebebc23d4b0576bcdd1251f41375
1 parent 30f27f0 commit 53137c4

File tree

5 files changed

+629
-208
lines changed

5 files changed

+629
-208
lines changed

llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -977,22 +977,13 @@ SeparateConstOffsetFromGEP::lowerToArithmetics(GetElementPtrInst *Variadic,
977977

978978
bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *GEP,
979979
TargetTransformInfo &TTI) {
980-
Type *GEPType = GEP->getResultElementType();
981-
// TODO: support reordering for non-trivial GEP chains
982-
if (GEPType->isAggregateType() || GEP->getNumIndices() != 1)
980+
if (GEP->getNumIndices() != 1)
983981
return false;
984982

985983
auto PtrGEP = dyn_cast<GetElementPtrInst>(GEP->getPointerOperand());
986984
if (!PtrGEP)
987985
return false;
988-
Type *PtrGEPType = PtrGEP->getResultElementType();
989-
// TODO: support reordering for non-trivial GEP chains
990-
if (PtrGEPType->isAggregateType() || PtrGEP->getNumIndices() != 1)
991-
return false;
992-
993-
// TODO: support reordering for non-trivial GEP chains
994-
if (PtrGEPType != GEPType ||
995-
PtrGEP->getSourceElementType() != GEP->getSourceElementType())
986+
if (PtrGEP->getNumIndices() != 1)
996987
return false;
997988

998989
bool NestedNeedsExtraction;
@@ -1007,8 +998,6 @@ bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *GEP,
1007998
/*HasBaseReg=*/true, /*Scale=*/0, AddrSpace))
1008999
return false;
10091000

1010-
IRBuilder<> Builder(GEP);
1011-
Builder.SetCurrentDebugLocation(GEP->getDebugLoc());
10121001
bool GEPInBounds = GEP->isInBounds();
10131002
bool PtrGEPInBounds = PtrGEP->isInBounds();
10141003
bool IsChainInBounds = GEPInBounds && PtrGEPInBounds;
@@ -1023,13 +1012,14 @@ bool SeparateConstOffsetFromGEP::reorderGEP(GetElementPtrInst *GEP,
10231012
}
10241013
}
10251014

1015+
IRBuilder<> Builder(GEP);
10261016
// For trivial GEP chains, we can swap the indicies.
1027-
auto NewSrc = Builder.CreateGEP(PtrGEPType, PtrGEP->getPointerOperand(),
1028-
SmallVector<Value *, 4>(GEP->indices()));
1029-
cast<GetElementPtrInst>(NewSrc)->setIsInBounds(IsChainInBounds);
1030-
auto NewGEP = Builder.CreateGEP(GEPType, NewSrc,
1031-
SmallVector<Value *, 4>(PtrGEP->indices()));
1032-
cast<GetElementPtrInst>(NewGEP)->setIsInBounds(IsChainInBounds);
1017+
Value *NewSrc = Builder.CreateGEP(
1018+
GEP->getSourceElementType(), PtrGEP->getPointerOperand(),
1019+
SmallVector<Value *, 4>(GEP->indices()), "", IsChainInBounds);
1020+
Value *NewGEP = Builder.CreateGEP(PtrGEP->getSourceElementType(), NewSrc,
1021+
SmallVector<Value *, 4>(PtrGEP->indices()),
1022+
"", IsChainInBounds);
10331023
GEP->replaceAllUsesWith(NewGEP);
10341024
RecursivelyDeleteTriviallyDeadInstructions(GEP);
10351025
return true;
Lines changed: 277 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
22
; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -S -passes=separate-const-offset-from-gep < %s | FileCheck %s
33

4-
define void @inboundsPossiblyNegative(ptr %in.ptr, i32 %in.idx1) {
4+
define void @inboundsPossiblyNegative(ptr %in.ptr, i64 %in.idx1) {
55
; CHECK-LABEL: define void @inboundsPossiblyNegative(
6-
; CHECK-SAME: ptr [[IN_PTR:%.*]], i32 [[IN_IDX1:%.*]]) #[[ATTR0:[0-9]+]] {
6+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0:[0-9]+]] {
77
; CHECK-NEXT: entry:
8-
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IN_IDX1]] to i64
9-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr <2 x i8>, ptr [[IN_PTR]], i64 [[IDXPROM]]
10-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr <2 x i8>, ptr [[TMP0]], i32 1
8+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr <2 x i8>, ptr [[IN_PTR]], i64 [[IN_IDX1]]
9+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr <2 x i8>, ptr [[TMP0]], i64 1
1110
; CHECK-NEXT: ret void
1211
;
1312
entry:
14-
%const1 = getelementptr inbounds <2 x i8>, ptr %in.ptr, i32 1
15-
%idx1 = getelementptr inbounds <2 x i8>, ptr %const1, i32 %in.idx1
13+
%const1 = getelementptr inbounds <2 x i8>, ptr %in.ptr, i64 1
14+
%idx1 = getelementptr inbounds <2 x i8>, ptr %const1, i64 %in.idx1
1615
ret void
1716
}
1817

19-
define void @inboundsNonNegative(ptr %in.ptr, i32 %in.idx1) {
20-
; CHECK-LABEL: define void @inboundsNonNegative(
18+
define void @inboundsNonNegative_nonCanonical(ptr %in.ptr, i32 %in.idx1) {
19+
; CHECK-LABEL: define void @inboundsNonNegative_nonCanonical(
2120
; CHECK-SAME: ptr [[IN_PTR:%.*]], i32 [[IN_IDX1:%.*]]) #[[ATTR0]] {
2221
; CHECK-NEXT: entry:
23-
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i32 [[IN_IDX1]], 2147483647
24-
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IN_IDX1_NNEG]] to i64
25-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <2 x i8>, ptr [[IN_PTR]], i64 [[IDXPROM]]
22+
; CHECK-NEXT: [[IN_IDX1_NNEG1:%.*]] = and i32 [[IN_IDX1]], 2147483647
23+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = sext i32 [[IN_IDX1_NNEG1]] to i64
24+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <2 x i8>, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
2625
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <2 x i8>, ptr [[TMP0]], i32 1
2726
; CHECK-NEXT: ret void
2827
;
@@ -33,19 +32,277 @@ entry:
3332
ret void
3433
}
3534

36-
define void @inboundsNonchained(ptr %in.ptr, i32 %in.idx1) {
35+
define void @inboundsNonNegative(ptr %in.ptr, i64 %in.idx1) {
36+
; CHECK-LABEL: define void @inboundsNonNegative(
37+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
38+
; CHECK-NEXT: entry:
39+
; CHECK-NEXT: [[IDXPROM:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
40+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <2 x i8>, ptr [[IN_PTR]], i64 [[IDXPROM]]
41+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <2 x i8>, ptr [[TMP0]], i64 1
42+
; CHECK-NEXT: ret void
43+
;
44+
entry:
45+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
46+
%const1 = getelementptr inbounds <2 x i8>, ptr %in.ptr, i64 1
47+
%idx1 = getelementptr inbounds <2 x i8>, ptr %const1, i64 %in.idx1.nneg
48+
ret void
49+
}
50+
51+
define void @inboundsNonchained(ptr %in.ptr, i64 %in.idx1) {
3752
; CHECK-LABEL: define void @inboundsNonchained(
38-
; CHECK-SAME: ptr [[IN_PTR:%.*]], i32 [[IN_IDX1:%.*]]) #[[ATTR0]] {
53+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
3954
; CHECK-NEXT: entry:
40-
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i32 [[IN_IDX1]], 2147483647
41-
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IN_IDX1_NNEG]] to i64
55+
; CHECK-NEXT: [[IDXPROM:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
4256
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr <2 x i8>, ptr [[IN_PTR]], i64 [[IDXPROM]]
43-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr <2 x i8>, ptr [[TMP0]], i32 1
57+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr <2 x i8>, ptr [[TMP0]], i64 1
4458
; CHECK-NEXT: ret void
4559
;
4660
entry:
47-
%in.idx1.nneg = and i32 %in.idx1, 2147483647
48-
%const1 = getelementptr inbounds <2 x i8>, ptr %in.ptr, i32 1
49-
%idx1 = getelementptr <2 x i8>, ptr %const1, i32 %in.idx1.nneg
61+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
62+
%const1 = getelementptr inbounds <2 x i8>, ptr %in.ptr, i64 1
63+
%idx1 = getelementptr <2 x i8>, ptr %const1, i64 %in.idx1.nneg
64+
ret void
65+
}
66+
67+
define void @inboundsNonNegativeType_i16i8(ptr %in.ptr, i64 %in.idx1) {
68+
; CHECK-LABEL: define void @inboundsNonNegativeType_i16i8(
69+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
70+
; CHECK-NEXT: entry:
71+
; CHECK-NEXT: [[IDXPROM:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
72+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[IN_PTR]], i64 [[IDXPROM]]
73+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i16, ptr [[TMP0]], i64 1024
74+
; CHECK-NEXT: ret void
75+
;
76+
entry:
77+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
78+
%const1 = getelementptr inbounds i16, ptr %in.ptr, i64 1024
79+
%idx1 = getelementptr inbounds i8, ptr %const1, i64 %in.idx1.nneg
80+
ret void
81+
}
82+
83+
define void @inboundsNonNegative_i8i16(ptr %in.ptr, i64 %in.idx1) {
84+
; CHECK-LABEL: define void @inboundsNonNegative_i8i16(
85+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
86+
; CHECK-NEXT: entry:
87+
; CHECK-NEXT: [[IDXPROM:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
88+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i16, ptr [[IN_PTR]], i64 [[IDXPROM]]
89+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 1024
90+
; CHECK-NEXT: ret void
91+
;
92+
entry:
93+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
94+
%const1 = getelementptr inbounds i8, ptr %in.ptr, i64 1024
95+
%idx1 = getelementptr inbounds i16, ptr %const1, i64 %in.idx1.nneg
96+
ret void
97+
}
98+
99+
define void @inboundsNonchained_first(ptr %in.ptr, i64 %in.idx1) {
100+
; CHECK-LABEL: define void @inboundsNonchained_first(
101+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
102+
; CHECK-NEXT: entry:
103+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
104+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
105+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i64 1024
106+
; CHECK-NEXT: ret void
107+
;
108+
entry:
109+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
110+
%const1 = getelementptr inbounds i8, ptr %in.ptr, i64 1024
111+
%idx1 = getelementptr i32, ptr %const1, i64 %in.idx1.nneg
112+
ret void
113+
}
114+
115+
define void @inboundsNonchained_second(ptr %in.ptr, i64 %in.idx1) {
116+
; CHECK-LABEL: define void @inboundsNonchained_second(
117+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
118+
; CHECK-NEXT: entry:
119+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
120+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i64, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
121+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i64 1024
122+
; CHECK-NEXT: ret void
123+
;
124+
entry:
125+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
126+
%const1 = getelementptr i8, ptr %in.ptr, i64 1024
127+
%idx1 = getelementptr inbounds i64, ptr %const1, i64 %in.idx1.nneg
128+
ret void
129+
}
130+
131+
define void @notInbounds(ptr %in.ptr, i64 %in.idx1) {
132+
; CHECK-LABEL: define void @notInbounds(
133+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
134+
; CHECK-NEXT: entry:
135+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
136+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i128, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
137+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i64 1024
138+
; CHECK-NEXT: ret void
139+
;
140+
entry:
141+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
142+
%const1 = getelementptr i8, ptr %in.ptr, i64 1024
143+
%idx1 = getelementptr i128, ptr %const1, i64 %in.idx1.nneg
144+
ret void
145+
}
146+
147+
define void @vectorType1(ptr %in.ptr, i64 %in.idx1) {
148+
; CHECK-LABEL: define void @vectorType1(
149+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
150+
; CHECK-NEXT: entry:
151+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
152+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <2 x i8>, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
153+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <4 x i8>, ptr [[TMP0]], i32 3
154+
; CHECK-NEXT: ret void
155+
;
156+
entry:
157+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
158+
%const1 = getelementptr inbounds <4 x i8>, ptr %in.ptr, i32 3
159+
%idx1 = getelementptr inbounds <2 x i8>, ptr %const1, i64 %in.idx1.nneg
160+
ret void
161+
}
162+
163+
define void @vectorType2(ptr %in.ptr, i64 %in.idx1) {
164+
; CHECK-LABEL: define void @vectorType2(
165+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
166+
; CHECK-NEXT: entry:
167+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
168+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <4 x half>, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
169+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <4 x i8>, ptr [[TMP0]], i32 1
170+
; CHECK-NEXT: ret void
171+
;
172+
entry:
173+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
174+
%const1 = getelementptr inbounds <4 x i8>, ptr %in.ptr, i32 1
175+
%idx1 = getelementptr inbounds <4 x half>, ptr %const1, i64 %in.idx1.nneg
176+
ret void
177+
}
178+
179+
define void @vectorType3(ptr %in.ptr, i64 %in.idx1) {
180+
; CHECK-LABEL: define void @vectorType3(
181+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
182+
; CHECK-NEXT: entry:
183+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
184+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds ptr, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
185+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <4 x ptr>, ptr [[TMP0]], i32 1
186+
; CHECK-NEXT: ret void
187+
;
188+
entry:
189+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
190+
%const1 = getelementptr inbounds <4 x ptr>, ptr %in.ptr, i32 1
191+
%idx1 = getelementptr inbounds ptr, ptr %const1, i64 %in.idx1.nneg
192+
ret void
193+
}
194+
195+
define void @vectorType4(ptr %in.ptr, i64 %in.idx1) {
196+
; CHECK-LABEL: define void @vectorType4(
197+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
198+
; CHECK-NEXT: entry:
199+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
200+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds <8 x ptr addrspace(1)>, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
201+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <4 x ptr>, ptr [[TMP0]], i32 3
202+
; CHECK-NEXT: ret void
203+
;
204+
entry:
205+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
206+
%const1 = getelementptr inbounds <4 x ptr>, ptr %in.ptr, i32 3
207+
%idx1 = getelementptr inbounds <8 x ptr addrspace(1)>, ptr %const1, i64 %in.idx1.nneg
208+
ret void
209+
}
210+
211+
212+
define void @ptrType(ptr %in.ptr, i64 %in.idx1) {
213+
; CHECK-LABEL: define void @ptrType(
214+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
215+
; CHECK-NEXT: entry:
216+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
217+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds ptr, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
218+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds ptr addrspace(2), ptr [[TMP0]], i32 1
219+
; CHECK-NEXT: ret void
220+
;
221+
entry:
222+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
223+
%const1 = getelementptr inbounds ptr addrspace(2), ptr %in.ptr, i32 1
224+
%idx1 = getelementptr inbounds ptr, ptr %const1, i64 %in.idx1.nneg
225+
ret void
226+
}
227+
228+
define void @ptrType2(ptr %in.ptr, i64 %in.idx1) {
229+
; CHECK-LABEL: define void @ptrType2(
230+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
231+
; CHECK-NEXT: entry:
232+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
233+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i64, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
234+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds ptr addrspace(3), ptr [[TMP0]], i32 3
235+
; CHECK-NEXT: ret void
236+
;
237+
entry:
238+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
239+
%const1 = getelementptr inbounds ptr addrspace(3), ptr %in.ptr, i32 3
240+
%idx1 = getelementptr inbounds i64, ptr %const1, i64 %in.idx1.nneg
241+
ret void
242+
}
243+
244+
define void @ptrType3(ptr %in.ptr, i64 %in.idx1) {
245+
; CHECK-LABEL: define void @ptrType3(
246+
; CHECK-SAME: ptr [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
247+
; CHECK-NEXT: entry:
248+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 2147483647
249+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i16, ptr [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
250+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds ptr addrspace(7), ptr [[TMP0]], i32 3
251+
; CHECK-NEXT: ret void
252+
;
253+
entry:
254+
%in.idx1.nneg = and i64 %in.idx1, 2147483647
255+
%const1 = getelementptr inbounds ptr addrspace(7), ptr %in.ptr, i32 3
256+
%idx1 = getelementptr inbounds i16, ptr %const1, i64 %in.idx1.nneg
257+
ret void
258+
}
259+
260+
define void @addrspace1(ptr addrspace(1) %in.ptr, i64 %in.idx1) {
261+
; CHECK-LABEL: define void @addrspace1(
262+
; CHECK-SAME: ptr addrspace(1) [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
263+
; CHECK-NEXT: entry:
264+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
265+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i128, ptr addrspace(1) [[IN_PTR]], i64 [[IN_IDX1_NNEG]]
266+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[TMP0]], i64 1024
267+
; CHECK-NEXT: ret void
268+
;
269+
entry:
270+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
271+
%const1 = getelementptr inbounds i8, ptr addrspace(1) %in.ptr, i64 1024
272+
%idx1 = getelementptr inbounds i128, ptr addrspace(1) %const1, i64 %in.idx1.nneg
273+
ret void
274+
}
275+
276+
define void @addrspace3(ptr addrspace(3) %in.ptr, i64 %in.idx1) {
277+
; CHECK-LABEL: define void @addrspace3(
278+
; CHECK-SAME: ptr addrspace(3) [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
279+
; CHECK-NEXT: entry:
280+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
281+
; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX1_NNEG]] to i32
282+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i128, ptr addrspace(3) [[IN_PTR]], i32 [[IDXPROM]]
283+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(3) [[TMP0]], i64 1024
284+
; CHECK-NEXT: ret void
285+
;
286+
entry:
287+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
288+
%const1 = getelementptr inbounds i8, ptr addrspace(3) %in.ptr, i64 1024
289+
%idx1 = getelementptr inbounds i128, ptr addrspace(3) %const1, i64 %in.idx1.nneg
290+
ret void
291+
}
292+
293+
define void @addrspace7(ptr addrspace(7) %in.ptr, i64 %in.idx1) {
294+
; CHECK-LABEL: define void @addrspace7(
295+
; CHECK-SAME: ptr addrspace(7) [[IN_PTR:%.*]], i64 [[IN_IDX1:%.*]]) #[[ATTR0]] {
296+
; CHECK-NEXT: entry:
297+
; CHECK-NEXT: [[IN_IDX1_NNEG:%.*]] = and i64 [[IN_IDX1]], 9223372036854775807
298+
; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[IN_IDX1_NNEG]] to i32
299+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i128, ptr addrspace(7) [[IN_PTR]], i32 [[IDXPROM]]
300+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr addrspace(7) [[TMP0]], i64 1024
301+
; CHECK-NEXT: ret void
302+
;
303+
entry:
304+
%in.idx1.nneg = and i64 %in.idx1, 9223372036854775807
305+
%const1 = getelementptr inbounds i8, ptr addrspace(7) %in.ptr, i64 1024
306+
%idx1 = getelementptr inbounds i128, ptr addrspace(7) %const1, i64 %in.idx1.nneg
50307
ret void
51308
}

0 commit comments

Comments
 (0)