@@ -110,4 +110,241 @@ fail:
110
110
unreachable
111
111
}
112
112
113
+
114
+ define void @predicated_outside_loop_signed (i32 %arg ) nounwind #0 {
115
+ ; CHECK-LABEL: @predicated_outside_loop_signed(
116
+ ; CHECK-NEXT: entry:
117
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
118
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
119
+ ; CHECK-NEXT: br i1 [[CMP1]], label [[OUTER_PREHEADER:%.*]], label [[EXIT:%.*]]
120
+ ; CHECK: outer.preheader:
121
+ ; CHECK-NEXT: br label [[OUTER:%.*]]
122
+ ; CHECK: outer:
123
+ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
124
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
125
+ ; CHECK-NEXT: [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
126
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 0, [[SUB3]]
127
+ ; CHECK-NEXT: br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
128
+ ; CHECK: inner.ph:
129
+ ; CHECK-NEXT: br label [[INNER:%.*]]
130
+ ; CHECK: inner:
131
+ ; CHECK-NEXT: br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
132
+ ; CHECK: outer.inc.loopexit:
133
+ ; CHECK-NEXT: br label [[OUTER_INC]]
134
+ ; CHECK: outer.inc:
135
+ ; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
136
+ ; CHECK-NEXT: br i1 false, label [[OUTER]], label [[EXIT_LOOPEXIT:%.*]]
137
+ ; CHECK: exit.loopexit:
138
+ ; CHECK-NEXT: br label [[EXIT]]
139
+ ; CHECK: exit:
140
+ ; CHECK-NEXT: ret void
141
+ ;
142
+ entry:
143
+ %sub1 = sub nsw i32 %arg , 1
144
+ %cmp1 = icmp slt i32 0 , %sub1
145
+ br i1 %cmp1 , label %outer , label %exit
146
+
147
+ outer:
148
+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %outer.inc ]
149
+ %sub2 = sub nsw i32 %arg , %i
150
+ %sub3 = sub nsw i32 %sub2 , 1
151
+ %cmp2 = icmp slt i32 0 , %sub3
152
+ br i1 %cmp2 , label %inner.ph , label %outer.inc
153
+
154
+ inner.ph:
155
+ br label %inner
156
+
157
+ inner:
158
+ %j = phi i32 [ 0 , %inner.ph ], [ %j.inc , %inner ]
159
+ %j.inc = add nsw i32 %j , 1
160
+ %cmp3 = icmp slt i32 %j.inc , %sub3
161
+ br i1 %cmp3 , label %inner , label %outer.inc
162
+
163
+ outer.inc:
164
+ %i.inc = add nsw i32 %i , 1
165
+ %cmp4 = icmp slt i32 %i.inc , %arg
166
+ br i1 %cmp4 , label %outer , label %exit
167
+
168
+ exit:
169
+ ret void
170
+ }
171
+
172
+ define void @predicated_outside_loop_unsigned (i32 %arg ) nounwind #0 {
173
+ ; CHECK-LABEL: @predicated_outside_loop_unsigned(
174
+ ; CHECK-NEXT: entry:
175
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
176
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
177
+ ; CHECK-NEXT: br i1 [[CMP1]], label [[OUTER_PREHEADER:%.*]], label [[EXIT:%.*]]
178
+ ; CHECK: outer.preheader:
179
+ ; CHECK-NEXT: br label [[OUTER:%.*]]
180
+ ; CHECK: outer:
181
+ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ], [ 0, [[OUTER_PREHEADER]] ]
182
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
183
+ ; CHECK-NEXT: [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
184
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 0, [[SUB3]]
185
+ ; CHECK-NEXT: br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
186
+ ; CHECK: inner.ph:
187
+ ; CHECK-NEXT: br label [[INNER:%.*]]
188
+ ; CHECK: inner:
189
+ ; CHECK-NEXT: br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
190
+ ; CHECK: outer.inc.loopexit:
191
+ ; CHECK-NEXT: br label [[OUTER_INC]]
192
+ ; CHECK: outer.inc:
193
+ ; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
194
+ ; CHECK-NEXT: br i1 false, label [[OUTER]], label [[EXIT_LOOPEXIT:%.*]]
195
+ ; CHECK: exit.loopexit:
196
+ ; CHECK-NEXT: br label [[EXIT]]
197
+ ; CHECK: exit:
198
+ ; CHECK-NEXT: ret void
199
+ ;
200
+ entry:
201
+ %sub1 = sub nsw i32 %arg , 1
202
+ %cmp1 = icmp slt i32 0 , %sub1
203
+ br i1 %cmp1 , label %outer , label %exit
204
+
205
+ outer:
206
+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %outer.inc ]
207
+ %sub2 = sub nsw i32 %arg , %i
208
+ %sub3 = sub nsw i32 %sub2 , 1
209
+ %cmp2 = icmp ult i32 0 , %sub3
210
+ br i1 %cmp2 , label %inner.ph , label %outer.inc
211
+
212
+ inner.ph:
213
+ br label %inner
214
+
215
+ inner:
216
+ %j = phi i32 [ 0 , %inner.ph ], [ %j.inc , %inner ]
217
+ %j.inc = add nsw i32 %j , 1
218
+ %cmp3 = icmp slt i32 %j.inc , %sub3
219
+ br i1 %cmp3 , label %inner , label %outer.inc
220
+
221
+ outer.inc:
222
+ %i.inc = add nsw i32 %i , 1
223
+ %cmp4 = icmp slt i32 %i.inc , %arg
224
+ br i1 %cmp4 , label %outer , label %exit
225
+
226
+ exit:
227
+ ret void
228
+ }
229
+
230
+ define void @predicated_inside_loop_signed (i32 %arg ) nounwind #0 {
231
+ ; CHECK-LABEL: @predicated_inside_loop_signed(
232
+ ; CHECK-NEXT: entry:
233
+ ; CHECK-NEXT: br label [[OUTER:%.*]]
234
+ ; CHECK: outer:
235
+ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ]
236
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
237
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
238
+ ; CHECK-NEXT: br i1 [[CMP1]], label [[GUARDED:%.*]], label [[EXIT:%.*]]
239
+ ; CHECK: guarded:
240
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
241
+ ; CHECK-NEXT: [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
242
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 0, [[SUB3]]
243
+ ; CHECK-NEXT: br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
244
+ ; CHECK: inner.ph:
245
+ ; CHECK-NEXT: br label [[INNER:%.*]]
246
+ ; CHECK: inner:
247
+ ; CHECK-NEXT: br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
248
+ ; CHECK: outer.inc.loopexit:
249
+ ; CHECK-NEXT: br label [[OUTER_INC]]
250
+ ; CHECK: outer.inc:
251
+ ; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
252
+ ; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[I_INC]], [[ARG]]
253
+ ; CHECK-NEXT: br i1 [[CMP4]], label [[OUTER]], label [[EXIT]]
254
+ ; CHECK: exit:
255
+ ; CHECK-NEXT: ret void
256
+ ;
257
+ entry:
258
+ br label %outer
259
+
260
+ outer:
261
+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %outer.inc ]
262
+ %sub1 = sub nsw i32 %arg , 1
263
+ %cmp1 = icmp slt i32 0 , %sub1
264
+ br i1 %cmp1 , label %guarded , label %exit
265
+
266
+ guarded:
267
+ %sub2 = sub nsw i32 %arg , %i
268
+ %sub3 = sub nsw i32 %sub2 , 1
269
+ %cmp2 = icmp slt i32 0 , %sub3
270
+ br i1 %cmp2 , label %inner.ph , label %outer.inc
271
+
272
+ inner.ph:
273
+ br label %inner
274
+
275
+ inner:
276
+ %j = phi i32 [ 0 , %inner.ph ], [ %j.inc , %inner ]
277
+ %j.inc = add nsw i32 %j , 1
278
+ %cmp3 = icmp slt i32 %j.inc , %sub3
279
+ br i1 %cmp3 , label %inner , label %outer.inc
280
+
281
+ outer.inc:
282
+ %i.inc = add nsw i32 %i , 1
283
+ %cmp4 = icmp slt i32 %i.inc , %arg
284
+ br i1 %cmp4 , label %outer , label %exit
285
+
286
+ exit:
287
+ ret void
288
+ }
289
+
290
+ define void @predicated_inside_loop_unsigned (i32 %arg ) nounwind #0 {
291
+ ; CHECK-LABEL: @predicated_inside_loop_unsigned(
292
+ ; CHECK-NEXT: entry:
293
+ ; CHECK-NEXT: br label [[OUTER:%.*]]
294
+ ; CHECK: outer:
295
+ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[OUTER_INC:%.*]] ]
296
+ ; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 [[ARG:%.*]], 1
297
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 0, [[SUB1]]
298
+ ; CHECK-NEXT: br i1 [[CMP1]], label [[GUARDED:%.*]], label [[EXIT:%.*]]
299
+ ; CHECK: guarded:
300
+ ; CHECK-NEXT: [[SUB2:%.*]] = sub nsw i32 [[ARG]], [[I]]
301
+ ; CHECK-NEXT: [[SUB3:%.*]] = sub nsw i32 [[SUB2]], 1
302
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 0, [[SUB3]]
303
+ ; CHECK-NEXT: br i1 [[CMP2]], label [[INNER_PH:%.*]], label [[OUTER_INC]]
304
+ ; CHECK: inner.ph:
305
+ ; CHECK-NEXT: br label [[INNER:%.*]]
306
+ ; CHECK: inner:
307
+ ; CHECK-NEXT: br i1 false, label [[INNER]], label [[OUTER_INC_LOOPEXIT:%.*]]
308
+ ; CHECK: outer.inc.loopexit:
309
+ ; CHECK-NEXT: br label [[OUTER_INC]]
310
+ ; CHECK: outer.inc:
311
+ ; CHECK-NEXT: [[I_INC]] = add nuw nsw i32 [[I]], 1
312
+ ; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i32 [[I_INC]], [[ARG]]
313
+ ; CHECK-NEXT: br i1 [[CMP4]], label [[OUTER]], label [[EXIT]]
314
+ ; CHECK: exit:
315
+ ; CHECK-NEXT: ret void
316
+ ;
317
+ entry:
318
+ br label %outer
319
+
320
+ outer:
321
+ %i = phi i32 [ 0 , %entry ], [ %i.inc , %outer.inc ]
322
+ %sub1 = sub nsw i32 %arg , 1
323
+ %cmp1 = icmp slt i32 0 , %sub1
324
+ br i1 %cmp1 , label %guarded , label %exit
325
+
326
+ guarded:
327
+ %sub2 = sub nsw i32 %arg , %i
328
+ %sub3 = sub nsw i32 %sub2 , 1
329
+ %cmp2 = icmp ult i32 0 , %sub3
330
+ br i1 %cmp2 , label %inner.ph , label %outer.inc
331
+
332
+ inner.ph:
333
+ br label %inner
334
+
335
+ inner:
336
+ %j = phi i32 [ 0 , %inner.ph ], [ %j.inc , %inner ]
337
+ %j.inc = add nsw i32 %j , 1
338
+ %cmp3 = icmp slt i32 %j.inc , %sub3
339
+ br i1 %cmp3 , label %inner , label %outer.inc
340
+
341
+ outer.inc:
342
+ %i.inc = add nsw i32 %i , 1
343
+ %cmp4 = icmp slt i32 %i.inc , %arg
344
+ br i1 %cmp4 , label %outer , label %exit
345
+
346
+ exit:
347
+ ret void
348
+ }
349
+
113
350
!0 = !{i32 0 , i32 2147483647 }
0 commit comments