1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -indvars %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdefine void @test1(i64 %start) { 6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1 7*9880d681SAndroid Build Coastguard Workerentry: 8*9880d681SAndroid Build Coastguard Worker br label %loop 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerloop: 11*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 12*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 13*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1 14*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 15*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 18*9880d681SAndroid Build Coastguard Worker ret void 19*9880d681SAndroid Build Coastguard Worker} 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Workerdefine void @test2(i64 %start) { 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2 23*9880d681SAndroid Build Coastguard Workerentry: 24*9880d681SAndroid Build Coastguard Worker br label %loop 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerloop: 27*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 28*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 29*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sle i64 %start, -1 30*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp sle i64 %indvars.iv, -1 31*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 34*9880d681SAndroid Build Coastguard Worker ret void 35*9880d681SAndroid Build Coastguard Worker} 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; As long as the test dominates the backedge, we're good 38*9880d681SAndroid Build Coastguard Workerdefine void @test3(i64 %start) { 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3 40*9880d681SAndroid Build Coastguard Workerentry: 41*9880d681SAndroid Build Coastguard Worker br label %loop 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerloop: 44*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 45*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 46*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 47*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %for.end 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerbackedge: 50*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 51*9880d681SAndroid Build Coastguard Worker call void @foo() 52*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1 53*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 54*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 57*9880d681SAndroid Build Coastguard Worker ret void 58*9880d681SAndroid Build Coastguard Worker} 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerdefine void @test4(i64 %start) { 61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4 62*9880d681SAndroid Build Coastguard Workerentry: 63*9880d681SAndroid Build Coastguard Worker br label %loop 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerloop: 66*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 67*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 68*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 69*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %for.end 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerbackedge: 72*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 73*9880d681SAndroid Build Coastguard Worker call void @foo() 74*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sgt i64 %start, -1 75*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp sgt i64 %indvars.iv, -1 76*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %loop, label %for.end 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 79*9880d681SAndroid Build Coastguard Worker ret void 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerdefine void @test5(i64 %start) { 83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5 84*9880d681SAndroid Build Coastguard Workerentry: 85*9880d681SAndroid Build Coastguard Worker br label %loop 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Workerloop: 88*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 89*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw i64 %indvars.iv, 1 90*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 91*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %for.end 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerbackedge: 94*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 95*9880d681SAndroid Build Coastguard Worker call void @foo() 96*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp ugt i64 %start, 100 97*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ugt i64 %indvars.iv, 100 98*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %loop, label %for.end 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 101*9880d681SAndroid Build Coastguard Worker ret void 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Workerdefine void @test6(i64 %start) { 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6 106*9880d681SAndroid Build Coastguard Workerentry: 107*9880d681SAndroid Build Coastguard Worker br label %loop 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Workerloop: 110*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 111*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nuw i64 %indvars.iv, 1 112*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 113*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %for.end 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerbackedge: 116*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 117*9880d681SAndroid Build Coastguard Worker call void @foo() 118*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp ult i64 %start, 100 119*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ult i64 %indvars.iv, 100 120*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 123*9880d681SAndroid Build Coastguard Worker ret void 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdefine void @test7(i64 %start, i64* %inc_ptr) { 127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7 128*9880d681SAndroid Build Coastguard Workerentry: 129*9880d681SAndroid Build Coastguard Worker %inc = load i64, i64* %inc_ptr, !range !0 130*9880d681SAndroid Build Coastguard Worker %ok = icmp sge i64 %inc, 0 131*9880d681SAndroid Build Coastguard Worker br i1 %ok, label %loop, label %for.end 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Workerloop: 134*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 135*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, %inc 136*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %start, -1 137*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 138*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 141*9880d681SAndroid Build Coastguard Worker ret void 142*9880d681SAndroid Build Coastguard Worker} 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker!0 = !{i64 0, i64 100} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker; Negative test - we can't show that the internal branch executes, so we can't 147*9880d681SAndroid Build Coastguard Worker; fold the test to a loop invariant one. 148*9880d681SAndroid Build Coastguard Workerdefine void @test1_neg(i64 %start) { 149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1_neg 150*9880d681SAndroid Build Coastguard Workerentry: 151*9880d681SAndroid Build Coastguard Worker br label %loop 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerloop: 154*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 155*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 156*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 157*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %skip 158*9880d681SAndroid Build Coastguard Workerskip: 159*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 160*9880d681SAndroid Build Coastguard Worker call void @foo() 161*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 162*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 163*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %backedge 164*9880d681SAndroid Build Coastguard Workerbackedge: 165*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 166*9880d681SAndroid Build Coastguard Worker call void @foo() 167*9880d681SAndroid Build Coastguard Worker br label %loop 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 170*9880d681SAndroid Build Coastguard Worker ret void 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; Slightly subtle version of @test4 where the icmp dominates the backedge, 174*9880d681SAndroid Build Coastguard Worker; but the exit branch doesn't. 175*9880d681SAndroid Build Coastguard Workerdefine void @test2_neg(i64 %start) { 176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2_neg 177*9880d681SAndroid Build Coastguard Workerentry: 178*9880d681SAndroid Build Coastguard Worker br label %loop 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Workerloop: 181*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 182*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 183*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 184*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 185*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 186*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %skip 187*9880d681SAndroid Build Coastguard Workerskip: 188*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 189*9880d681SAndroid Build Coastguard Worker call void @foo() 190*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %backedge 191*9880d681SAndroid Build Coastguard Workerbackedge: 192*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 193*9880d681SAndroid Build Coastguard Worker call void @foo() 194*9880d681SAndroid Build Coastguard Worker br label %loop 195*9880d681SAndroid Build Coastguard Worker 196*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 197*9880d681SAndroid Build Coastguard Worker ret void 198*9880d681SAndroid Build Coastguard Worker} 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker; The branch has to exit the loop if the condition is true 201*9880d681SAndroid Build Coastguard Workerdefine void @test3_neg(i64 %start) { 202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3_neg 203*9880d681SAndroid Build Coastguard Workerentry: 204*9880d681SAndroid Build Coastguard Worker br label %loop 205*9880d681SAndroid Build Coastguard Worker 206*9880d681SAndroid Build Coastguard Workerloop: 207*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 208*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 209*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 210*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 211*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %loop, label %for.end 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 214*9880d681SAndroid Build Coastguard Worker ret void 215*9880d681SAndroid Build Coastguard Worker} 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workerdefine void @test4_neg(i64 %start) { 218*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4_neg 219*9880d681SAndroid Build Coastguard Workerentry: 220*9880d681SAndroid Build Coastguard Worker br label %loop 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Workerloop: 223*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ] 224*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, 1 225*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i64 %indvars.iv.next, 25 226*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %backedge, label %for.end 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Workerbackedge: 229*9880d681SAndroid Build Coastguard Worker ; prevent flattening, needed to make sure we're testing what we intend 230*9880d681SAndroid Build Coastguard Worker call void @foo() 231*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1 232*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp sgt i64 %indvars.iv, -1 233*9880d681SAndroid Build Coastguard Worker 234*9880d681SAndroid Build Coastguard Worker; %cmp1 can be made loop invariant only if the branch below goes to 235*9880d681SAndroid Build Coastguard Worker; %the header when %cmp1 is true. 236*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 239*9880d681SAndroid Build Coastguard Worker ret void 240*9880d681SAndroid Build Coastguard Worker} 241*9880d681SAndroid Build Coastguard Worker 242*9880d681SAndroid Build Coastguard Workerdefine void @test5_neg(i64 %start, i64 %inc) { 243*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5_neg 244*9880d681SAndroid Build Coastguard Workerentry: 245*9880d681SAndroid Build Coastguard Worker br label %loop 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Workerloop: 248*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 249*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, %inc 250*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 251*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 252*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 253*9880d681SAndroid Build Coastguard Worker 254*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 255*9880d681SAndroid Build Coastguard Worker ret void 256*9880d681SAndroid Build Coastguard Worker} 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Workerdefine void @test8(i64 %start, i64* %inc_ptr) { 259*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8 260*9880d681SAndroid Build Coastguard Workerentry: 261*9880d681SAndroid Build Coastguard Worker %inc = load i64, i64* %inc_ptr, !range !1 262*9880d681SAndroid Build Coastguard Worker %ok = icmp sge i64 %inc, 0 263*9880d681SAndroid Build Coastguard Worker br i1 %ok, label %loop, label %for.end 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Workerloop: 266*9880d681SAndroid Build Coastguard Worker %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ] 267*9880d681SAndroid Build Coastguard Worker %indvars.iv.next = add nsw i64 %indvars.iv, %inc 268*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1 269*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i64 %indvars.iv, -1 270*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.end, label %loop 271*9880d681SAndroid Build Coastguard Worker 272*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %if.end, %entry 273*9880d681SAndroid Build Coastguard Worker ret void 274*9880d681SAndroid Build Coastguard Worker} 275*9880d681SAndroid Build Coastguard Worker 276*9880d681SAndroid Build Coastguard Worker!1 = !{i64 -1, i64 100} 277*9880d681SAndroid Build Coastguard Worker 278*9880d681SAndroid Build Coastguard Worker 279*9880d681SAndroid Build Coastguard Workerdeclare void @foo() 280