@@ -50,10 +50,9 @@ define ptr @partialConstant2(ptr %p, i64 %a, i64 %b) {
5050; result = ((ptr) p + a) + 3
5151define ptr @merge (ptr %p , i64 %a ) {
5252; CHECK-LABEL: @merge(
53- ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 4
54- ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]
55- ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8
56- ; CHECK-NEXT: ret ptr [[TMP3]]
53+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]
54+ ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP1]], i64 12
55+ ; CHECK-NEXT: ret ptr [[TMP2]]
5756;
5857 %1 = getelementptr inbounds i32 , ptr %p , i64 1
5958 %2 = getelementptr inbounds i32 , ptr %1 , i64 %a
@@ -67,13 +66,11 @@ define ptr @merge(ptr %p, i64 %a) {
6766; result = (ptr) ((ptr) ((ptr) ptr + a) + (a * b)) + 9
6867define ptr @nested (ptr %p , i64 %a , i64 %b ) {
6968; CHECK-LABEL: @nested(
70- ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 16
71- ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 [[A:%.*]]
72- ; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[A]], [[B:%.*]]
73- ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 128
74- ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i16, ptr [[TMP4]], i64 [[TMP3]]
75- ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP5]], i64 16
76- ; CHECK-NEXT: ret ptr [[TMP6]]
69+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
70+ ; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[A]], [[B:%.*]]
71+ ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i16, ptr [[TMP1]], i64 [[TMP2]]
72+ ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP3]], i64 160
73+ ; CHECK-NEXT: ret ptr [[TMP4]]
7774;
7875 %1 = getelementptr inbounds <3 x i32 >, ptr %p , i64 1
7976 %2 = getelementptr inbounds i8 , ptr %1 , i64 %a
@@ -125,3 +122,138 @@ define ptr @multipleUses3(ptr %p) {
125122 %3 = getelementptr inbounds i32 , ptr %1 , i64 %2
126123 ret ptr %3
127124}
125+
126+ define ptr @merge_nuw (ptr %p , i64 %a ) {
127+ ; CHECK-LABEL: @merge_nuw(
128+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
129+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5
130+ ; CHECK-NEXT: ret ptr [[GEP3]]
131+ ;
132+ %gep1 = getelementptr nuw i8 , ptr %p , i64 1
133+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %a
134+ %gep3 = getelementptr nuw i32 , ptr %gep2 , i64 1
135+ ret ptr %gep3
136+ }
137+
138+ define ptr @merge_nuw_inbounds (ptr %p , i64 %a ) {
139+ ; CHECK-LABEL: @merge_nuw_inbounds(
140+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
141+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP2]], i64 5
142+ ; CHECK-NEXT: ret ptr [[GEP3]]
143+ ;
144+ %gep1 = getelementptr inbounds nuw i8 , ptr %p , i64 1
145+ %gep2 = getelementptr inbounds nuw i32 , ptr %gep1 , i64 %a
146+ %gep3 = getelementptr inbounds nuw i32 , ptr %gep2 , i64 1
147+ ret ptr %gep3
148+ }
149+
150+ ; It would be okay to preserve nusw here, as the constant addition does not
151+ ; overflow.
152+ define ptr @merge_nuw_nusw (ptr %p , i64 %a ) {
153+ ; CHECK-LABEL: @merge_nuw_nusw(
154+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
155+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5
156+ ; CHECK-NEXT: ret ptr [[GEP3]]
157+ ;
158+ %gep1 = getelementptr nusw nuw i8 , ptr %p , i64 1
159+ %gep2 = getelementptr nusw nuw i32 , ptr %gep1 , i64 %a
160+ %gep3 = getelementptr nusw nuw i32 , ptr %gep2 , i64 1
161+ ret ptr %gep3
162+ }
163+
164+ ; Can't preserve nusw on the final GEP
165+ define ptr @merge_nuw_nusw_overflow (ptr %p , i64 %a ) {
166+ ; CHECK-LABEL: @merge_nuw_nusw_overflow(
167+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
168+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 -2305843009213693952
169+ ; CHECK-NEXT: ret ptr [[GEP3]]
170+ ;
171+ %gep1 = getelementptr nusw nuw i8 , ptr %p , i64 u0x7000000000000000
172+ %gep2 = getelementptr nusw nuw i32 , ptr %gep1 , i64 %a
173+ %gep3 = getelementptr nusw nuw i8 , ptr %gep2 , i64 u0x7000000000000000
174+ ret ptr %gep3
175+ }
176+
177+ define ptr @merge_missing_nuw1 (ptr %p , i64 %a ) {
178+ ; CHECK-LABEL: @merge_missing_nuw1(
179+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]
180+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5
181+ ; CHECK-NEXT: ret ptr [[GEP3]]
182+ ;
183+ %gep1 = getelementptr i8 , ptr %p , i64 1
184+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %a
185+ %gep3 = getelementptr nuw i32 , ptr %gep2 , i64 1
186+ ret ptr %gep3
187+ }
188+
189+ define ptr @merge_missing_nuw2 (ptr %p , i64 %a ) {
190+ ; CHECK-LABEL: @merge_missing_nuw2(
191+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]
192+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5
193+ ; CHECK-NEXT: ret ptr [[GEP3]]
194+ ;
195+ %gep1 = getelementptr nuw i8 , ptr %p , i64 1
196+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %a
197+ %gep3 = getelementptr nuw i32 , ptr %gep2 , i64 1
198+ ret ptr %gep3
199+ }
200+
201+ define ptr @merge_missing_nuw3 (ptr %p , i64 %a ) {
202+ ; CHECK-LABEL: @merge_missing_nuw3(
203+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
204+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5
205+ ; CHECK-NEXT: ret ptr [[GEP3]]
206+ ;
207+ %gep1 = getelementptr nuw i8 , ptr %p , i64 1
208+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %a
209+ %gep3 = getelementptr i32 , ptr %gep2 , i64 1
210+ ret ptr %gep3
211+ }
212+
213+ define ptr @merge_nuw_missing_inbounds (ptr %p , i64 %a ) {
214+ ; CHECK-LABEL: @merge_nuw_missing_inbounds(
215+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
216+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5
217+ ; CHECK-NEXT: ret ptr [[GEP3]]
218+ ;
219+ %gep1 = getelementptr nuw i8 , ptr %p , i64 1
220+ %gep2 = getelementptr inbounds nuw i32 , ptr %gep1 , i64 %a
221+ %gep3 = getelementptr inbounds nuw i32 , ptr %gep2 , i64 1
222+ ret ptr %gep3
223+ }
224+
225+ define ptr @merge_nuw_missing_nusw (ptr %p , i64 %a ) {
226+ ; CHECK-LABEL: @merge_nuw_missing_nusw(
227+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[A:%.*]]
228+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[GEP2]], i64 5
229+ ; CHECK-NEXT: ret ptr [[GEP3]]
230+ ;
231+ %gep1 = getelementptr nusw nuw i8 , ptr %p , i64 1
232+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %a
233+ %gep3 = getelementptr nusw nuw i32 , ptr %gep2 , i64 1
234+ ret ptr %gep3
235+ }
236+
237+ define ptr @merge_inbounds_missing_nuw (ptr %p , i64 %a ) {
238+ ; CHECK-LABEL: @merge_inbounds_missing_nuw(
239+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]
240+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5
241+ ; CHECK-NEXT: ret ptr [[GEP3]]
242+ ;
243+ %gep1 = getelementptr inbounds nuw i8 , ptr %p , i64 1
244+ %gep2 = getelementptr inbounds i32 , ptr %gep1 , i64 %a
245+ %gep3 = getelementptr inbounds nuw i32 , ptr %gep2 , i64 1
246+ ret ptr %gep3
247+ }
248+
249+ define ptr @merge_nusw_missing_nuw (ptr %p , i64 %a ) {
250+ ; CHECK-LABEL: @merge_nusw_missing_nuw(
251+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[A:%.*]]
252+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i8, ptr [[GEP2]], i64 5
253+ ; CHECK-NEXT: ret ptr [[GEP3]]
254+ ;
255+ %gep1 = getelementptr nusw nuw i8 , ptr %p , i64 1
256+ %gep2 = getelementptr nusw i32 , ptr %gep1 , i64 %a
257+ %gep3 = getelementptr nusw nuw i32 , ptr %gep2 , i64 1
258+ ret ptr %gep3
259+ }
0 commit comments