1 ;; RUN: opt -S < %s -indvars | FileCheck %s 2 3 ;; Check if llvm can narrow !range metadata based on loop entry 4 ;; predicates. 5 6 declare void @abort() 7 8 define i1 @bounded_below_slt(i32* nocapture readonly %buffer) { 9 ; CHECK-LABEL: bounded_below_slt 10 entry: 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 15 loop.preheader: 16 br label %loop 17 18 loop: 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 25 loop.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 31 abort.loopexit: 32 br label %abort 33 34 abort: 35 ret i1 false 36 37 oob: 38 tail call void @abort() 39 ret i1 false 40 } 41 42 define i1 @bounded_below_sle(i32* nocapture readonly %buffer) { 43 ; CHECK-LABEL: bounded_below_sle 44 entry: 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 49 loop.preheader: 50 br label %loop 51 52 loop: 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 59 loop.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 65 abort.loopexit: 66 br label %abort 67 68 abort: 69 ret i1 false 70 71 oob: 72 tail call void @abort() 73 ret i1 false 74 } 75 76 ;; Assert that we're not making an incorrect transform. 77 78 declare i32 @check(i8*) 79 80 define void @NoChange() { 81 ; CHECK-LABEL: NoChange 82 entry: 83 br label %loop.begin 84 85 loop.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 92 loop: 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 100 abort.now: 101 tail call void @abort() 102 unreachable 103 104 loop.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 109 exit: 110 ret void 111 } 112 113 !0 = !{i32 0, i32 100} 114