1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -indvars -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; Make sure that indvars can perform LFTR without a canonical IV. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Perform LFTR using the original pointer-type IV. 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; for(char* p = base; p < base + n; ++p) { 10*9880d681SAndroid Build Coastguard Worker; *p = p-base; 11*9880d681SAndroid Build Coastguard Worker; } 12*9880d681SAndroid Build Coastguard Workerdefine void @ptriv(i8* %base, i32 %n) nounwind { 13*9880d681SAndroid Build Coastguard Workerentry: 14*9880d681SAndroid Build Coastguard Worker %idx.ext = sext i32 %n to i64 15*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds i8, i8* %base, i64 %idx.ext 16*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp ult i8* %base, %add.ptr 17*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %for.body, label %for.end 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker; CHECK: for.body: 20*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8* 21*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 22*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add 23*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i8* 24*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 25*9880d681SAndroid Build Coastguard Workerfor.body: 26*9880d681SAndroid Build Coastguard Worker %p.02 = phi i8* [ %base, %entry ], [ %incdec.ptr, %for.body ] 27*9880d681SAndroid Build Coastguard Worker ; cruft to make the IV useful 28*9880d681SAndroid Build Coastguard Worker %sub.ptr.lhs.cast = ptrtoint i8* %p.02 to i64 29*9880d681SAndroid Build Coastguard Worker %sub.ptr.rhs.cast = ptrtoint i8* %base to i64 30*9880d681SAndroid Build Coastguard Worker %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast 31*9880d681SAndroid Build Coastguard Worker %conv = trunc i64 %sub.ptr.sub to i8 32*9880d681SAndroid Build Coastguard Worker store i8 %conv, i8* %p.02 33*9880d681SAndroid Build Coastguard Worker %incdec.ptr = getelementptr inbounds i8, i8* %p.02, i32 1 34*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i8* %incdec.ptr, %add.ptr 35*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workerfor.end: 38*9880d681SAndroid Build Coastguard Worker ret void 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker; This test checks that SCEVExpander can handle an outer loop that has been 42*9880d681SAndroid Build Coastguard Worker; simplified, and as a result the inner loop's exit test will be rewritten. 43*9880d681SAndroid Build Coastguard Workerdefine void @expandOuterRecurrence(i32 %arg) nounwind { 44*9880d681SAndroid Build Coastguard Workerentry: 45*9880d681SAndroid Build Coastguard Worker %sub1 = sub nsw i32 %arg, 1 46*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp slt i32 0, %sub1 47*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %outer, label %exit 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker; CHECK: outer: 50*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt 51*9880d681SAndroid Build Coastguard Workerouter: 52*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ 0, %entry ], [ %i.inc, %outer.inc ] 53*9880d681SAndroid Build Coastguard Worker %sub2 = sub nsw i32 %arg, %i 54*9880d681SAndroid Build Coastguard Worker %sub3 = sub nsw i32 %sub2, 1 55*9880d681SAndroid Build Coastguard Worker %cmp2 = icmp slt i32 0, %sub3 56*9880d681SAndroid Build Coastguard Worker br i1 %cmp2, label %inner.ph, label %outer.inc 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerinner.ph: 59*9880d681SAndroid Build Coastguard Worker br label %inner 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker; CHECK: inner: 62*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 63*9880d681SAndroid Build Coastguard Workerinner: 64*9880d681SAndroid Build Coastguard Worker %j = phi i32 [ 0, %inner.ph ], [ %j.inc, %inner ] 65*9880d681SAndroid Build Coastguard Worker %j.inc = add nsw i32 %j, 1 66*9880d681SAndroid Build Coastguard Worker %cmp3 = icmp slt i32 %j.inc, %sub3 67*9880d681SAndroid Build Coastguard Worker br i1 %cmp3, label %inner, label %outer.inc 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; CHECK: outer.inc: 70*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne 71*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 72*9880d681SAndroid Build Coastguard Workerouter.inc: 73*9880d681SAndroid Build Coastguard Worker %i.inc = add nsw i32 %i, 1 74*9880d681SAndroid Build Coastguard Worker %cmp4 = icmp slt i32 %i.inc, %sub1 75*9880d681SAndroid Build Coastguard Worker br i1 %cmp4, label %outer, label %exit 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Workerexit: 78*9880d681SAndroid Build Coastguard Worker ret void 79*9880d681SAndroid Build Coastguard Worker} 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; Force SCEVExpander to look for an existing well-formed phi. 82*9880d681SAndroid Build Coastguard Worker; Perform LFTR without generating extra preheader code. 83*9880d681SAndroid Build Coastguard Workerdefine void @guardedloop([0 x double]* %matrix, [0 x double]* %vector, 84*9880d681SAndroid Build Coastguard Worker i32 %irow, i32 %ilead) nounwind { 85*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 86*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext 87*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add 88*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 89*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64 90*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64 91*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 92*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne 93*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 94*9880d681SAndroid Build Coastguard Workerentry: 95*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 1, %irow 96*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %loop, label %return 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerloop: 99*9880d681SAndroid Build Coastguard Worker %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ] 100*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ] 101*9880d681SAndroid Build Coastguard Worker %diagidx = add nsw i32 %rowidx, %i 102*9880d681SAndroid Build Coastguard Worker %diagidxw = sext i32 %diagidx to i64 103*9880d681SAndroid Build Coastguard Worker %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw 104*9880d681SAndroid Build Coastguard Worker %v1 = load double, double* %matrixp 105*9880d681SAndroid Build Coastguard Worker %iw = sext i32 %i to i64 106*9880d681SAndroid Build Coastguard Worker %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw 107*9880d681SAndroid Build Coastguard Worker %v2 = load double, double* %vectorp 108*9880d681SAndroid Build Coastguard Worker %row.inc = add nsw i32 %rowidx, %ilead 109*9880d681SAndroid Build Coastguard Worker %i.inc = add nsw i32 %i, 1 110*9880d681SAndroid Build Coastguard Worker %cmp196 = icmp slt i32 %i.inc, %irow 111*9880d681SAndroid Build Coastguard Worker br i1 %cmp196, label %loop, label %return 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Workerreturn: 114*9880d681SAndroid Build Coastguard Worker ret void 115*9880d681SAndroid Build Coastguard Worker} 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker; Avoid generating extra code to materialize a trip count. Skip LFTR. 118*9880d681SAndroid Build Coastguard Workerdefine void @unguardedloop([0 x double]* %matrix, [0 x double]* %vector, 119*9880d681SAndroid Build Coastguard Worker i32 %irow, i32 %ilead) nounwind { 120*9880d681SAndroid Build Coastguard Workerentry: 121*9880d681SAndroid Build Coastguard Worker br label %loop 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 124*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: zext 125*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add 126*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 127*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64 128*9880d681SAndroid Build Coastguard Worker; CHECK: phi i64 129*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 130*9880d681SAndroid Build Coastguard Worker; CHECK: icmp slt 131*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 132*9880d681SAndroid Build Coastguard Workerloop: 133*9880d681SAndroid Build Coastguard Worker %rowidx = phi i32 [ 0, %entry ], [ %row.inc, %loop ] 134*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ] 135*9880d681SAndroid Build Coastguard Worker %diagidx = add nsw i32 %rowidx, %i 136*9880d681SAndroid Build Coastguard Worker %diagidxw = sext i32 %diagidx to i64 137*9880d681SAndroid Build Coastguard Worker %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw 138*9880d681SAndroid Build Coastguard Worker %v1 = load double, double* %matrixp 139*9880d681SAndroid Build Coastguard Worker %iw = sext i32 %i to i64 140*9880d681SAndroid Build Coastguard Worker %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw 141*9880d681SAndroid Build Coastguard Worker %v2 = load double, double* %vectorp 142*9880d681SAndroid Build Coastguard Worker %row.inc = add nsw i32 %rowidx, %ilead 143*9880d681SAndroid Build Coastguard Worker %i.inc = add nsw i32 %i, 1 144*9880d681SAndroid Build Coastguard Worker %cmp196 = icmp slt i32 %i.inc, %irow 145*9880d681SAndroid Build Coastguard Worker br i1 %cmp196, label %loop, label %return 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Workerreturn: 148*9880d681SAndroid Build Coastguard Worker ret void 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker; Remove %i which is only used by the exit test. 152*9880d681SAndroid Build Coastguard Worker; Verify that SCEV can still compute a backedge count from the sign 153*9880d681SAndroid Build Coastguard Worker; extended %n, used for pointer comparison by LFTR. 154*9880d681SAndroid Build Coastguard Worker; 155*9880d681SAndroid Build Coastguard Worker; TODO: Fix for PR13371 currently makes this impossible. See 156*9880d681SAndroid Build Coastguard Worker; IndVarSimplify.cpp hasConcreteDef(). We may want to change to undef rules. 157*9880d681SAndroid Build Coastguard Workerdefine void @geplftr(i8* %base, i32 %x, i32 %y, i32 %n) nounwind { 158*9880d681SAndroid Build Coastguard Workerentry: 159*9880d681SAndroid Build Coastguard Worker %x.ext = sext i32 %x to i64 160*9880d681SAndroid Build Coastguard Worker %add.ptr = getelementptr inbounds i8, i8* %base, i64 %x.ext 161*9880d681SAndroid Build Coastguard Worker %y.ext = sext i32 %y to i64 162*9880d681SAndroid Build Coastguard Worker %add.ptr10 = getelementptr inbounds i8, i8* %add.ptr, i64 %y.ext 163*9880d681SAndroid Build Coastguard Worker %lim = add i32 %x, %n 164*9880d681SAndroid Build Coastguard Worker %cmp.ph = icmp ult i32 %x, %lim 165*9880d681SAndroid Build Coastguard Worker br i1 %cmp.ph, label %loop, label %exit 166*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @geplftr( 167*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 168*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8* 169*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: phi // This check is currently disabled 170*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr 171*9880d681SAndroid Build Coastguard Worker; CHECK: store 172*9880d681SAndroid Build Coastguard Worker; DISABLE: icmp ne i8* // This check is currently disabled 173*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 174*9880d681SAndroid Build Coastguard Workerloop: 175*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %x, %entry ], [ %inc, %loop ] 176*9880d681SAndroid Build Coastguard Worker %aptr = phi i8* [ %add.ptr10, %entry ], [ %incdec.ptr, %loop ] 177*9880d681SAndroid Build Coastguard Worker %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1 178*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %aptr 179*9880d681SAndroid Build Coastguard Worker %inc = add i32 %i, 1 180*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i32 %inc, %lim 181*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %loop, label %exit 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Workerexit: 184*9880d681SAndroid Build Coastguard Worker ret void 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker; Exercise backedge taken count verification with a never-taken loop. 188*9880d681SAndroid Build Coastguard Workerdefine void @nevertaken() nounwind uwtable ssp { 189*9880d681SAndroid Build Coastguard Workerentry: 190*9880d681SAndroid Build Coastguard Worker br label %loop 191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @nevertaken( 192*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 193*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 194*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: add 195*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: icmp 196*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 197*9880d681SAndroid Build Coastguard Workerloop: 198*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ 0, %entry ], [ %inc, %loop ] 199*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i, 1 200*9880d681SAndroid Build Coastguard Worker %cmp = icmp sle i32 %inc, 0 201*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %loop, label %exit 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Workerexit: 204*9880d681SAndroid Build Coastguard Worker ret void 205*9880d681SAndroid Build Coastguard Worker} 206*9880d681SAndroid Build Coastguard Worker 207*9880d681SAndroid Build Coastguard Worker; Test LFTR on an IV whose recurrence start is a non-unit pointer type. 208*9880d681SAndroid Build Coastguard Workerdefine void @aryptriv([256 x i8]* %base, i32 %n) nounwind { 209*9880d681SAndroid Build Coastguard Workerentry: 210*9880d681SAndroid Build Coastguard Worker %ivstart = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 0 211*9880d681SAndroid Build Coastguard Worker %ivend = getelementptr inbounds [256 x i8], [256 x i8]* %base, i32 0, i32 %n 212*9880d681SAndroid Build Coastguard Worker %cmp.ph = icmp ult i8* %ivstart, %ivend 213*9880d681SAndroid Build Coastguard Worker br i1 %cmp.ph, label %loop, label %exit 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 216*9880d681SAndroid Build Coastguard Worker; CHECK: phi i8* 217*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: phi 218*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr 219*9880d681SAndroid Build Coastguard Worker; CHECK: store 220*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i8* 221*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 222*9880d681SAndroid Build Coastguard Workerloop: 223*9880d681SAndroid Build Coastguard Worker %aptr = phi i8* [ %ivstart, %entry ], [ %incdec.ptr, %loop ] 224*9880d681SAndroid Build Coastguard Worker %incdec.ptr = getelementptr inbounds i8, i8* %aptr, i32 1 225*9880d681SAndroid Build Coastguard Worker store i8 3, i8* %aptr 226*9880d681SAndroid Build Coastguard Worker %cmp = icmp ult i8* %incdec.ptr, %ivend 227*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %loop, label %exit 228*9880d681SAndroid Build Coastguard Worker 229*9880d681SAndroid Build Coastguard Workerexit: 230*9880d681SAndroid Build Coastguard Worker ret void 231*9880d681SAndroid Build Coastguard Worker} 232