1
- ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2
2
; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3
3
4
- define i8 @simple (i1 ) {
5
- ; CHECK-LABEL: @simple(
4
+ declare void @use (i8 , i8 )
5
+
6
+ define i8 @simple_phi (i1 %c , i8 %a , i8 %b ) {
7
+ ; CHECK-LABEL: define i8 @simple_phi
8
+ ; CHECK-SAME: (i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
6
9
; CHECK-NEXT: entry:
7
- ; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0:%.* ]], i8 0 , i8 1
8
- ; CHECK-NEXT: br i1 [[TMP0 ]], label [[THEN:%.*]], label [[ELSE:%.*]]
10
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C ]], i8 [[A]] , i8 [[B]]
11
+ ; CHECK-NEXT: br i1 [[C ]], label [[THEN:%.*]], label [[ELSE:%.*]]
9
12
; CHECK: then:
10
- ; CHECK-NEXT: ret i8 0
13
+ ; CHECK-NEXT: ret i8 [[A]]
11
14
; CHECK: else:
12
- ; CHECK-NEXT: ret i8 1
15
+ ; CHECK-NEXT: ret i8 [[B]]
13
16
;
14
17
entry:
15
- %s = select i1 %0 , i8 0 , i8 1
16
- br i1 %0 , label %then , label %else
18
+ %s = select i1 %c , i8 %a , i8 %b
19
+ br i1 %c , label %then , label %else
17
20
18
21
then:
19
- %a = phi i8 [ %s , %entry ]
20
- ret i8 %a
22
+ %phi1 = phi i8 [ %s , %entry ]
23
+ ret i8 %phi1
21
24
22
25
else:
23
- %b = phi i8 [ %s , %entry ]
24
- ret i8 %b
26
+ %phi2 = phi i8 [ %s , %entry ]
27
+ ret i8 %phi2
25
28
}
26
29
27
- define void @loop (i32 ) {
28
- ; CHECK-LABEL: @loop(
30
+ define i8 @phi_other_edge (i1 %c , i8 %a , i8 %b , i32 %sw ) {
31
+ ; CHECK-LABEL: define i8 @phi_other_edge
32
+ ; CHECK-SAME: (i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]], i32 [[SW:%.*]]) {
33
+ ; CHECK-NEXT: entry:
34
+ ; CHECK-NEXT: switch i32 [[SW]], label [[TEST:%.*]] [
35
+ ; CHECK-NEXT: i32 0, label [[THEN:%.*]]
36
+ ; CHECK-NEXT: i32 1, label [[ELSE:%.*]]
37
+ ; CHECK-NEXT: ]
38
+ ; CHECK: test:
39
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[A]], i8 [[B]]
40
+ ; CHECK-NEXT: br i1 [[C]], label [[THEN]], label [[ELSE]]
41
+ ; CHECK: then:
42
+ ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[TEST]] ], [ 1, [[ENTRY:%.*]] ]
43
+ ; CHECK-NEXT: ret i8 [[PHI1]]
44
+ ; CHECK: else:
45
+ ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[TEST]] ], [ 2, [[ENTRY]] ]
46
+ ; CHECK-NEXT: ret i8 [[PHI2]]
47
+ ;
48
+ entry:
49
+ switch i32 %sw , label %test [
50
+ i32 0 , label %then
51
+ i32 1 , label %else
52
+ ]
53
+
54
+ test:
55
+ %s = select i1 %c , i8 %a , i8 %b
56
+ br i1 %c , label %then , label %else
57
+
58
+ then:
59
+ %phi1 = phi i8 [ %s , %test ], [ 1 , %entry ]
60
+ ret i8 %phi1
61
+
62
+ else:
63
+ %phi2 = phi i8 [ %s , %test ], [ 2 , %entry ]
64
+ ret i8 %phi2
65
+ }
66
+
67
+ define void @phi_loop (i32 ) {
68
+ ; CHECK-LABEL: define void @phi_loop
69
+ ; CHECK-SAME: (i32 [[TMP0:%.*]]) {
29
70
; CHECK-NEXT: entry:
30
71
; CHECK-NEXT: br label [[LOOP:%.*]]
31
72
; CHECK: loop:
32
- ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[TMP0:%.* ]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[LOOP]] ]
73
+ ; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[LOOP]] ]
33
74
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[IDX]], 0
34
75
; CHECK-NEXT: [[TMP2]] = add i32 [[IDX]], -1
35
76
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP1]], i32 0, i32 [[TMP2]]
51
92
ret void
52
93
}
53
94
95
+ define void @simple_multiple_uses (i1 %c , i8 %a , i8 %b ) {
96
+ ; CHECK-LABEL: define void @simple_multiple_uses
97
+ ; CHECK-SAME: (i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {
98
+ ; CHECK-NEXT: entry:
99
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[A]], i8 [[B]]
100
+ ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
101
+ ; CHECK: then:
102
+ ; CHECK-NEXT: call void @use(i8 [[S]], i8 [[S]])
103
+ ; CHECK-NEXT: ret void
104
+ ; CHECK: else:
105
+ ; CHECK-NEXT: call void @use(i8 [[S]], i8 [[S]])
106
+ ; CHECK-NEXT: ret void
107
+ ;
108
+ entry:
109
+ %s = select i1 %c , i8 %a , i8 %b
110
+ br i1 %c , label %then , label %else
111
+
112
+ then:
113
+ call void @use (i8 %s , i8 %s )
114
+ ret void
115
+
116
+ else:
117
+ call void @use (i8 %s , i8 %s )
118
+ ret void
119
+ }
120
+
54
121
define i8 @not_correlated (i1 , i1 ) {
55
- ; CHECK-LABEL: @not_correlated(
122
+ ; CHECK-LABEL: define i8 @not_correlated
123
+ ; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]]) {
56
124
; CHECK-NEXT: entry:
57
- ; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0:%.* ]], i8 0, i8 1
58
- ; CHECK-NEXT: br i1 [[TMP1:%.* ]], label [[THEN:%.*]], label [[ELSE:%.*]]
125
+ ; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0]], i8 0, i8 1
126
+ ; CHECK-NEXT: br i1 [[TMP1]], label [[THEN:%.*]], label [[ELSE:%.*]]
59
127
; CHECK: then:
60
128
; CHECK-NEXT: ret i8 [[S]]
61
129
; CHECK: else:
78
146
@b = global i32 0 , align 4
79
147
80
148
define i32 @PR23752 () {
81
- ; CHECK-LABEL: @PR23752(
149
+ ; CHECK-LABEL: define i32 @PR23752() {
82
150
; CHECK-NEXT: entry:
83
151
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
84
152
; CHECK: for.body:
@@ -103,12 +171,13 @@ if.end:
103
171
}
104
172
105
173
define i1 @test1 (ptr %p , i1 %unknown ) {
106
- ; CHECK-LABEL: @test1(
107
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
174
+ ; CHECK-LABEL: define i1 @test1
175
+ ; CHECK-SAME: (ptr [[P:%.*]], i1 [[UNKNOWN:%.*]]) {
176
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4
108
177
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[PVAL]], 255
109
178
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
110
179
; CHECK: next:
111
- ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN:%.* ]], i32 [[PVAL]], i32 5
180
+ ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN]], i32 [[PVAL]], i32 5
112
181
; CHECK-NEXT: ret i1 false
113
182
; CHECK: exit:
114
183
; CHECK-NEXT: ret i1 true
@@ -128,12 +197,13 @@ exit:
128
197
129
198
; Check that we take a conservative meet
130
199
define i1 @test2 (ptr %p , i32 %qval , i1 %unknown ) {
131
- ; CHECK-LABEL: @test2(
132
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
200
+ ; CHECK-LABEL: define i1 @test2
201
+ ; CHECK-SAME: (ptr [[P:%.*]], i32 [[QVAL:%.*]], i1 [[UNKNOWN:%.*]]) {
202
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4
133
203
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[PVAL]], 255
134
204
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
135
205
; CHECK: next:
136
- ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN:%.* ]], i32 [[PVAL]], i32 [[QVAL:%.* ]]
206
+ ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN]], i32 [[PVAL]], i32 [[QVAL]]
137
207
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 255
138
208
; CHECK-NEXT: ret i1 [[RES]]
139
209
; CHECK: exit:
@@ -154,12 +224,13 @@ exit:
154
224
155
225
; Same as @test2, but for the opposite select input
156
226
define i1 @test3 (ptr %p , i32 %qval , i1 %unknown ) {
157
- ; CHECK-LABEL: @test3(
158
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
227
+ ; CHECK-LABEL: define i1 @test3
228
+ ; CHECK-SAME: (ptr [[P:%.*]], i32 [[QVAL:%.*]], i1 [[UNKNOWN:%.*]]) {
229
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4
159
230
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[PVAL]], 255
160
231
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
161
232
; CHECK: next:
162
- ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN:%.* ]], i32 [[QVAL:%.* ]], i32 [[PVAL]]
233
+ ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN]], i32 [[QVAL]], i32 [[PVAL]]
163
234
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 255
164
235
; CHECK-NEXT: ret i1 [[RES]]
165
236
; CHECK: exit:
@@ -183,12 +254,13 @@ exit:
183
254
; is to get around the fact that all integers (including constants
184
255
; and non-constants) are actually represented as constant-ranges.
185
256
define i1 @test4 (ptr %p , i32 %qval , i1 %unknown ) {
186
- ; CHECK-LABEL: @test4(
187
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
257
+ ; CHECK-LABEL: define i1 @test4
258
+ ; CHECK-SAME: (ptr [[P:%.*]], i32 [[QVAL:%.*]], i1 [[UNKNOWN:%.*]]) {
259
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4
188
260
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[PVAL]], 255
189
261
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
190
262
; CHECK: next:
191
- ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN:%.* ]], double 1.000000e+00, double 0.000000e+00
263
+ ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[UNKNOWN]], double 1.000000e+00, double 0.000000e+00
192
264
; CHECK-NEXT: [[RES:%.*]] = fcmp oeq double [[MIN]], 3.000000e+02
193
265
; CHECK-NEXT: ret i1 [[RES]]
194
266
; CHECK: exit:
@@ -211,8 +283,9 @@ exit:
211
283
;;
212
284
213
285
define i1 @test5 (ptr %p , i1 %unknown ) {
214
- ; CHECK-LABEL: @test5(
215
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
286
+ ; CHECK-LABEL: define i1 @test5
287
+ ; CHECK-SAME: (ptr [[P:%.*]], i1 [[UNKNOWN:%.*]]) {
288
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4, !noundef [[META0:![0-9]+]]
216
289
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[PVAL]], 255
217
290
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
218
291
; CHECK: next:
@@ -237,8 +310,9 @@ exit:
237
310
}
238
311
239
312
define i1 @test6 (ptr %p , i1 %unknown ) {
240
- ; CHECK-LABEL: @test6(
241
- ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P:%.*]], align 4
313
+ ; CHECK-LABEL: define i1 @test6
314
+ ; CHECK-SAME: (ptr [[P:%.*]], i1 [[UNKNOWN:%.*]]) {
315
+ ; CHECK-NEXT: [[PVAL:%.*]] = load i32, ptr [[P]], align 4, !noundef [[META0]]
242
316
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[PVAL]], 255
243
317
; CHECK-NEXT: br i1 [[CMP1]], label [[NEXT:%.*]], label [[EXIT:%.*]]
244
318
; CHECK: next:
@@ -263,8 +337,9 @@ exit:
263
337
}
264
338
265
339
define i64 @select_cond_may_undef (i32 %a ) {
266
- ; CHECK-LABEL: @select_cond_may_undef(
267
- ; CHECK-NEXT: [[IS_A_NONNEGATIVE:%.*]] = icmp sgt i32 [[A:%.*]], 1
340
+ ; CHECK-LABEL: define i64 @select_cond_may_undef
341
+ ; CHECK-SAME: (i32 [[A:%.*]]) {
342
+ ; CHECK-NEXT: [[IS_A_NONNEGATIVE:%.*]] = icmp sgt i32 [[A]], 1
268
343
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[IS_A_NONNEGATIVE]], i32 [[A]], i32 0
269
344
; CHECK-NEXT: [[MAX:%.*]] = sext i32 [[NARROW]] to i64
270
345
; CHECK-NEXT: ret i64 [[MAX]]
0 commit comments