@@ -108,3 +108,163 @@ entry:
108108 store i32 %b , ptr %gep
109109 ret void
110110}
111+
112+ define ptr @gep_inbounds_add_nsw_nonneg (ptr %ptr , i64 %a , i64 %b ) {
113+ ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_nonneg(
114+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
115+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
116+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
117+ ; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
118+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])
119+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
120+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
121+ ; CHECK-NEXT: ret ptr [[GEP]]
122+ ;
123+ %a.nneg = icmp sgt i64 %a , -1
124+ call void @llvm.assume (i1 %a.nneg )
125+ %b.nneg = icmp sgt i64 %b , -1
126+ call void @llvm.assume (i1 %b.nneg )
127+ %add = add nsw i64 %a , %b
128+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %add
129+ ret ptr %gep
130+ }
131+
132+ define ptr @gep_inbounds_add_nsw_not_nonneg1 (ptr %ptr , i64 %a , i64 %b ) {
133+ ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg1(
134+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
135+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
136+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
137+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
138+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
139+ ; CHECK-NEXT: ret ptr [[GEP]]
140+ ;
141+ %a.nneg = icmp sgt i64 %a , -1
142+ call void @llvm.assume (i1 %a.nneg )
143+ %add = add nsw i64 %a , %b
144+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %add
145+ ret ptr %gep
146+ }
147+
148+ define ptr @gep_inbounds_add_nsw_not_nonneg2 (ptr %ptr , i64 %a , i64 %b ) {
149+ ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg2(
150+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
151+ ; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
152+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])
153+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
154+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
155+ ; CHECK-NEXT: ret ptr [[GEP]]
156+ ;
157+ %b.nneg = icmp sgt i64 %b , -1
158+ call void @llvm.assume (i1 %b.nneg )
159+ %add = add nsw i64 %a , %b
160+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %add
161+ ret ptr %gep
162+ }
163+
164+ define ptr @gep_not_inbounds_add_nsw_nonneg (ptr %ptr , i64 %a , i64 %b ) {
165+ ; CHECK-LABEL: define ptr @gep_not_inbounds_add_nsw_nonneg(
166+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
167+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
168+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
169+ ; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
170+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])
171+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
172+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
173+ ; CHECK-NEXT: ret ptr [[GEP]]
174+ ;
175+ %a.nneg = icmp sgt i64 %a , -1
176+ call void @llvm.assume (i1 %a.nneg )
177+ %b.nneg = icmp sgt i64 %b , -1
178+ call void @llvm.assume (i1 %b.nneg )
179+ %add = add nsw i64 %a , %b
180+ %gep = getelementptr i32 , ptr %ptr , i64 %add
181+ ret ptr %gep
182+ }
183+
184+ define ptr @gep_inbounds_add_not_nsw_nonneg (ptr %ptr , i64 %a , i64 %b ) {
185+ ; CHECK-LABEL: define ptr @gep_inbounds_add_not_nsw_nonneg(
186+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
187+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
188+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
189+ ; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
190+ ; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])
191+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
192+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
193+ ; CHECK-NEXT: ret ptr [[GEP]]
194+ ;
195+ %a.nneg = icmp sgt i64 %a , -1
196+ call void @llvm.assume (i1 %a.nneg )
197+ %b.nneg = icmp sgt i64 %b , -1
198+ call void @llvm.assume (i1 %b.nneg )
199+ %add = add i64 %a , %b
200+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %add
201+ ret ptr %gep
202+ }
203+
204+ define ptr @gep_inbounds_sext_add_nonneg (ptr %ptr , i32 %a ) {
205+ ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_nonneg(
206+ ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
207+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
208+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
209+ ; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
210+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
211+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40
212+ ; CHECK-NEXT: ret ptr [[GEP]]
213+ ;
214+ %a.nneg = icmp sgt i32 %a , -1
215+ call void @llvm.assume (i1 %a.nneg )
216+ %add = add nsw i32 %a , 10
217+ %idx = sext i32 %add to i64
218+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %idx
219+ ret ptr %gep
220+ }
221+
222+ define ptr @gep_inbounds_sext_add_not_nonneg_1 (ptr %ptr , i32 %a ) {
223+ ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_1(
224+ ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
225+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
226+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
227+ ; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
228+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
229+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 -40
230+ ; CHECK-NEXT: ret ptr [[GEP]]
231+ ;
232+ %a.nneg = icmp sgt i32 %a , -1
233+ call void @llvm.assume (i1 %a.nneg )
234+ %add = add nsw i32 %a , -10
235+ %idx = sext i32 %add to i64
236+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %idx
237+ ret ptr %gep
238+ }
239+
240+ define ptr @gep_inbounds_sext_add_not_nonneg_2 (ptr %ptr , i32 %a ) {
241+ ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_2(
242+ ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
243+ ; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[A]] to i64
244+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
245+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40
246+ ; CHECK-NEXT: ret ptr [[GEP]]
247+ ;
248+ %add = add nsw i32 %a , 10
249+ %idx = sext i32 %add to i64
250+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %idx
251+ ret ptr %gep
252+ }
253+
254+ define ptr @gep_not_inbounds_sext_add_nonneg (ptr %ptr , i32 %a ) {
255+ ; CHECK-LABEL: define ptr @gep_not_inbounds_sext_add_nonneg(
256+ ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
257+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
258+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
259+ ; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
260+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
261+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40
262+ ; CHECK-NEXT: ret ptr [[GEP]]
263+ ;
264+ %a.nneg = icmp sgt i32 %a , -1
265+ call void @llvm.assume (i1 %a.nneg )
266+ %add = add nsw i32 %a , 10
267+ %idx = sext i32 %add to i64
268+ %gep = getelementptr i32 , ptr %ptr , i64 %idx
269+ ret ptr %gep
270+ }
0 commit comments