xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/simplify-pointer-arithmetic.ll (revision 864bb84a427de367528d15270790dd152871daf2)
1261f219fSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
2f15ed06aSBjorn Pettersson; RUN: opt -passes=indvars -S %s | FileCheck %s
3261f219fSFlorian Hahn
4261f219fSFlorian Hahn; Test cases inspired by PR48965.
5261f219fSFlorian Hahn
6261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees
7261f219fSFlorian Hahn; the offset is positive. %i.ult.ext can be simplified.
8*864bb84aSNikita Popovdefine i1 @can_simplify_ult_i32_ptr_len_zext(ptr %p.base, i32 %len) {
9261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ult_i32_ptr_len_zext(
10261f219fSFlorian Hahn; CHECK-NEXT:  entry:
11261f219fSFlorian Hahn; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64
12*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]]
13261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0
14261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
15261f219fSFlorian Hahn; CHECK:       header.preheader:
16261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
17261f219fSFlorian Hahn; CHECK:       trap.loopexit:
18261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
19261f219fSFlorian Hahn; CHECK:       trap:
20261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
21261f219fSFlorian Hahn; CHECK:       header:
22*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
23261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ]
24261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
25261f219fSFlorian Hahn; CHECK-NEXT:    [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]]
26261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]]
27261f219fSFlorian Hahn; CHECK:       latch:
28*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
29*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
30*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
31261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
32261f219fSFlorian Hahn; CHECK:       exit:
33261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
34261f219fSFlorian Hahn;
35261f219fSFlorian Hahnentry:
36261f219fSFlorian Hahn  %ext = zext i32 %len to i64
37*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext
38261f219fSFlorian Hahn  %len.nonzero = icmp ne i32 %len, 0
39261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
40261f219fSFlorian Hahn
41261f219fSFlorian Hahntrap:
42261f219fSFlorian Hahn  ret i1 false
43261f219fSFlorian Hahn
44261f219fSFlorian Hahnheader:
45*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
46261f219fSFlorian Hahn  %i = phi i64 [ 0, %entry ], [ %i.inc, %latch]
47261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
48261f219fSFlorian Hahn  %i.ult.ext = icmp ult i64 %i, %ext
49261f219fSFlorian Hahn  br i1 %i.ult.ext, label %latch, label %trap
50261f219fSFlorian Hahn
51261f219fSFlorian Hahnlatch:
52*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
53*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
54*864bb84aSNikita Popov  store i32 0, ptr %p
55261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
56261f219fSFlorian Hahn
57261f219fSFlorian Hahnexit:
58261f219fSFlorian Hahn  ret i1 true
59261f219fSFlorian Hahn}
60261f219fSFlorian Hahn
61261f219fSFlorian Hahn; %len may be (signed) negative, %i.ult.ext cannot be simplified.
62*864bb84aSNikita Popovdefine i1 @cannot_simplify_ult_i32_ptr_len_ult(ptr %p.base, i64 %len) {
63261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_ult(
64261f219fSFlorian Hahn; CHECK-NEXT:  entry:
65*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[LEN:%.*]]
66261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0
67261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
68261f219fSFlorian Hahn; CHECK:       header.preheader:
69261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
70261f219fSFlorian Hahn; CHECK:       trap.loopexit:
71261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
72261f219fSFlorian Hahn; CHECK:       trap:
73261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
74261f219fSFlorian Hahn; CHECK:       header:
75*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
76261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ]
77261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
78261f219fSFlorian Hahn; CHECK-NEXT:    [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[LEN]]
79261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]]
80261f219fSFlorian Hahn; CHECK:       latch:
81*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
82*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
83*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
84261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
85261f219fSFlorian Hahn; CHECK:       exit:
86261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
87261f219fSFlorian Hahn;
88261f219fSFlorian Hahnentry:
89*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %len
90261f219fSFlorian Hahn  %len.nonzero = icmp ne i64 %len, 0
91261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
92261f219fSFlorian Hahn
93261f219fSFlorian Hahntrap:
94261f219fSFlorian Hahn  ret i1 false
95261f219fSFlorian Hahn
96261f219fSFlorian Hahnheader:
97*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
98261f219fSFlorian Hahn  %i = phi i64 [ 0, %entry ], [ %i.inc, %latch]
99261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
100261f219fSFlorian Hahn  %i.ult.ext = icmp ult i64 %i, %len
101261f219fSFlorian Hahn  br i1 %i.ult.ext, label %latch, label %trap
102261f219fSFlorian Hahn
103261f219fSFlorian Hahnlatch:
104*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
105*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
106*864bb84aSNikita Popov  store i32 0, ptr %p
107261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
108261f219fSFlorian Hahn
109261f219fSFlorian Hahnexit:
110261f219fSFlorian Hahn  ret i1 true
111261f219fSFlorian Hahn}
112261f219fSFlorian Hahn
113261f219fSFlorian Hahn; Similar to can_simplify_ult_i32_ptr_len_zext, but %i has 1 as start value. %i.ult.ext cannot be simplified.
114*864bb84aSNikita Popovdefine i1 @cannot_simplify_ult_i32_ptr_len_zext(ptr %p.base, i32 %len) {
115261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_ult_i32_ptr_len_zext(
116261f219fSFlorian Hahn; CHECK-NEXT:  entry:
117261f219fSFlorian Hahn; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64
118*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]]
119261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0
120261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
121261f219fSFlorian Hahn; CHECK:       header.preheader:
122261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
123261f219fSFlorian Hahn; CHECK:       trap.loopexit:
124261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
125261f219fSFlorian Hahn; CHECK:       trap:
126261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
127261f219fSFlorian Hahn; CHECK:       header:
128*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
129261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ]
130261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
131261f219fSFlorian Hahn; CHECK-NEXT:    [[I_ULT_EXT:%.*]] = icmp ult i64 [[I]], [[EXT]]
132261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]]
133261f219fSFlorian Hahn; CHECK:       latch:
134*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
135*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
136*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
137261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
138261f219fSFlorian Hahn; CHECK:       exit:
139261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
140261f219fSFlorian Hahn;
141261f219fSFlorian Hahnentry:
142261f219fSFlorian Hahn  %ext = zext i32 %len to i64
143*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext
144261f219fSFlorian Hahn  %len.nonzero = icmp ne i32 %len, 0
145261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
146261f219fSFlorian Hahn
147261f219fSFlorian Hahntrap:
148261f219fSFlorian Hahn  ret i1 false
149261f219fSFlorian Hahn
150261f219fSFlorian Hahnheader:
151*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
152261f219fSFlorian Hahn  %i = phi i64 [ 1, %entry ], [ %i.inc, %latch]
153261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
154261f219fSFlorian Hahn  %i.ult.ext = icmp ult i64 %i, %ext
155261f219fSFlorian Hahn  br i1 %i.ult.ext, label %latch, label %trap
156261f219fSFlorian Hahn
157261f219fSFlorian Hahnlatch:
158*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
159*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
160*864bb84aSNikita Popov  store i32 0, ptr %p
161261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
162261f219fSFlorian Hahn
163261f219fSFlorian Hahnexit:
164261f219fSFlorian Hahn  ret i1 true
165261f219fSFlorian Hahn}
166261f219fSFlorian Hahn
167*864bb84aSNikita Popovdefine i1 @can_simplify_ule_i32_ptr_len_zext(ptr %p.base, i32 %len) {
168261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_ule_i32_ptr_len_zext(
169261f219fSFlorian Hahn; CHECK-NEXT:  entry:
170261f219fSFlorian Hahn; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64
171*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]]
172261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0
173261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
174261f219fSFlorian Hahn; CHECK:       header.preheader:
175261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
176261f219fSFlorian Hahn; CHECK:       trap.loopexit:
177261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
178261f219fSFlorian Hahn; CHECK:       trap:
179261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
180261f219fSFlorian Hahn; CHECK:       header:
181*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
182261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 1, [[HEADER_PREHEADER]] ]
183261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
184261f219fSFlorian Hahn; CHECK-NEXT:    [[I_ULT_EXT:%.*]] = icmp ule i64 [[I]], [[EXT]]
185261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_ULT_EXT]], label [[LATCH]], label [[TRAP_LOOPEXIT:%.*]]
186261f219fSFlorian Hahn; CHECK:       latch:
187*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
188*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
189*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
190261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
191261f219fSFlorian Hahn; CHECK:       exit:
192261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
193261f219fSFlorian Hahn;
194261f219fSFlorian Hahnentry:
195261f219fSFlorian Hahn  %ext = zext i32 %len to i64
196*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext
197261f219fSFlorian Hahn  %len.nonzero = icmp ne i32 %len, 0
198261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
199261f219fSFlorian Hahn
200261f219fSFlorian Hahntrap:
201261f219fSFlorian Hahn  ret i1 false
202261f219fSFlorian Hahn
203261f219fSFlorian Hahnheader:
204*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
205261f219fSFlorian Hahn  %i = phi i64 [ 1, %entry ], [ %i.inc, %latch]
206261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
207261f219fSFlorian Hahn  %i.ult.ext = icmp ule i64 %i, %ext
208261f219fSFlorian Hahn  br i1 %i.ult.ext, label %latch, label %trap
209261f219fSFlorian Hahn
210261f219fSFlorian Hahnlatch:
211*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
212*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
213*864bb84aSNikita Popov  store i32 0, ptr %p
214261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
215261f219fSFlorian Hahn
216261f219fSFlorian Hahnexit:
217261f219fSFlorian Hahn  ret i1 true
218261f219fSFlorian Hahn}
219261f219fSFlorian Hahn
220261f219fSFlorian Hahn; %len is zero-extended before being used to compute %p.end, which guarantees
221261f219fSFlorian Hahn; the offset is positive. %i.uge.ext can be simplified.
222*864bb84aSNikita Popovdefine i1 @can_simplify_uge_i32_ptr_len_zext(ptr %p.base, i32 %len) {
223261f219fSFlorian Hahn; CHECK-LABEL: @can_simplify_uge_i32_ptr_len_zext(
224261f219fSFlorian Hahn; CHECK-NEXT:  entry:
225261f219fSFlorian Hahn; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64
226*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]]
227261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0
228261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
229261f219fSFlorian Hahn; CHECK:       header.preheader:
230261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
231261f219fSFlorian Hahn; CHECK:       trap.loopexit:
232261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
233261f219fSFlorian Hahn; CHECK:       trap:
234261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
235261f219fSFlorian Hahn; CHECK:       header:
236*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
237261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ]
238261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
239261f219fSFlorian Hahn; CHECK-NEXT:    [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]]
240261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]]
241261f219fSFlorian Hahn; CHECK:       latch:
242*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
243*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
244*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
245261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
246261f219fSFlorian Hahn; CHECK:       exit:
247261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
248261f219fSFlorian Hahn;
249261f219fSFlorian Hahnentry:
250261f219fSFlorian Hahn  %ext = zext i32 %len to i64
251*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext
252261f219fSFlorian Hahn  %len.nonzero = icmp ne i32 %len, 0
253261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
254261f219fSFlorian Hahn
255261f219fSFlorian Hahntrap:
256261f219fSFlorian Hahn  ret i1 false
257261f219fSFlorian Hahn
258261f219fSFlorian Hahnheader:
259*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
260261f219fSFlorian Hahn  %i = phi i64 [ 0, %entry ], [ %i.inc, %latch]
261261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
262261f219fSFlorian Hahn  %i.uge.ext = icmp uge i64 %i, %ext
263261f219fSFlorian Hahn  br i1 %i.uge.ext, label %trap, label %latch
264261f219fSFlorian Hahn
265261f219fSFlorian Hahnlatch:
266*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
267*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
268*864bb84aSNikita Popov  store i32 0, ptr %p
269261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
270261f219fSFlorian Hahn
271261f219fSFlorian Hahnexit:
272261f219fSFlorian Hahn  ret i1 true
273261f219fSFlorian Hahn}
274261f219fSFlorian Hahn
275*864bb84aSNikita Popovdefine i1 @cannot_simplify_uge_i32_ptr_len(ptr %p.base, i64 %len) {
276261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len(
277261f219fSFlorian Hahn; CHECK-NEXT:  entry:
278*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[LEN:%.*]]
279261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i64 [[LEN]], 0
280261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
281261f219fSFlorian Hahn; CHECK:       header.preheader:
282261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
283261f219fSFlorian Hahn; CHECK:       trap.loopexit:
284261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
285261f219fSFlorian Hahn; CHECK:       trap:
286261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
287261f219fSFlorian Hahn; CHECK:       header:
288*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
289261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ]
290261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 1
291261f219fSFlorian Hahn; CHECK-NEXT:    [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[LEN]]
292261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]]
293261f219fSFlorian Hahn; CHECK:       latch:
294*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
295*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
296*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
297261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
298261f219fSFlorian Hahn; CHECK:       exit:
299261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
300261f219fSFlorian Hahn;
301261f219fSFlorian Hahnentry:
302*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %len
303261f219fSFlorian Hahn  %len.nonzero = icmp ne i64 %len, 0
304261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
305261f219fSFlorian Hahn
306261f219fSFlorian Hahntrap:
307261f219fSFlorian Hahn  ret i1 false
308261f219fSFlorian Hahn
309261f219fSFlorian Hahnheader:
310*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
311261f219fSFlorian Hahn  %i = phi i64 [ 0, %entry ], [ %i.inc, %latch]
312261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 1
313261f219fSFlorian Hahn  %i.uge.ext = icmp uge i64 %i, %len
314261f219fSFlorian Hahn  br i1 %i.uge.ext, label %trap, label %latch
315261f219fSFlorian Hahn
316261f219fSFlorian Hahnlatch:
317*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
318*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
319*864bb84aSNikita Popov  store i32 0, ptr %p
320261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
321261f219fSFlorian Hahn
322261f219fSFlorian Hahnexit:
323261f219fSFlorian Hahn  ret i1 true
324261f219fSFlorian Hahn}
325261f219fSFlorian Hahn
326*864bb84aSNikita Popovdefine i1 @cannot_simplify_uge_i32_ptr_len_zext_step_2(ptr %p.base, i32 %len) {
327261f219fSFlorian Hahn; CHECK-LABEL: @cannot_simplify_uge_i32_ptr_len_zext_step_2(
328261f219fSFlorian Hahn; CHECK-NEXT:  entry:
329261f219fSFlorian Hahn; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[LEN:%.*]] to i64
330*864bb84aSNikita Popov; CHECK-NEXT:    [[P_END:%.*]] = getelementptr inbounds i32, ptr [[P_BASE:%.*]], i64 [[EXT]]
331261f219fSFlorian Hahn; CHECK-NEXT:    [[LEN_NONZERO:%.*]] = icmp ne i32 [[LEN]], 0
332261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NONZERO]], label [[HEADER_PREHEADER:%.*]], label [[TRAP:%.*]]
333261f219fSFlorian Hahn; CHECK:       header.preheader:
334261f219fSFlorian Hahn; CHECK-NEXT:    br label [[HEADER:%.*]]
335261f219fSFlorian Hahn; CHECK:       trap.loopexit:
336261f219fSFlorian Hahn; CHECK-NEXT:    br label [[TRAP]]
337261f219fSFlorian Hahn; CHECK:       trap:
338261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 false
339261f219fSFlorian Hahn; CHECK:       header:
340*864bb84aSNikita Popov; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[P_INC:%.*]], [[LATCH:%.*]] ], [ [[P_BASE]], [[HEADER_PREHEADER]] ]
341261f219fSFlorian Hahn; CHECK-NEXT:    [[I:%.*]] = phi i64 [ [[I_INC:%.*]], [[LATCH]] ], [ 0, [[HEADER_PREHEADER]] ]
342261f219fSFlorian Hahn; CHECK-NEXT:    [[I_INC]] = add nuw nsw i64 [[I]], 2
343261f219fSFlorian Hahn; CHECK-NEXT:    [[I_UGE_EXT:%.*]] = icmp uge i64 [[I]], [[EXT]]
344261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[I_UGE_EXT]], label [[TRAP_LOOPEXIT:%.*]], label [[LATCH]]
345261f219fSFlorian Hahn; CHECK:       latch:
346*864bb84aSNikita Popov; CHECK-NEXT:    [[P_INC]] = getelementptr inbounds i32, ptr [[P]], i64 1
347*864bb84aSNikita Popov; CHECK-NEXT:    [[C:%.*]] = icmp ne ptr [[P_INC]], [[P_END]]
348*864bb84aSNikita Popov; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
349261f219fSFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[HEADER]], label [[EXIT:%.*]]
350261f219fSFlorian Hahn; CHECK:       exit:
351261f219fSFlorian Hahn; CHECK-NEXT:    ret i1 true
352261f219fSFlorian Hahn;
353261f219fSFlorian Hahnentry:
354261f219fSFlorian Hahn  %ext = zext i32 %len to i64
355*864bb84aSNikita Popov  %p.end = getelementptr inbounds i32, ptr %p.base, i64 %ext
356261f219fSFlorian Hahn  %len.nonzero = icmp ne i32 %len, 0
357261f219fSFlorian Hahn  br i1 %len.nonzero, label %header, label %trap
358261f219fSFlorian Hahn
359261f219fSFlorian Hahntrap:
360261f219fSFlorian Hahn  ret i1 false
361261f219fSFlorian Hahn
362261f219fSFlorian Hahnheader:
363*864bb84aSNikita Popov  %p = phi ptr [ %p.base, %entry ], [ %p.inc, %latch ]
364261f219fSFlorian Hahn  %i = phi i64 [ 0, %entry ], [ %i.inc, %latch]
365261f219fSFlorian Hahn  %i.inc = add nsw nuw i64 %i, 2
366261f219fSFlorian Hahn  %i.uge.ext = icmp uge i64 %i, %ext
367261f219fSFlorian Hahn  br i1 %i.uge.ext, label %trap, label %latch
368261f219fSFlorian Hahn
369261f219fSFlorian Hahnlatch:
370*864bb84aSNikita Popov  %p.inc = getelementptr inbounds i32, ptr %p, i64 1
371*864bb84aSNikita Popov  %c = icmp ne ptr %p.inc, %p.end
372*864bb84aSNikita Popov  store i32 0, ptr %p
373261f219fSFlorian Hahn  br i1 %c, label %header, label %exit
374261f219fSFlorian Hahn
375261f219fSFlorian Hahnexit:
376261f219fSFlorian Hahn  ret i1 true
377261f219fSFlorian Hahn}
378