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