1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -indvars -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*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" 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; IV with constant start, preinc and postinc sign extends, with and without NSW. 6*9880d681SAndroid Build Coastguard Worker; IV rewrite only removes one sext. WidenIVs removes all three. 7*9880d681SAndroid Build Coastguard Workerdefine void @postincConstIV(i8* %base, i32 %limit) nounwind { 8*9880d681SAndroid Build Coastguard Workerentry: 9*9880d681SAndroid Build Coastguard Worker br label %loop 10*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sext 12*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 13*9880d681SAndroid Build Coastguard Workerloop: 14*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %postiv, %loop ], [ 0, %entry ] 15*9880d681SAndroid Build Coastguard Worker %ivnsw = phi i32 [ %postivnsw, %loop ], [ 0, %entry ] 16*9880d681SAndroid Build Coastguard Worker %preofs = sext i32 %iv to i64 17*9880d681SAndroid Build Coastguard Worker %preadr = getelementptr i8, i8* %base, i64 %preofs 18*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %preadr 19*9880d681SAndroid Build Coastguard Worker %postiv = add i32 %iv, 1 20*9880d681SAndroid Build Coastguard Worker %postofs = sext i32 %postiv to i64 21*9880d681SAndroid Build Coastguard Worker %postadr = getelementptr i8, i8* %base, i64 %postofs 22*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %postadr 23*9880d681SAndroid Build Coastguard Worker %postivnsw = add nsw i32 %ivnsw, 1 24*9880d681SAndroid Build Coastguard Worker %postofsnsw = sext i32 %postivnsw to i64 25*9880d681SAndroid Build Coastguard Worker %postadrnsw = getelementptr inbounds i8, i8* %base, i64 %postofsnsw 26*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %postadrnsw 27*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %limit, %iv 28*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %loop, label %exit 29*9880d681SAndroid Build Coastguard Workerexit: 30*9880d681SAndroid Build Coastguard Worker br label %return 31*9880d681SAndroid Build Coastguard Workerreturn: 32*9880d681SAndroid Build Coastguard Worker ret void 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; IV with nonconstant start, preinc and postinc sign extends, 36*9880d681SAndroid Build Coastguard Worker; with and without NSW. 37*9880d681SAndroid Build Coastguard Worker; As with postincConstIV, WidenIVs removes all three sexts. 38*9880d681SAndroid Build Coastguard Workerdefine void @postincVarIV(i8* %base, i32 %init, i32 %limit) nounwind { 39*9880d681SAndroid Build Coastguard Workerentry: 40*9880d681SAndroid Build Coastguard Worker %precond = icmp sgt i32 %limit, %init 41*9880d681SAndroid Build Coastguard Worker br i1 %precond, label %loop, label %return 42*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 43*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sext 44*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 45*9880d681SAndroid Build Coastguard Workerloop: 46*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ %postiv, %loop ], [ %init, %entry ] 47*9880d681SAndroid Build Coastguard Worker %ivnsw = phi i32 [ %postivnsw, %loop ], [ %init, %entry ] 48*9880d681SAndroid Build Coastguard Worker %preofs = sext i32 %iv to i64 49*9880d681SAndroid Build Coastguard Worker %preadr = getelementptr i8, i8* %base, i64 %preofs 50*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %preadr 51*9880d681SAndroid Build Coastguard Worker %postiv = add i32 %iv, 1 52*9880d681SAndroid Build Coastguard Worker %postofs = sext i32 %postiv to i64 53*9880d681SAndroid Build Coastguard Worker %postadr = getelementptr i8, i8* %base, i64 %postofs 54*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %postadr 55*9880d681SAndroid Build Coastguard Worker %postivnsw = add nsw i32 %ivnsw, 1 56*9880d681SAndroid Build Coastguard Worker %postofsnsw = sext i32 %postivnsw to i64 57*9880d681SAndroid Build Coastguard Worker %postadrnsw = getelementptr i8, i8* %base, i64 %postofsnsw 58*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %postadrnsw 59*9880d681SAndroid Build Coastguard Worker %cond = icmp sgt i32 %limit, %postiv 60*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %loop, label %exit 61*9880d681SAndroid Build Coastguard Workerexit: 62*9880d681SAndroid Build Coastguard Worker br label %return 63*9880d681SAndroid Build Coastguard Workerreturn: 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; Test sign extend elimination in the inner and outer loop. 68*9880d681SAndroid Build Coastguard Worker; %outercount is straightforward to widen, besides being in an outer loop. 69*9880d681SAndroid Build Coastguard Worker; %innercount is currently blocked by lcssa, so is not widened. 70*9880d681SAndroid Build Coastguard Worker; %inneriv can be widened only after proving it has no signed-overflow 71*9880d681SAndroid Build Coastguard Worker; based on the loop test. 72*9880d681SAndroid Build Coastguard Workerdefine void @nestedIV(i8* %address, i32 %limit) nounwind { 73*9880d681SAndroid Build Coastguard Workerentry: 74*9880d681SAndroid Build Coastguard Worker %limitdec = add i32 %limit, -1 75*9880d681SAndroid Build Coastguard Worker br label %outerloop 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker; CHECK: outerloop: 78*9880d681SAndroid Build Coastguard Worker; 79*9880d681SAndroid Build Coastguard Worker; Eliminate %ofs1 after widening outercount. 80*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sext 81*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr 82*9880d681SAndroid Build Coastguard Worker; 83*9880d681SAndroid Build Coastguard Worker; IV rewriting hoists a gep into this block. We don't like that. 84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: getelementptr 85*9880d681SAndroid Build Coastguard Workerouterloop: 86*9880d681SAndroid Build Coastguard Worker %outercount = phi i32 [ %outerpostcount, %outermerge ], [ 0, %entry ] 87*9880d681SAndroid Build Coastguard Worker %innercount = phi i32 [ %innercount.merge, %outermerge ], [ 0, %entry ] 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker %outercountdec = add i32 %outercount, -1 90*9880d681SAndroid Build Coastguard Worker %ofs1 = sext i32 %outercountdec to i64 91*9880d681SAndroid Build Coastguard Worker %adr1 = getelementptr i8, i8* %address, i64 %ofs1 92*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %adr1 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker br label %innerpreheader 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerinnerpreheader: 97*9880d681SAndroid Build Coastguard Worker %innerprecmp = icmp sgt i32 %limitdec, %innercount 98*9880d681SAndroid Build Coastguard Worker br i1 %innerprecmp, label %innerloop, label %outermerge 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker; CHECK: innerloop: 101*9880d681SAndroid Build Coastguard Worker; 102*9880d681SAndroid Build Coastguard Worker; Eliminate %ofs2 after widening inneriv. 103*9880d681SAndroid Build Coastguard Worker; Eliminate %ofs3 after normalizing sext(innerpostiv) 104*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sext 105*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr 106*9880d681SAndroid Build Coastguard Worker; 107*9880d681SAndroid Build Coastguard Worker; FIXME: We should check that indvars does not increase the number of 108*9880d681SAndroid Build Coastguard Worker; IVs in this loop. sext elimination plus LFTR currently results in 2 final 109*9880d681SAndroid Build Coastguard Worker; IVs. Waiting to remove LFTR. 110*9880d681SAndroid Build Coastguard Workerinnerloop: 111*9880d681SAndroid Build Coastguard Worker %inneriv = phi i32 [ %innerpostiv, %innerloop ], [ %innercount, %innerpreheader ] 112*9880d681SAndroid Build Coastguard Worker %innerpostiv = add i32 %inneriv, 1 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker %ofs2 = sext i32 %inneriv to i64 115*9880d681SAndroid Build Coastguard Worker %adr2 = getelementptr i8, i8* %address, i64 %ofs2 116*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %adr2 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker %ofs3 = sext i32 %innerpostiv to i64 119*9880d681SAndroid Build Coastguard Worker %adr3 = getelementptr i8, i8* %address, i64 %ofs3 120*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %adr3 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker %innercmp = icmp sgt i32 %limitdec, %innerpostiv 123*9880d681SAndroid Build Coastguard Worker br i1 %innercmp, label %innerloop, label %innerexit 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerinnerexit: 126*9880d681SAndroid Build Coastguard Worker %innercount.lcssa = phi i32 [ %innerpostiv, %innerloop ] 127*9880d681SAndroid Build Coastguard Worker br label %outermerge 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; CHECK: outermerge: 130*9880d681SAndroid Build Coastguard Worker; 131*9880d681SAndroid Build Coastguard Worker; Eliminate %ofs4 after widening outercount 132*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: sext 133*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr 134*9880d681SAndroid Build Coastguard Worker; 135*9880d681SAndroid Build Coastguard Worker; TODO: Eliminate %ofs5 after removing lcssa 136*9880d681SAndroid Build Coastguard Workeroutermerge: 137*9880d681SAndroid Build Coastguard Worker %innercount.merge = phi i32 [ %innercount.lcssa, %innerexit ], [ %innercount, %innerpreheader ] 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker %ofs4 = sext i32 %outercount to i64 140*9880d681SAndroid Build Coastguard Worker %adr4 = getelementptr i8, i8* %address, i64 %ofs4 141*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %adr4 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker %ofs5 = sext i32 %innercount.merge to i64 144*9880d681SAndroid Build Coastguard Worker %adr5 = getelementptr i8, i8* %address, i64 %ofs5 145*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %adr5 146*9880d681SAndroid Build Coastguard Worker 147*9880d681SAndroid Build Coastguard Worker %outerpostcount = add i32 %outercount, 1 148*9880d681SAndroid Build Coastguard Worker %tmp47 = icmp slt i32 %outerpostcount, %limit 149*9880d681SAndroid Build Coastguard Worker br i1 %tmp47, label %outerloop, label %return 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Workerreturn: 152*9880d681SAndroid Build Coastguard Worker ret void 153*9880d681SAndroid Build Coastguard Worker} 154