blob: 52ad4dc73d417aa3c6aec3737b7bf9fe45f5cf45 [file] [log] [blame]
Sanjoy Das2512d0c2016-05-10 00:31:49 +00001; 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
9target datalayout = "n8:16:32:64"
10
11declare void @llvm.experimental.guard(i1, ...)
12
13define void @test_1(i1* %cond_buf, i32* %len_buf) {
14; CHECK-LABEL: @test_1(
15entry:
16 %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648}
17 br label %loop
18
19loop:
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
38leave:
39 ret void
40}
41
42define 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
47entry:
48 %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648}
49 br label %loop
50
51loop:
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
70leave:
71 ret void
72}
73
74define void @test_3(i1* %cond_buf, i32* %len_buf) {
75; CHECK-LABEL: @test_3(
76
77entry:
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
83loop:
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
101leave:
102 ret void
103}
104
105define void @test_4(i1* %cond_buf, i32* %len_buf) {
106; CHECK-LABEL: @test_4(
107
108entry:
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
114loop:
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
121left:
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
127be:
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
139leave:
140 ret void
141}