@@ -154,3 +154,350 @@ exit: ; preds = %bb2, %bb1, %bb0
154
154
%result = phi i1 [ %0 , %bb0 ], [ %1 , %bb1 ], [ %2 , %bb2 ]
155
155
ret i1 %result
156
156
}
157
+
158
+ declare void @foo ()
159
+
160
+ define i1 @test_icmp_simple (i1 %c , i32 %a , i32 %b ) {
161
+ ; CHECK-LABEL: @test_icmp_simple(
162
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
163
+ ; CHECK: common.ret:
164
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[CMP1:%.*]], [[IF]] ], [ [[CMP2:%.*]], [[ELSE]] ]
165
+ ; CHECK-NEXT: ret i1 [[COMMON_RET_OP]]
166
+ ; CHECK: if:
167
+ ; CHECK-NEXT: [[CMP1]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
168
+ ; CHECK-NEXT: call void @foo()
169
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
170
+ ; CHECK: else:
171
+ ; CHECK-NEXT: [[CMP2]] = icmp ugt i32 [[B]], [[A]]
172
+ ; CHECK-NEXT: call void @bar()
173
+ ; CHECK-NEXT: br label [[COMMON_RET]]
174
+ ;
175
+ br i1 %c , label %if , label %else
176
+
177
+ if:
178
+ %cmp1 = icmp ult i32 %a , %b
179
+ call void @foo ()
180
+ ret i1 %cmp1
181
+
182
+ else:
183
+ %cmp2 = icmp ugt i32 %b , %a
184
+ call void @bar ()
185
+ ret i1 %cmp2
186
+ }
187
+
188
+ define void @test_icmp_complex (i1 %c , i32 %a , i32 %b ) {
189
+ ; CHECK-LABEL: @test_icmp_complex(
190
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
191
+ ; CHECK: if:
192
+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
193
+ ; CHECK-NEXT: br i1 [[CMP1]], label [[IF2:%.*]], label [[ELSE2:%.*]]
194
+ ; CHECK: else:
195
+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[B]], [[A]]
196
+ ; CHECK-NEXT: br i1 [[CMP2]], label [[IF2]], label [[ELSE2]]
197
+ ; CHECK: common.ret:
198
+ ; CHECK-NEXT: ret void
199
+ ; CHECK: if2:
200
+ ; CHECK-NEXT: call void @foo()
201
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
202
+ ; CHECK: else2:
203
+ ; CHECK-NEXT: call void @bar()
204
+ ; CHECK-NEXT: br label [[COMMON_RET]]
205
+ ;
206
+ br i1 %c , label %if , label %else
207
+
208
+ if:
209
+ %cmp1 = icmp ult i32 %a , %b
210
+ br i1 %cmp1 , label %if2 , label %else2
211
+
212
+ else:
213
+ %cmp2 = icmp ugt i32 %b , %a
214
+ br i1 %cmp2 , label %if2 , label %else2
215
+
216
+ if2:
217
+ call void @foo ()
218
+ ret void
219
+
220
+ else2:
221
+ call void @bar ()
222
+ ret void
223
+ }
224
+
225
+ define i1 @test_icmp_wrong_operands (i1 %c , i32 %a , i32 %b ) {
226
+ ; CHECK-LABEL: @test_icmp_wrong_operands(
227
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
228
+ ; CHECK: common.ret:
229
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[CMP1:%.*]], [[IF]] ], [ [[CMP2:%.*]], [[ELSE]] ]
230
+ ; CHECK-NEXT: ret i1 [[COMMON_RET_OP]]
231
+ ; CHECK: if:
232
+ ; CHECK-NEXT: [[CMP1]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
233
+ ; CHECK-NEXT: call void @foo()
234
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
235
+ ; CHECK: else:
236
+ ; CHECK-NEXT: [[CMP2]] = icmp ugt i32 [[A]], [[B]]
237
+ ; CHECK-NEXT: call void @bar()
238
+ ; CHECK-NEXT: br label [[COMMON_RET]]
239
+ ;
240
+ br i1 %c , label %if , label %else
241
+
242
+ if:
243
+ %cmp1 = icmp ult i32 %a , %b
244
+ call void @foo ()
245
+ ret i1 %cmp1
246
+
247
+ else:
248
+ %cmp2 = icmp ugt i32 %a , %b
249
+ call void @bar ()
250
+ ret i1 %cmp2
251
+ }
252
+
253
+ define i1 @test_icmp_wrong_pred (i1 %c , i32 %a , i32 %b ) {
254
+ ; CHECK-LABEL: @test_icmp_wrong_pred(
255
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
256
+ ; CHECK: common.ret:
257
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ [[CMP1:%.*]], [[IF]] ], [ [[CMP2:%.*]], [[ELSE]] ]
258
+ ; CHECK-NEXT: ret i1 [[COMMON_RET_OP]]
259
+ ; CHECK: if:
260
+ ; CHECK-NEXT: [[CMP1]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
261
+ ; CHECK-NEXT: call void @foo()
262
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
263
+ ; CHECK: else:
264
+ ; CHECK-NEXT: [[CMP2]] = icmp uge i32 [[B]], [[A]]
265
+ ; CHECK-NEXT: call void @bar()
266
+ ; CHECK-NEXT: br label [[COMMON_RET]]
267
+ ;
268
+ br i1 %c , label %if , label %else
269
+
270
+ if:
271
+ %cmp1 = icmp ult i32 %a , %b
272
+ call void @foo ()
273
+ ret i1 %cmp1
274
+
275
+ else:
276
+ %cmp2 = icmp uge i32 %b , %a
277
+ call void @bar ()
278
+ ret i1 %cmp2
279
+ }
280
+
281
+ define i32 @test_binop (i1 %c , i32 %a , i32 %b ) {
282
+ ; CHECK-LABEL: @test_binop(
283
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
284
+ ; CHECK: common.ret:
285
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
286
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
287
+ ; CHECK: if:
288
+ ; CHECK-NEXT: [[OP1]] = add i32 [[A:%.*]], [[B:%.*]]
289
+ ; CHECK-NEXT: call void @foo()
290
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
291
+ ; CHECK: else:
292
+ ; CHECK-NEXT: [[OP2]] = add i32 [[B]], [[A]]
293
+ ; CHECK-NEXT: call void @bar()
294
+ ; CHECK-NEXT: br label [[COMMON_RET]]
295
+ ;
296
+ br i1 %c , label %if , label %else
297
+
298
+ if:
299
+ %op1 = add i32 %a , %b
300
+ call void @foo ()
301
+ ret i32 %op1
302
+
303
+ else:
304
+ %op2 = add i32 %b , %a
305
+ call void @bar ()
306
+ ret i32 %op2
307
+ }
308
+
309
+ define i32 @test_binop_flags (i1 %c , i32 %a , i32 %b ) {
310
+ ; CHECK-LABEL: @test_binop_flags(
311
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
312
+ ; CHECK: common.ret:
313
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
314
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
315
+ ; CHECK: if:
316
+ ; CHECK-NEXT: [[OP1]] = add nuw nsw i32 [[A:%.*]], [[B:%.*]]
317
+ ; CHECK-NEXT: call void @foo()
318
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
319
+ ; CHECK: else:
320
+ ; CHECK-NEXT: [[OP2]] = add nsw i32 [[B]], [[A]]
321
+ ; CHECK-NEXT: call void @bar()
322
+ ; CHECK-NEXT: br label [[COMMON_RET]]
323
+ ;
324
+ br i1 %c , label %if , label %else
325
+
326
+ if:
327
+ %op1 = add nuw nsw i32 %a , %b
328
+ call void @foo ()
329
+ ret i32 %op1
330
+
331
+ else:
332
+ %op2 = add nsw i32 %b , %a
333
+ call void @bar ()
334
+ ret i32 %op2
335
+ }
336
+
337
+ define i32 @test_binop_not_commutative (i1 %c , i32 %a , i32 %b ) {
338
+ ; CHECK-LABEL: @test_binop_not_commutative(
339
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
340
+ ; CHECK: common.ret:
341
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
342
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
343
+ ; CHECK: if:
344
+ ; CHECK-NEXT: [[OP1]] = sub i32 [[A:%.*]], [[B:%.*]]
345
+ ; CHECK-NEXT: call void @foo()
346
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
347
+ ; CHECK: else:
348
+ ; CHECK-NEXT: [[OP2]] = sub i32 [[B]], [[A]]
349
+ ; CHECK-NEXT: call void @bar()
350
+ ; CHECK-NEXT: br label [[COMMON_RET]]
351
+ ;
352
+ br i1 %c , label %if , label %else
353
+
354
+ if:
355
+ %op1 = sub i32 %a , %b
356
+ call void @foo ()
357
+ ret i32 %op1
358
+
359
+ else:
360
+ %op2 = sub i32 %b , %a
361
+ call void @bar ()
362
+ ret i32 %op2
363
+ }
364
+
365
+ define i32 @test_binop_wrong_ops (i1 %c , i32 %a , i32 %b , i32 %d ) {
366
+ ; CHECK-LABEL: @test_binop_wrong_ops(
367
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
368
+ ; CHECK: common.ret:
369
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
370
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
371
+ ; CHECK: if:
372
+ ; CHECK-NEXT: [[OP1]] = add i32 [[A:%.*]], [[B:%.*]]
373
+ ; CHECK-NEXT: call void @foo()
374
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
375
+ ; CHECK: else:
376
+ ; CHECK-NEXT: [[OP2]] = add i32 [[B]], [[D:%.*]]
377
+ ; CHECK-NEXT: call void @bar()
378
+ ; CHECK-NEXT: br label [[COMMON_RET]]
379
+ ;
380
+ br i1 %c , label %if , label %else
381
+
382
+ if:
383
+ %op1 = add i32 %a , %b
384
+ call void @foo ()
385
+ ret i32 %op1
386
+
387
+ else:
388
+ %op2 = add i32 %b , %d
389
+ call void @bar ()
390
+ ret i32 %op2
391
+ }
392
+
393
+ define i32 @test_intrin (i1 %c , i32 %a , i32 %b ) {
394
+ ; CHECK-LABEL: @test_intrin(
395
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
396
+ ; CHECK: common.ret:
397
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
398
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
399
+ ; CHECK: if:
400
+ ; CHECK-NEXT: [[OP1]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 [[B:%.*]])
401
+ ; CHECK-NEXT: call void @foo()
402
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
403
+ ; CHECK: else:
404
+ ; CHECK-NEXT: [[OP2]] = call i32 @llvm.umin.i32(i32 [[B]], i32 [[A]])
405
+ ; CHECK-NEXT: call void @bar()
406
+ ; CHECK-NEXT: br label [[COMMON_RET]]
407
+ ;
408
+ br i1 %c , label %if , label %else
409
+
410
+ if:
411
+ %op1 = call i32 @llvm.umin (i32 %a , i32 %b )
412
+ call void @foo ()
413
+ ret i32 %op1
414
+
415
+ else:
416
+ %op2 = call i32 @llvm.umin (i32 %b , i32 %a )
417
+ call void @bar ()
418
+ ret i32 %op2
419
+ }
420
+
421
+ define i32 @test_intrin_not_same (i1 %c , i32 %a , i32 %b ) {
422
+ ; CHECK-LABEL: @test_intrin_not_same(
423
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
424
+ ; CHECK: common.ret:
425
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
426
+ ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]]
427
+ ; CHECK: if:
428
+ ; CHECK-NEXT: [[OP1]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 [[B:%.*]])
429
+ ; CHECK-NEXT: call void @foo()
430
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
431
+ ; CHECK: else:
432
+ ; CHECK-NEXT: [[OP2]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[A]])
433
+ ; CHECK-NEXT: call void @bar()
434
+ ; CHECK-NEXT: br label [[COMMON_RET]]
435
+ ;
436
+ br i1 %c , label %if , label %else
437
+
438
+ if:
439
+ %op1 = call i32 @llvm.umin (i32 %a , i32 %b )
440
+ call void @foo ()
441
+ ret i32 %op1
442
+
443
+ else:
444
+ %op2 = call i32 @llvm.umax (i32 %b , i32 %a )
445
+ call void @bar ()
446
+ ret i32 %op2
447
+ }
448
+
449
+ define float @test_intrin_3arg (i1 %c , float %a , float %b , float %d ) {
450
+ ; CHECK-LABEL: @test_intrin_3arg(
451
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
452
+ ; CHECK: common.ret:
453
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
454
+ ; CHECK-NEXT: ret float [[COMMON_RET_OP]]
455
+ ; CHECK: if:
456
+ ; CHECK-NEXT: [[OP1]] = call float @llvm.fma.f32(float [[A:%.*]], float [[B:%.*]], float [[D:%.*]])
457
+ ; CHECK-NEXT: call void @foo()
458
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
459
+ ; CHECK: else:
460
+ ; CHECK-NEXT: [[OP2]] = call float @llvm.fma.f32(float [[B]], float [[A]], float [[D]])
461
+ ; CHECK-NEXT: call void @bar()
462
+ ; CHECK-NEXT: br label [[COMMON_RET]]
463
+ ;
464
+ br i1 %c , label %if , label %else
465
+
466
+ if:
467
+ %op1 = call float @llvm.fma (float %a , float %b , float %d )
468
+ call void @foo ()
469
+ ret float %op1
470
+
471
+ else:
472
+ %op2 = call float @llvm.fma (float %b , float %a , float %d )
473
+ call void @bar ()
474
+ ret float %op2
475
+ }
476
+
477
+ define float @test_intrin_3arg_wrong_args_commuted (i1 %c , float %a , float %b , float %d ) {
478
+ ; CHECK-LABEL: @test_intrin_3arg_wrong_args_commuted(
479
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
480
+ ; CHECK: common.ret:
481
+ ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi float [ [[OP1:%.*]], [[IF]] ], [ [[OP2:%.*]], [[ELSE]] ]
482
+ ; CHECK-NEXT: ret float [[COMMON_RET_OP]]
483
+ ; CHECK: if:
484
+ ; CHECK-NEXT: [[OP1]] = call float @llvm.fma.f32(float [[A:%.*]], float [[B:%.*]], float [[D:%.*]])
485
+ ; CHECK-NEXT: call void @foo()
486
+ ; CHECK-NEXT: br label [[COMMON_RET:%.*]]
487
+ ; CHECK: else:
488
+ ; CHECK-NEXT: [[OP2]] = call float @llvm.fma.f32(float [[A]], float [[D]], float [[B]])
489
+ ; CHECK-NEXT: call void @bar()
490
+ ; CHECK-NEXT: br label [[COMMON_RET]]
491
+ ;
492
+ br i1 %c , label %if , label %else
493
+
494
+ if:
495
+ %op1 = call float @llvm.fma (float %a , float %b , float %d )
496
+ call void @foo ()
497
+ ret float %op1
498
+
499
+ else:
500
+ %op2 = call float @llvm.fma (float %a , float %d , float %b )
501
+ call void @bar ()
502
+ ret float %op2
503
+ }
0 commit comments