1*9880d681SAndroid Build Coastguard Worker; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdefine void @f0(i1 %c) { 4*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f0 5*9880d681SAndroid Build Coastguard Workerentry: 6*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 7*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -1, i32 1 8*9880d681SAndroid Build Coastguard Worker br label %loop 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerloop: 11*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] 12*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 13*9880d681SAndroid Build Coastguard Worker; CHECK: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128) 15*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 16*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i32 %loop.iv, 1 17*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i32 %loop.iv.inc, 128 18*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerleave: 21*9880d681SAndroid Build Coastguard Worker ret void 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine void @f1(i1 %c) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f1 26*9880d681SAndroid Build Coastguard Workerentry: 27*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 120, i32 0 28*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -8, i32 8 29*9880d681SAndroid Build Coastguard Worker br label %loop 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Workerloop: 32*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] 33*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.1 = add i32 %iv, 1 36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(1 + %start)<nuw><nsw>,+,%step}<%loop> U: [1,122) S: [1,122) 37*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.2 = add i32 %iv, 2 38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(2 + %start)<nuw><nsw>,+,%step}<%loop> U: [2,123) S: [2,123) 39*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.3 = add i32 %iv, 3 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(3 + %start)<nuw><nsw>,+,%step}<%loop> U: [3,124) S: [3,124) 41*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.4 = add i32 %iv, 4 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(4 + %start)<nuw><nsw>,+,%step}<%loop> U: [4,125) S: [4,125) 43*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.5 = add i32 %iv, 5 44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(5 + %start)<nuw><nsw>,+,%step}<%loop> U: [5,126) S: [5,126) 45*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.6 = add i32 %iv, 6 46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(6 + %start)<nuw><nsw>,+,%step}<%loop> U: [6,127) S: [6,127) 47*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.7 = add i32 %iv, 7 48*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(7 + %start)<nuw><nsw>,+,%step}<%loop> U: [7,128) S: [7,128) 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker %iv.1 = add i32 %iv, 1 51*9880d681SAndroid Build Coastguard Worker %iv.2 = add i32 %iv, 2 52*9880d681SAndroid Build Coastguard Worker %iv.3 = add i32 %iv, 3 53*9880d681SAndroid Build Coastguard Worker %iv.4 = add i32 %iv, 4 54*9880d681SAndroid Build Coastguard Worker %iv.5 = add i32 %iv, 5 55*9880d681SAndroid Build Coastguard Worker %iv.6 = add i32 %iv, 6 56*9880d681SAndroid Build Coastguard Worker %iv.7 = add i32 %iv, 7 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m1 = sub i32 %iv, 1 59*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-1 + %start)<nsw>,+,%step}<%loop> U: [-1,120) S: [-1,120) 60*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m2 = sub i32 %iv, 2 61*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-2 + %start)<nsw>,+,%step}<%loop> U: [-2,119) S: [-2,119) 62*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m3 = sub i32 %iv, 3 63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-3 + %start)<nsw>,+,%step}<%loop> U: [-3,118) S: [-3,118) 64*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m4 = sub i32 %iv, 4 65*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-4 + %start)<nsw>,+,%step}<%loop> U: [-4,117) S: [-4,117) 66*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m5 = sub i32 %iv, 5 67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-5 + %start)<nsw>,+,%step}<%loop> U: [-5,116) S: [-5,116) 68*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m6 = sub i32 %iv, 6 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-6 + %start)<nsw>,+,%step}<%loop> U: [-6,115) S: [-6,115) 70*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.m7 = sub i32 %iv, 7 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(-7 + %start)<nsw>,+,%step}<%loop> U: [-7,114) S: [-7,114) 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker %iv.m1 = sub i32 %iv, 1 74*9880d681SAndroid Build Coastguard Worker %iv.m2 = sub i32 %iv, 2 75*9880d681SAndroid Build Coastguard Worker %iv.m3 = sub i32 %iv, 3 76*9880d681SAndroid Build Coastguard Worker %iv.m4 = sub i32 %iv, 4 77*9880d681SAndroid Build Coastguard Worker %iv.m5 = sub i32 %iv, 5 78*9880d681SAndroid Build Coastguard Worker %iv.m6 = sub i32 %iv, 6 79*9880d681SAndroid Build Coastguard Worker %iv.m7 = sub i32 %iv, 7 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 82*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i32 %loop.iv, 1 83*9880d681SAndroid Build Coastguard Worker %be.cond = icmp sgt i32 %loop.iv, 14 84*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %leave, label %loop 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerleave: 87*9880d681SAndroid Build Coastguard Worker ret void 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Workerdefine void @f2(i1 %c) { 91*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f2 92*9880d681SAndroid Build Coastguard Workerentry: 93*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 94*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -1, i32 1 95*9880d681SAndroid Build Coastguard Worker br label %loop 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Workerloop: 98*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] 99*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 100*9880d681SAndroid Build Coastguard Worker %iv.sext = sext i32 %iv to i64 101*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 102*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.sext = sext i32 %iv to i64 103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(sext i32 %start to i64),+,(sext i32 %step to i64)}<nsw><%loop> U: [0,128) S: [0,128) 104*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i32 %loop.iv, 1 105*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i32 %loop.iv.inc, 128 106*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerleave: 109*9880d681SAndroid Build Coastguard Worker ret void 110*9880d681SAndroid Build Coastguard Worker} 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Workerdefine void @f3(i1 %c) { 113*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f3 114*9880d681SAndroid Build Coastguard Workerentry: 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker; NB! the i16 type (as opposed to i32), the choice of the constant 509 117*9880d681SAndroid Build Coastguard Worker; and the trip count are all related and not arbitrary. We want an 118*9880d681SAndroid Build Coastguard Worker; add recurrence that will look like it can unsign-overflow *unless* 119*9880d681SAndroid Build Coastguard Worker; SCEV is able to see the correlation between the two selects feeding 120*9880d681SAndroid Build Coastguard Worker; into the initial value and the step increment. 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i16 1000, i16 0 123*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i16 1, i16 509 124*9880d681SAndroid Build Coastguard Worker br label %loop 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerloop: 127*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] 128*9880d681SAndroid Build Coastguard Worker %iv = phi i16 [ %start, %entry ], [ %iv.next, %loop ] 129*9880d681SAndroid Build Coastguard Worker %iv.zext = zext i16 %iv to i64 130*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.zext = zext i16 %iv to i64 131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(zext i16 %start to i64),+,(zext i16 %step to i64)}<nuw><%loop> U: [0,64644) S: [0,64644) 132*9880d681SAndroid Build Coastguard Worker %iv.next = add i16 %iv, %step 133*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i16 %loop.iv, 1 134*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i16 %loop.iv.inc, 128 135*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workerleave: 138*9880d681SAndroid Build Coastguard Worker ret void 139*9880d681SAndroid Build Coastguard Worker} 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Workerdefine void @f4(i1 %c) { 142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f4 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker; @f4() demonstrates a case where SCEV is not able to compute a 145*9880d681SAndroid Build Coastguard Worker; precise range for %iv.trunc, though it should be able to, in theory. 146*9880d681SAndroid Build Coastguard Worker; This is because SCEV looks into affine add recurrences only when the 147*9880d681SAndroid Build Coastguard Worker; backedge taken count of the loop has the same bitwidth as the 148*9880d681SAndroid Build Coastguard Worker; induction variable. 149*9880d681SAndroid Build Coastguard Workerentry: 150*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 151*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -1, i32 1 152*9880d681SAndroid Build Coastguard Worker br label %loop 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Workerloop: 155*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ] 156*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 157*9880d681SAndroid Build Coastguard Worker %iv.trunc = trunc i32 %iv to i16 158*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.trunc = trunc i32 %iv to i16 159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: full-set S: full-set 160*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 161*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i32 %loop.iv, 1 162*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i32 %loop.iv.inc, 128 163*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerleave: 166*9880d681SAndroid Build Coastguard Worker ret void 167*9880d681SAndroid Build Coastguard Worker} 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Workerdefine void @f5(i1 %c) { 170*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f5 171*9880d681SAndroid Build Coastguard Workerentry: 172*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 173*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -1, i32 1 174*9880d681SAndroid Build Coastguard Worker br label %loop 175*9880d681SAndroid Build Coastguard Worker 176*9880d681SAndroid Build Coastguard Workerloop: 177*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] 178*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 179*9880d681SAndroid Build Coastguard Worker %iv.trunc = trunc i32 %iv to i16 180*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.trunc = trunc i32 %iv to i16 181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128) 182*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i16 %loop.iv, 1 185*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i16 %loop.iv.inc, 128 186*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Workerleave: 189*9880d681SAndroid Build Coastguard Worker ret void 190*9880d681SAndroid Build Coastguard Worker} 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Workerdefine void @f6(i1 %c) { 193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f6 194*9880d681SAndroid Build Coastguard Workerentry: 195*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 196*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -2, i32 0 197*9880d681SAndroid Build Coastguard Worker br label %loop 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Workerloop: 200*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] 201*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 202*9880d681SAndroid Build Coastguard Worker; CHECK: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 203*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {%start,+,(1 + %step)<nuw><nsw>}<%loop> U: [0,128) S: [0,128) 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker %step.plus.one = add i32 %step, 1 206*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step.plus.one 207*9880d681SAndroid Build Coastguard Worker %iv.sext = sext i32 %iv to i64 208*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.sext = sext i32 %iv to i64 209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(sext i32 %start to i64),+,(1 + (sext i32 %step to i64))<nsw>}<nsw><%loop> U: [0,128) S: [0,128) 210*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i16 %loop.iv, 1 211*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i16 %loop.iv.inc, 128 212*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Workerleave: 215*9880d681SAndroid Build Coastguard Worker ret void 216*9880d681SAndroid Build Coastguard Worker} 217*9880d681SAndroid Build Coastguard Worker 218*9880d681SAndroid Build Coastguard Workerdefine void @f7(i1 %c) { 219*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: Classifying expressions for: @f7 220*9880d681SAndroid Build Coastguard Workerentry: 221*9880d681SAndroid Build Coastguard Worker %start = select i1 %c, i32 127, i32 0 222*9880d681SAndroid Build Coastguard Worker %step = select i1 %c, i32 -1, i32 1 223*9880d681SAndroid Build Coastguard Worker br label %loop 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Workerloop: 226*9880d681SAndroid Build Coastguard Worker %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ] 227*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ] 228*9880d681SAndroid Build Coastguard Worker %iv.trunc = trunc i32 %iv to i16 229*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.trunc = trunc i32 %iv to i16 230*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128) 231*9880d681SAndroid Build Coastguard Worker %iv.next = add i32 %iv, %step 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker %iv.trunc.plus.one = add i16 %iv.trunc, 1 234*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.trunc.plus.one = add i16 %iv.trunc, 1 235*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(1 + (trunc i32 %start to i16))<nuw><nsw>,+,(trunc i32 %step to i16)}<%loop> U: [1,129) S: [1,129) 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker %iv.trunc.plus.two = add i16 %iv.trunc, 2 238*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.trunc.plus.two = add i16 %iv.trunc, 2 239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: --> {(2 + (trunc i32 %start to i16))<nuw><nsw>,+,(trunc i32 %step to i16)}<%loop> U: [2,130) S: [2,130) 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Worker %loop.iv.inc = add i16 %loop.iv, 1 242*9880d681SAndroid Build Coastguard Worker %be.cond = icmp ne i16 %loop.iv.inc, 128 243*9880d681SAndroid Build Coastguard Worker br i1 %be.cond, label %loop, label %leave 244*9880d681SAndroid Build Coastguard Worker 245*9880d681SAndroid Build Coastguard Workerleave: 246*9880d681SAndroid Build Coastguard Worker ret void 247*9880d681SAndroid Build Coastguard Worker} 248