1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -indvars -loop-unroll -verify-loop-info | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; Unit tests for loop unrolling using ScalarEvolution to compute trip counts. 4*9880d681SAndroid Build Coastguard Worker; 5*9880d681SAndroid Build Coastguard Worker; Indvars is run first to generate an "old" SCEV result. Some unit 6*9880d681SAndroid Build Coastguard Worker; tests may check that SCEV is properly invalidated between passes. 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Completely unroll loops without a canonical IV. 9*9880d681SAndroid Build Coastguard Worker; 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @sansCanonical( 11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 12*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: icmp 13*9880d681SAndroid Build Coastguard Worker; CHECK: ret 14*9880d681SAndroid Build Coastguard Workerdefine i32 @sansCanonical(i32* %base) nounwind { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker br label %while.body 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerwhile.body: 19*9880d681SAndroid Build Coastguard Worker %iv = phi i64 [ 10, %entry ], [ %iv.next, %while.body ] 20*9880d681SAndroid Build Coastguard Worker %sum = phi i32 [ 0, %entry ], [ %sum.next, %while.body ] 21*9880d681SAndroid Build Coastguard Worker %iv.next = add i64 %iv, -1 22*9880d681SAndroid Build Coastguard Worker %adr = getelementptr inbounds i32, i32* %base, i64 %iv.next 23*9880d681SAndroid Build Coastguard Worker %tmp = load i32, i32* %adr, align 8 24*9880d681SAndroid Build Coastguard Worker %sum.next = add i32 %sum, %tmp 25*9880d681SAndroid Build Coastguard Worker %iv.narrow = trunc i64 %iv.next to i32 26*9880d681SAndroid Build Coastguard Worker %cmp.i65 = icmp sgt i32 %iv.narrow, 0 27*9880d681SAndroid Build Coastguard Worker br i1 %cmp.i65, label %while.body, label %exit 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Workerexit: 30*9880d681SAndroid Build Coastguard Worker ret i32 %sum 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; SCEV unrolling properly handles loops with multiple exits. In this 34*9880d681SAndroid Build Coastguard Worker; case, the computed trip count based on a canonical IV is *not* for a 35*9880d681SAndroid Build Coastguard Worker; latch block. Canonical unrolling incorrectly unrolls it, but SCEV 36*9880d681SAndroid Build Coastguard Worker; unrolling does not. 37*9880d681SAndroid Build Coastguard Worker; 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @earlyLoopTest( 39*9880d681SAndroid Build Coastguard Worker; CHECK: tail: 40*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br 41*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp2, label %loop, label %exit2 42*9880d681SAndroid Build Coastguard Workerdefine i64 @earlyLoopTest(i64* %base) nounwind { 43*9880d681SAndroid Build Coastguard Workerentry: 44*9880d681SAndroid Build Coastguard Worker br label %loop 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Workerloop: 47*9880d681SAndroid Build Coastguard Worker %iv = phi i64 [ 0, %entry ], [ %inc, %tail ] 48*9880d681SAndroid Build Coastguard Worker %s = phi i64 [ 0, %entry ], [ %s.next, %tail ] 49*9880d681SAndroid Build Coastguard Worker %adr = getelementptr i64, i64* %base, i64 %iv 50*9880d681SAndroid Build Coastguard Worker %val = load i64, i64* %adr 51*9880d681SAndroid Build Coastguard Worker %s.next = add i64 %s, %val 52*9880d681SAndroid Build Coastguard Worker %inc = add i64 %iv, 1 53*9880d681SAndroid Build Coastguard Worker %cmp = icmp ne i64 %inc, 4 54*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %tail, label %exit1 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workertail: 57*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp ne i64 %val, 0 58*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %loop, label %exit2 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerexit1: 61*9880d681SAndroid Build Coastguard Worker ret i64 %s 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Workerexit2: 64*9880d681SAndroid Build Coastguard Worker ret i64 %s.next 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; SCEV properly unrolls multi-exit loops. 68*9880d681SAndroid Build Coastguard Worker; 69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @multiExit( 70*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr i32, i32* %base, i32 10 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: load i32, i32* 72*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 false, label %l2.10, label %exit1 73*9880d681SAndroid Build Coastguard Worker; CHECK: l2.10: 74*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br 75*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 76*9880d681SAndroid Build Coastguard Workerdefine i32 @multiExit(i32* %base) nounwind { 77*9880d681SAndroid Build Coastguard Workerentry: 78*9880d681SAndroid Build Coastguard Worker br label %l1 79*9880d681SAndroid Build Coastguard Workerl1: 80*9880d681SAndroid Build Coastguard Worker %iv1 = phi i32 [ 0, %entry ], [ %inc1, %l2 ] 81*9880d681SAndroid Build Coastguard Worker %iv2 = phi i32 [ 0, %entry ], [ %inc2, %l2 ] 82*9880d681SAndroid Build Coastguard Worker %inc1 = add i32 %iv1, 1 83*9880d681SAndroid Build Coastguard Worker %inc2 = add i32 %iv2, 1 84*9880d681SAndroid Build Coastguard Worker %adr = getelementptr i32, i32* %base, i32 %iv1 85*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %adr 86*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 %iv1, 5 87*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %l2, label %exit1 88*9880d681SAndroid Build Coastguard Workerl2: 89*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp slt i32 %iv2, 10 90*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %l1, label %exit2 91*9880d681SAndroid Build Coastguard Workerexit1: 92*9880d681SAndroid Build Coastguard Worker ret i32 1 93*9880d681SAndroid Build Coastguard Workerexit2: 94*9880d681SAndroid Build Coastguard Worker ret i32 %val 95*9880d681SAndroid Build Coastguard Worker} 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker; SCEV should not unroll a multi-exit loops unless the latch block has 99*9880d681SAndroid Build Coastguard Worker; a known trip count, regardless of the early exit trip counts. The 100*9880d681SAndroid Build Coastguard Worker; LoopUnroll utility uses this assumption to optimize the latch 101*9880d681SAndroid Build Coastguard Worker; block's branch. 102*9880d681SAndroid Build Coastguard Worker; 103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @multiExitIncomplete( 104*9880d681SAndroid Build Coastguard Worker; CHECK: l3: 105*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br 106*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp3, label %l1, label %exit3 107*9880d681SAndroid Build Coastguard Workerdefine i32 @multiExitIncomplete(i32* %base) nounwind { 108*9880d681SAndroid Build Coastguard Workerentry: 109*9880d681SAndroid Build Coastguard Worker br label %l1 110*9880d681SAndroid Build Coastguard Workerl1: 111*9880d681SAndroid Build Coastguard Worker %iv1 = phi i32 [ 0, %entry ], [ %inc1, %l3 ] 112*9880d681SAndroid Build Coastguard Worker %iv2 = phi i32 [ 0, %entry ], [ %inc2, %l3 ] 113*9880d681SAndroid Build Coastguard Worker %inc1 = add i32 %iv1, 1 114*9880d681SAndroid Build Coastguard Worker %inc2 = add i32 %iv2, 1 115*9880d681SAndroid Build Coastguard Worker %adr = getelementptr i32, i32* %base, i32 %iv1 116*9880d681SAndroid Build Coastguard Worker %val = load i32, i32* %adr 117*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 %iv1, 5 118*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %l2, label %exit1 119*9880d681SAndroid Build Coastguard Workerl2: 120*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp slt i32 %iv2, 10 121*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %l3, label %exit2 122*9880d681SAndroid Build Coastguard Workerl3: 123*9880d681SAndroid Build Coastguard Worker %cmp3 = icmp ne i32 %val, 0 124*9880d681SAndroid Build Coastguard Worker br i1 %cmp3, label %l1, label %exit3 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerexit1: 127*9880d681SAndroid Build Coastguard Worker ret i32 1 128*9880d681SAndroid Build Coastguard Workerexit2: 129*9880d681SAndroid Build Coastguard Worker ret i32 2 130*9880d681SAndroid Build Coastguard Workerexit3: 131*9880d681SAndroid Build Coastguard Worker ret i32 3 132*9880d681SAndroid Build Coastguard Worker} 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker; When loop unroll merges a loop exit with one of its parent loop's 135*9880d681SAndroid Build Coastguard Worker; exits, SCEV must forget its ExitNotTaken info. 136*9880d681SAndroid Build Coastguard Worker; 137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nestedUnroll( 138*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br i1 139*9880d681SAndroid Build Coastguard Worker; CHECK: for.body87: 140*9880d681SAndroid Build Coastguard Workerdefine void @nestedUnroll() nounwind { 141*9880d681SAndroid Build Coastguard Workerentry: 142*9880d681SAndroid Build Coastguard Worker br label %for.inc 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Workerfor.inc: 145*9880d681SAndroid Build Coastguard Worker br i1 false, label %for.inc, label %for.body38.preheader 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Workerfor.body38.preheader: 148*9880d681SAndroid Build Coastguard Worker br label %for.body38 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Workerfor.body38: 151*9880d681SAndroid Build Coastguard Worker %i.113 = phi i32 [ %inc76, %for.inc74 ], [ 0, %for.body38.preheader ] 152*9880d681SAndroid Build Coastguard Worker %mul48 = mul nsw i32 %i.113, 6 153*9880d681SAndroid Build Coastguard Worker br label %for.body43 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workerfor.body43: 156*9880d681SAndroid Build Coastguard Worker %j.011 = phi i32 [ 0, %for.body38 ], [ %inc72, %for.body43 ] 157*9880d681SAndroid Build Coastguard Worker %add49 = add nsw i32 %j.011, %mul48 158*9880d681SAndroid Build Coastguard Worker %sh_prom50 = zext i32 %add49 to i64 159*9880d681SAndroid Build Coastguard Worker %inc72 = add nsw i32 %j.011, 1 160*9880d681SAndroid Build Coastguard Worker br i1 false, label %for.body43, label %for.inc74 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Workerfor.inc74: 163*9880d681SAndroid Build Coastguard Worker %inc76 = add nsw i32 %i.113, 1 164*9880d681SAndroid Build Coastguard Worker br i1 false, label %for.body38, label %for.body87.preheader 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Workerfor.body87.preheader: 167*9880d681SAndroid Build Coastguard Worker br label %for.body87 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerfor.body87: 170*9880d681SAndroid Build Coastguard Worker br label %for.body87 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; PR16130: clang produces incorrect code with loop/expression at -O2 174*9880d681SAndroid Build Coastguard Worker; rdar:14036816 loop-unroll makes assumptions about undefined behavior 175*9880d681SAndroid Build Coastguard Worker; 176*9880d681SAndroid Build Coastguard Worker; The loop latch is assumed to exit after the first iteration because 177*9880d681SAndroid Build Coastguard Worker; of the induction variable's NSW flag. However, the loop latch's 178*9880d681SAndroid Build Coastguard Worker; equality test is skipped and the loop exits after the second 179*9880d681SAndroid Build Coastguard Worker; iteration via the early exit. So loop unrolling cannot assume that 180*9880d681SAndroid Build Coastguard Worker; the loop latch's exit count of zero is an upper bound on the number 181*9880d681SAndroid Build Coastguard Worker; of iterations. 182*9880d681SAndroid Build Coastguard Worker; 183*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nsw_latch( 184*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 185*9880d681SAndroid Build Coastguard Worker; CHECK: %b.03 = phi i32 [ 0, %entry ], [ %add, %for.cond ] 186*9880d681SAndroid Build Coastguard Worker; CHECK: return: 187*9880d681SAndroid Build Coastguard Worker; CHECK: %b.03.lcssa = phi i32 [ %b.03, %for.body ], [ %b.03, %for.cond ] 188*9880d681SAndroid Build Coastguard Workerdefine void @nsw_latch(i32* %a) nounwind { 189*9880d681SAndroid Build Coastguard Workerentry: 190*9880d681SAndroid Build Coastguard Worker br label %for.body 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %for.cond, %entry 193*9880d681SAndroid Build Coastguard Worker %b.03 = phi i32 [ 0, %entry ], [ %add, %for.cond ] 194*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %b.03, 0 195*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %b.03, 8 196*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %for.cond, label %return 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerfor.cond: ; preds = %for.body 199*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %add, 13 200*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %return, label %for.body 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Workerreturn: ; preds = %for.body, %for.cond 203*9880d681SAndroid Build Coastguard Worker %b.03.lcssa = phi i32 [ %b.03, %for.body ], [ %b.03, %for.cond ] 204*9880d681SAndroid Build Coastguard Worker %retval.0 = phi i32 [ 1, %for.body ], [ 0, %for.cond ] 205*9880d681SAndroid Build Coastguard Worker store i32 %b.03.lcssa, i32* %a, align 4 206*9880d681SAndroid Build Coastguard Worker ret void 207*9880d681SAndroid Build Coastguard Worker} 208