1*9880d681SAndroid Build Coastguard Worker;; RUN: opt -S < %s -indvars | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -lcssa -loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)' 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker;; Check if llvm can narrow !range metadata based on loop entry 5*9880d681SAndroid Build Coastguard Worker;; predicates. 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workerdeclare void @abort() 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdefine i1 @bounded_below_slt(i32* nocapture readonly %buffer) { 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bounded_below_slt 11*9880d681SAndroid Build Coastguard Workerentry: 12*9880d681SAndroid Build Coastguard Worker %length = load i32, i32* %buffer, !range !0 13*9880d681SAndroid Build Coastguard Worker %entry.pred = icmp eq i32 %length, 0 14*9880d681SAndroid Build Coastguard Worker br i1 %entry.pred, label %abort, label %loop.preheader 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerloop.preheader: 17*9880d681SAndroid Build Coastguard Worker br label %loop 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerloop: 20*9880d681SAndroid Build Coastguard Worker; CHECK: loop 21*9880d681SAndroid Build Coastguard Worker %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ] 22*9880d681SAndroid Build Coastguard Worker %oob.pred = icmp slt i32 %idx, %length 23*9880d681SAndroid Build Coastguard Worker br i1 %oob.pred, label %loop.next, label %oob 24*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 true, label %loop.next, label %oob 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerloop.next: 27*9880d681SAndroid Build Coastguard Worker; CHECK: loop.next 28*9880d681SAndroid Build Coastguard Worker %idx.inc = add i32 %idx, 1 29*9880d681SAndroid Build Coastguard Worker %exit.pred = icmp slt i32 %idx.inc, %length 30*9880d681SAndroid Build Coastguard Worker br i1 %exit.pred, label %loop, label %abort.loopexit 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Workerabort.loopexit: 33*9880d681SAndroid Build Coastguard Worker br label %abort 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Workerabort: 36*9880d681SAndroid Build Coastguard Worker ret i1 false 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Workeroob: 39*9880d681SAndroid Build Coastguard Worker tail call void @abort() 40*9880d681SAndroid Build Coastguard Worker ret i1 false 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerdefine i1 @bounded_below_sle(i32* nocapture readonly %buffer) { 44*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bounded_below_sle 45*9880d681SAndroid Build Coastguard Workerentry: 46*9880d681SAndroid Build Coastguard Worker %length = load i32, i32* %buffer, !range !0 47*9880d681SAndroid Build Coastguard Worker %entry.pred = icmp eq i32 %length, 0 48*9880d681SAndroid Build Coastguard Worker br i1 %entry.pred, label %abort, label %loop.preheader 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerloop.preheader: 51*9880d681SAndroid Build Coastguard Worker br label %loop 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Workerloop: 54*9880d681SAndroid Build Coastguard Worker; CHECK: loop 55*9880d681SAndroid Build Coastguard Worker %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ] 56*9880d681SAndroid Build Coastguard Worker %oob.pred = icmp sle i32 %idx, %length 57*9880d681SAndroid Build Coastguard Worker br i1 %oob.pred, label %loop.next, label %oob 58*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 true, label %loop.next, label %oob 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerloop.next: 61*9880d681SAndroid Build Coastguard Worker; CHECK: loop.next 62*9880d681SAndroid Build Coastguard Worker %idx.inc = add i32 %idx, 1 63*9880d681SAndroid Build Coastguard Worker %exit.pred = icmp sle i32 %idx.inc, %length 64*9880d681SAndroid Build Coastguard Worker br i1 %exit.pred, label %loop, label %abort.loopexit 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workerabort.loopexit: 67*9880d681SAndroid Build Coastguard Worker br label %abort 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Workerabort: 70*9880d681SAndroid Build Coastguard Worker ret i1 false 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Workeroob: 73*9880d681SAndroid Build Coastguard Worker tail call void @abort() 74*9880d681SAndroid Build Coastguard Worker ret i1 false 75*9880d681SAndroid Build Coastguard Worker} 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker;; Assert that we're not making an incorrect transform. 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Workerdeclare i32 @check(i8*) 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Workerdefine void @NoChange() { 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: NoChange 83*9880d681SAndroid Build Coastguard Workerentry: 84*9880d681SAndroid Build Coastguard Worker br label %loop.begin 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerloop.begin: 87*9880d681SAndroid Build Coastguard Worker; CHECK: loop.begin: 88*9880d681SAndroid Build Coastguard Worker %i.01 = phi i64 [ 2, %entry ], [ %add, %loop.end ] 89*9880d681SAndroid Build Coastguard Worker %cmp = icmp ugt i64 %i.01, 1 90*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp = icmp ugt i64 %i.01, 1 91*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %loop, label %loop.end 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerloop: 94*9880d681SAndroid Build Coastguard Worker; CHECK: loop 95*9880d681SAndroid Build Coastguard Worker %.sum = add i64 %i.01, -2 96*9880d681SAndroid Build Coastguard Worker %v = getelementptr inbounds i8, i8* null, i64 %.sum 97*9880d681SAndroid Build Coastguard Worker %r = tail call i32 @check(i8* %v) 98*9880d681SAndroid Build Coastguard Worker %c = icmp eq i32 %r, 0 99*9880d681SAndroid Build Coastguard Worker br i1 %c, label %loop.end, label %abort.now 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerabort.now: 102*9880d681SAndroid Build Coastguard Worker tail call void @abort() 103*9880d681SAndroid Build Coastguard Worker unreachable 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerloop.end: 106*9880d681SAndroid Build Coastguard Worker %add = add i64 %i.01, -1 107*9880d681SAndroid Build Coastguard Worker %eq = icmp eq i64 %add, 0 108*9880d681SAndroid Build Coastguard Worker br i1 %eq, label %exit, label %loop.begin 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerexit: 111*9880d681SAndroid Build Coastguard Worker ret void 112*9880d681SAndroid Build Coastguard Worker} 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker!0 = !{i32 0, i32 100} 115