@@ -468,4 +468,104 @@ exit:
468
468
ret void
469
469
}
470
470
471
+ define void @test_can_predicate_simple_unsigned (i32* %p , i32* %arr ) {
472
+ ; CHECK-LABEL: @test_can_predicate_simple_unsigned(
473
+ ; CHECK-NEXT: preheader:
474
+ ; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[P:%.*]], align 4
475
+ ; CHECK-NEXT: br label [[LOOP:%.*]]
476
+ ; CHECK: loop:
477
+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[PREHEADER:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
478
+ ; CHECK-NEXT: [[ZERO_COND:%.*]] = icmp eq i32 [[IV]], 0
479
+ ; CHECK-NEXT: br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
480
+ ; CHECK: range_check_block:
481
+ ; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], 1
482
+ ; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[LEN]]
483
+ ; CHECK-NEXT: br i1 [[RANGE_CHECK]], label [[BACKEDGE]], label [[FAIL:%.*]]
484
+ ; CHECK: backedge:
485
+ ; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, i32* [[P]], i32 [[IV]]
486
+ ; CHECK-NEXT: [[EL:%.*]] = load i32, i32* [[EL_PTR]], align 4
487
+ ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i32 [[EL]], 0
488
+ ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT]]
489
+ ; CHECK: exit:
490
+ ; CHECK-NEXT: ret void
491
+ ; CHECK: fail:
492
+ ; CHECK-NEXT: unreachable
493
+ ;
494
+ preheader:
495
+ %len = load i32 , i32* %p
496
+ br label %loop
497
+
498
+ loop:
499
+ %iv = phi i32 [%len , %preheader ], [%iv.next , %backedge ]
500
+ %zero_cond = icmp eq i32 %iv , 0
501
+ br i1 %zero_cond , label %exit , label %range_check_block
502
+
503
+ range_check_block:
504
+ %iv.next = sub i32 %iv , 1
505
+ %range_check = icmp ult i32 %iv.next , %len
506
+ br i1 %range_check , label %backedge , label %fail
507
+
508
+ backedge:
509
+ %el.ptr = getelementptr i32 , i32* %p , i32 %iv
510
+ %el = load i32 , i32* %el.ptr
511
+ %loop.cond = icmp eq i32 %el , 0
512
+ br i1 %loop.cond , label %loop , label %exit
513
+
514
+ exit:
515
+ ret void
516
+
517
+ fail:
518
+ unreachable
519
+ }
520
+
521
+ define void @test_can_predicate_simple_signed (i32* %p , i32* %arr ) {
522
+ ; CHECK-LABEL: @test_can_predicate_simple_signed(
523
+ ; CHECK-NEXT: preheader:
524
+ ; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[P:%.*]], align 4
525
+ ; CHECK-NEXT: br label [[LOOP:%.*]]
526
+ ; CHECK: loop:
527
+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[PREHEADER:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
528
+ ; CHECK-NEXT: [[ZERO_COND:%.*]] = icmp eq i32 [[IV]], 0
529
+ ; CHECK-NEXT: br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
530
+ ; CHECK: range_check_block:
531
+ ; CHECK-NEXT: [[IV_NEXT]] = sub i32 [[IV]], 1
532
+ ; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV_NEXT]], [[LEN]]
533
+ ; CHECK-NEXT: br i1 [[RANGE_CHECK]], label [[BACKEDGE]], label [[FAIL:%.*]]
534
+ ; CHECK: backedge:
535
+ ; CHECK-NEXT: [[EL_PTR:%.*]] = getelementptr i32, i32* [[P]], i32 [[IV]]
536
+ ; CHECK-NEXT: [[EL:%.*]] = load i32, i32* [[EL_PTR]], align 4
537
+ ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i32 [[EL]], 0
538
+ ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT]]
539
+ ; CHECK: exit:
540
+ ; CHECK-NEXT: ret void
541
+ ; CHECK: fail:
542
+ ; CHECK-NEXT: unreachable
543
+ ;
544
+ preheader:
545
+ %len = load i32 , i32* %p
546
+ br label %loop
547
+
548
+ loop:
549
+ %iv = phi i32 [%len , %preheader ], [%iv.next , %backedge ]
550
+ %zero_cond = icmp eq i32 %iv , 0
551
+ br i1 %zero_cond , label %exit , label %range_check_block
552
+
553
+ range_check_block:
554
+ %iv.next = sub i32 %iv , 1
555
+ %range_check = icmp slt i32 %iv.next , %len
556
+ br i1 %range_check , label %backedge , label %fail
557
+
558
+ backedge:
559
+ %el.ptr = getelementptr i32 , i32* %p , i32 %iv
560
+ %el = load i32 , i32* %el.ptr
561
+ %loop.cond = icmp eq i32 %el , 0
562
+ br i1 %loop.cond , label %loop , label %exit
563
+
564
+ exit:
565
+ ret void
566
+
567
+ fail:
568
+ unreachable
569
+ }
570
+
471
571
!0 = !{i32 0 , i32 2147483647 }
0 commit comments