1 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -unroll-count=4 -verify-dom-info -S | FileCheck %s 2 3 ; REQUIRES: asserts 4 ; The tests below are for verifying dom tree after runtime unrolling 5 ; with multiple exit/exiting blocks. 6 7 ; We explicitly set the unroll count so that expensiveTripCount computation is allowed. 8 9 ; mergedexit block has edges from loop exit blocks. 10 define i64 @test1() { 11 ; CHECK-LABEL: test1( 12 ; CHECK-LABEL: headerexit: 13 ; CHECK-NEXT: %addphi = phi i64 [ %add.iv, %header ], [ %add.iv.1, %header.1 ], [ %add.iv.2, %header.2 ], [ %add.iv.3, %header.3 ] 14 ; CHECK-NEXT: br label %mergedexit 15 ; CHECK-LABEL: latchexit: 16 ; CHECK-NEXT: %shftphi = phi i64 [ %shft, %latch ], [ %shft.1, %latch.1 ], [ %shft.2, %latch.2 ], [ %shft.3, %latch.3 ] 17 ; CHECK-NEXT: br label %mergedexit 18 ; CHECK-LABEL: mergedexit: 19 ; CHECK-NEXT: %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ] 20 ; CHECK-NEXT: ret i64 %retval 21 entry: 22 br label %preheader 23 24 preheader: ; preds = %bb 25 %trip = zext i32 undef to i64 26 br label %header 27 28 header: ; preds = %latch, %preheader 29 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 30 %add.iv = add nuw nsw i64 %iv, 2 31 %cmp1 = icmp ult i64 %add.iv, %trip 32 br i1 %cmp1, label %latch, label %headerexit 33 34 latch: ; preds = %header 35 %shft = ashr i64 %add.iv, 1 36 %cmp2 = icmp ult i64 %shft, %trip 37 br i1 %cmp2, label %header, label %latchexit 38 39 headerexit: ; preds = %header 40 %addphi = phi i64 [ %add.iv, %header ] 41 br label %mergedexit 42 43 latchexit: ; preds = %latch 44 %shftphi = phi i64 [ %shft, %latch ] 45 br label %mergedexit 46 47 mergedexit: ; preds = %latchexit, %headerexit 48 %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ] 49 ret i64 %retval 50 } 51 52 ; mergedexit has edges from loop exit blocks and a block outside the loop. 53 define void @test2(i1 %cond, i32 %n) { 54 ; CHECK-LABEL: header.1: 55 ; CHECK-NEXT: %add.iv.1 = add nuw nsw i64 %add.iv, 2 56 ; CHECK: br i1 %cmp1.1, label %latch.1, label %headerexit 57 ; CHECK-LABEL: latch.3: 58 ; CHECK: %cmp2.3 = icmp ult i64 %shft.3, %trip 59 ; CHECK-NEXT: br i1 %cmp2.3, label %header, label %latchexit, !llvm.loop 60 entry: 61 br i1 %cond, label %preheader, label %mergedexit 62 63 preheader: ; preds = %entry 64 %trip = zext i32 %n to i64 65 br label %header 66 67 header: ; preds = %latch, %preheader 68 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 69 %add.iv = add nuw nsw i64 %iv, 2 70 %cmp1 = icmp ult i64 %add.iv, %trip 71 br i1 %cmp1, label %latch, label %headerexit 72 73 latch: ; preds = %header 74 %shft = ashr i64 %add.iv, 1 75 %cmp2 = icmp ult i64 %shft, %trip 76 br i1 %cmp2, label %header, label %latchexit 77 78 headerexit: ; preds = %header 79 br label %mergedexit 80 81 latchexit: ; preds = %latch 82 br label %mergedexit 83 84 mergedexit: ; preds = %latchexit, %headerexit, %entry 85 ret void 86 } 87 88 89 ; exitsucc is from loop exit block only. 90 define i64 @test3(i32 %n) { 91 ; CHECK-LABEL: test3( 92 ; CHECK-LABEL: headerexit: 93 ; CHECK-NEXT: br label %exitsucc 94 ; CHECK-LABEL: latchexit: 95 ; CHECK-NEXT: %shftphi = phi i64 [ %shft, %latch ], [ %shft.1, %latch.1 ], [ %shft.2, %latch.2 ], [ %shft.3, %latch.3 ] 96 ; CHECK-NEXT: ret i64 %shftphi 97 ; CHECK-LABEL: exitsucc: 98 ; CHECK-NEXT: ret i64 96 99 entry: 100 br label %preheader 101 102 preheader: ; preds = %bb 103 %trip = zext i32 %n to i64 104 br label %header 105 106 header: ; preds = %latch, %preheader 107 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 108 %add.iv = add nuw nsw i64 %iv, 2 109 %cmp1 = icmp ult i64 %add.iv, %trip 110 br i1 %cmp1, label %latch, label %headerexit 111 112 latch: ; preds = %header 113 %shft = ashr i64 %add.iv, 1 114 %cmp2 = icmp ult i64 %shft, %trip 115 br i1 %cmp2, label %header, label %latchexit 116 117 headerexit: ; preds = %header 118 br label %exitsucc 119 120 latchexit: ; preds = %latch 121 %shftphi = phi i64 [ %shft, %latch ] 122 ret i64 %shftphi 123 124 exitsucc: ; preds = %headerexit 125 ret i64 96 126 } 127