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