• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -correlated-propagation -S | FileCheck %s
2
3; CHECK-LABEL: @simple(
4define i8 @simple(i1) {
5entry:
6  %s = select i1 %0, i8 0, i8 1
7  br i1 %0, label %then, label %else
8
9then:
10; CHECK: ret i8 0
11  %a = phi i8 [ %s, %entry ]
12  ret i8 %a
13
14else:
15; CHECK: ret i8 1
16  %b = phi i8 [ %s, %entry ]
17  ret i8 %b
18}
19
20; CHECK-LABEL: @loop(
21define void @loop(i32) {
22entry:
23  br label %loop
24
25loop:
26  %idx = phi i32 [ %0, %entry ], [ %sel, %loop ]
27; CHECK: %idx = phi i32 [ %0, %entry ], [ %2, %loop ]
28  %1 = icmp eq i32 %idx, 0
29  %2 = add i32 %idx, -1
30  %sel = select i1 %1, i32 0, i32 %2
31  br i1 %1, label %out, label %loop
32
33out:
34  ret void
35}
36
37; CHECK-LABEL: @not_correlated(
38define i8 @not_correlated(i1, i1) {
39entry:
40  %s = select i1 %0, i8 0, i8 1
41  br i1 %1, label %then, label %else
42
43then:
44; CHECK: ret i8 %s
45  %a = phi i8 [ %s, %entry ]
46  ret i8 %a
47
48else:
49; CHECK: ret i8 %s
50  %b = phi i8 [ %s, %entry ]
51  ret i8 %b
52}
53
54@c = global i32 0, align 4
55@b = global i32 0, align 4
56
57; CHECK-LABEL: @PR23752(
58define i32 @PR23752() {
59entry:
60  br label %for.body
61
62for.body:
63  %phi = phi i32 [ 0, %entry ], [ %sel, %for.body ]
64  %sel = select i1 icmp sgt (i32* @b, i32* @c), i32 %phi, i32 1
65  %cmp = icmp ne i32 %sel, 1
66  br i1 %cmp, label %for.body, label %if.end
67
68; CHECK:      %[[sel:.*]] = select i1 icmp sgt (i32* @b, i32* @c), i32 0, i32 1
69; CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[sel]], 1
70; CHECK-NEXT: br i1 %[[cmp]]
71
72if.end:
73  ret i32 %sel
74; CHECK: ret i32 1
75}
76
77define i1 @test1(i32* %p, i1 %unknown) {
78; CHECK-LABEL: @test1
79  %pval = load i32, i32* %p
80  %cmp1 = icmp slt i32 %pval, 255
81  br i1 %cmp1, label %next, label %exit
82
83next:
84  %min = select i1 %unknown, i32 %pval, i32 5
85  ;; TODO: This pointless branch shouldn't be neccessary
86  br label %next2
87next2:
88; CHECK-LABEL: next2:
89; CHECK: ret i1 false
90  %res = icmp eq i32 %min, 255
91  ret i1 %res
92
93exit:
94; CHECK-LABEL: exit:
95; CHECK: ret i1 true
96  ret i1 true
97}
98
99; Check that we take a conservative meet
100define i1 @test2(i32* %p, i32 %qval, i1 %unknown) {
101; CHECK-LABEL: test2
102  %pval = load i32, i32* %p
103  %cmp1 = icmp slt i32 %pval, 255
104  br i1 %cmp1, label %next, label %exit
105
106next:
107  %min = select i1 %unknown, i32 %pval, i32 %qval
108  ;; TODO: This pointless branch shouldn't be neccessary
109  br label %next2
110next2:
111; CHECK-LABEL: next2
112; CHECK: ret i1 %res
113  %res = icmp eq i32 %min, 255
114  ret i1 %res
115
116exit:
117; CHECK-LABEL: exit:
118; CHECK: ret i1 true
119  ret i1 true
120}
121
122; Same as @test2, but for the opposite select input
123define i1 @test3(i32* %p, i32 %qval, i1 %unknown) {
124; CHECK-LABEL: test3
125  %pval = load i32, i32* %p
126  %cmp1 = icmp slt i32 %pval, 255
127  br i1 %cmp1, label %next, label %exit
128
129next:
130  %min = select i1 %unknown, i32 %qval, i32 %pval
131  ;; TODO: This pointless branch shouldn't be neccessary
132  br label %next2
133next2:
134; CHECK-LABEL: next2
135; CHECK: ret i1 %res
136  %res = icmp eq i32 %min, 255
137  ret i1 %res
138
139exit:
140; CHECK-LABEL: exit:
141; CHECK: ret i1 true
142  ret i1 true
143}
144
145; Conflicting constants (i.e. isOverdefined result)
146; NOTE: Using doubles in this version is a bit of a hack.  This
147; is to get around the fact that all integers (including constants
148; and non-constants) are actually represented as constant-ranges.
149define i1 @test4(i32* %p, i32 %qval, i1 %unknown) {
150; CHECK-LABEL: test4
151  %pval = load i32, i32* %p
152  %cmp1 = icmp slt i32 %pval, 255
153  br i1 %cmp1, label %next, label %exit
154
155next:
156  %min = select i1 %unknown, double 1.0, double 0.0
157  ;; TODO: This pointless branch shouldn't be neccessary
158  br label %next2
159next2:
160; CHECK-LABEL: next2
161; CHECK: ret i1 %res
162  %res = fcmp oeq double %min, 300.0
163  ret i1 %res
164
165exit:
166; CHECK-LABEL: exit:
167; CHECK: ret i1 true
168  ret i1 true
169}
170
171;; Using the condition to clamp the result
172;;
173
174define i1 @test5(i32* %p, i1 %unknown) {
175; CHECK-LABEL: @test5
176  %pval = load i32, i32* %p
177  %cmp1 = icmp slt i32 %pval, 255
178  br i1 %cmp1, label %next, label %exit
179
180next:
181  %cond = icmp sgt i32 %pval, 0
182  %min = select i1 %cond, i32 %pval, i32 5
183  ;; TODO: This pointless branch shouldn't be neccessary
184  br label %next2
185next2:
186; CHECK-LABEL: next2:
187; CHECK: ret i1 false
188  %res = icmp eq i32 %min, -1
189  ret i1 %res
190
191exit:
192; CHECK-LABEL: exit:
193; CHECK: ret i1 true
194  ret i1 true
195}
196
197define i1 @test6(i32* %p, i1 %unknown) {
198; CHECK-LABEL: @test6
199  %pval = load i32, i32* %p
200  %cmp1 = icmp ult i32 %pval, 255
201  br i1 %cmp1, label %next, label %exit
202
203next:
204  %cond = icmp ne i32 %pval, 254
205  %sel = select i1 %cond, i32 %pval, i32 1
206  ;; TODO: This pointless branch shouldn't be neccessary
207  br label %next2
208next2:
209; CHECK-LABEL: next2:
210; CHECK: ret i1 true
211  %res = icmp slt i32 %sel, 254
212  ret i1 %res
213
214exit:
215; CHECK-LABEL: exit:
216; CHECK: ret i1 true
217  ret i1 true
218}
219