| Sanjoy Das | 2512d0c | 2016-05-10 00:31:49 +0000 | [diff] [blame] | 1 | ; RUN: opt -S -indvars < %s | FileCheck %s | 
|  | 2 |  | 
|  | 3 | ; Check that SCEV is able to recognize and use guards to prove | 
|  | 4 | ; conditions gaurding loop entries and backedges.  This isn't intended | 
|  | 5 | ; to be a comprehensive test of SCEV's simplification capabilities, | 
|  | 6 | ; tests directly testing e.g. if SCEV can elide a sext should go | 
|  | 7 | ; elsewhere. | 
|  | 8 |  | 
|  | 9 | target datalayout = "n8:16:32:64" | 
|  | 10 |  | 
|  | 11 | declare void @llvm.experimental.guard(i1, ...) | 
|  | 12 |  | 
|  | 13 | define void @test_1(i1* %cond_buf, i32* %len_buf) { | 
|  | 14 | ; CHECK-LABEL: @test_1( | 
|  | 15 | entry: | 
|  | 16 | %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648} | 
|  | 17 | br label %loop | 
|  | 18 |  | 
|  | 19 | loop: | 
|  | 20 | ; CHECK: loop: | 
|  | 21 | ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] | 
|  | 22 | ; CHECK:  %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 23 | ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 24 | ; CHECK: leave: | 
|  | 25 |  | 
|  | 26 | %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] | 
|  | 27 | %iv.inc = add i32 %iv, 1 | 
|  | 28 |  | 
|  | 29 | %iv.cmp = icmp slt i32 %iv, %len | 
|  | 30 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] | 
|  | 31 |  | 
|  | 32 | %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 33 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 34 |  | 
|  | 35 | %becond = load volatile i1, i1* %cond_buf | 
|  | 36 | br i1 %becond, label %loop, label %leave | 
|  | 37 |  | 
|  | 38 | leave: | 
|  | 39 | ret void | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | define void @test_2(i32 %n, i32* %len_buf) { | 
|  | 43 | ; CHECK-LABEL: @test_2( | 
|  | 44 | ; CHECK:  [[LEN_SEXT:%[^ ]+]] = sext i32 %len to i64 | 
|  | 45 | ; CHECK:  br label %loop | 
|  | 46 |  | 
|  | 47 | entry: | 
|  | 48 | %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648} | 
|  | 49 | br label %loop | 
|  | 50 |  | 
|  | 51 | loop: | 
|  | 52 | ; CHECK: loop: | 
|  | 53 | ; CHECK:  %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ] | 
|  | 54 | ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 | 
|  | 55 | ; CHECK:  %iv.inc.cmp = icmp slt i64 %indvars.iv.next, [[LEN_SEXT]] | 
|  | 56 | ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 57 | ; CHECK: leave: | 
|  | 58 |  | 
|  | 59 | %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] | 
|  | 60 | %iv.inc = add i32 %iv, 1 | 
|  | 61 |  | 
|  | 62 | %iv.sext = sext i32 %iv to i64 | 
|  | 63 |  | 
|  | 64 | %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 65 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 66 |  | 
|  | 67 | %becond = icmp ne i32 %iv, %n | 
|  | 68 | br i1 %becond, label %loop, label %leave | 
|  | 69 |  | 
|  | 70 | leave: | 
|  | 71 | ret void | 
|  | 72 | } | 
|  | 73 |  | 
|  | 74 | define void @test_3(i1* %cond_buf, i32* %len_buf) { | 
|  | 75 | ; CHECK-LABEL: @test_3( | 
|  | 76 |  | 
|  | 77 | entry: | 
|  | 78 | %len = load i32, i32* %len_buf | 
|  | 79 | %entry.cond = icmp sgt i32 %len, 0 | 
|  | 80 | call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ] | 
|  | 81 | br label %loop | 
|  | 82 |  | 
|  | 83 | loop: | 
|  | 84 | ; CHECK: loop: | 
|  | 85 | ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] | 
|  | 86 | ; CHECK:  %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 87 | ; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 88 | ; CHECK: leave: | 
|  | 89 | %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] | 
|  | 90 | %iv.inc = add i32 %iv, 1 | 
|  | 91 |  | 
|  | 92 | %iv.cmp = icmp slt i32 %iv, %len | 
|  | 93 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] | 
|  | 94 |  | 
|  | 95 | %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 96 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 97 |  | 
|  | 98 | %becond = load volatile i1, i1* %cond_buf | 
|  | 99 | br i1 %becond, label %loop, label %leave | 
|  | 100 |  | 
|  | 101 | leave: | 
|  | 102 | ret void | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | define void @test_4(i1* %cond_buf, i32* %len_buf) { | 
|  | 106 | ; CHECK-LABEL: @test_4( | 
|  | 107 |  | 
|  | 108 | entry: | 
|  | 109 | %len = load i32, i32* %len_buf | 
|  | 110 | %entry.cond = icmp sgt i32 %len, 0 | 
|  | 111 | call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ] | 
|  | 112 | br label %loop | 
|  | 113 |  | 
|  | 114 | loop: | 
|  | 115 | %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ] | 
|  | 116 | %iv.inc = add i32 %iv, 1 | 
|  | 117 |  | 
|  | 118 | %cond = load volatile i1, i1* %cond_buf | 
|  | 119 | br i1 %cond, label %left, label %be | 
|  | 120 |  | 
|  | 121 | left: | 
|  | 122 | ; Does not dominate the backedge, so cannot be used in the inductive proof | 
|  | 123 | %iv.inc.cmp = icmp slt i32 %iv.inc, %len | 
|  | 124 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] | 
|  | 125 | br label %be | 
|  | 126 |  | 
|  | 127 | be: | 
|  | 128 | ; CHECK: be: | 
|  | 129 | ; CHECK-NEXT:  %iv.cmp = icmp slt i32 %iv, %len | 
|  | 130 | ; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] | 
|  | 131 | ; CHECK: leave: | 
|  | 132 |  | 
|  | 133 | %iv.cmp = icmp slt i32 %iv, %len | 
|  | 134 | call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] | 
|  | 135 |  | 
|  | 136 | %becond = load volatile i1, i1* %cond_buf | 
|  | 137 | br i1 %becond, label %loop, label %leave | 
|  | 138 |  | 
|  | 139 | leave: | 
|  | 140 | ret void | 
|  | 141 | } |