1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
1
2
; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
2
3
3
- ; Check that debug locations are preserved. For more info see:
4
- ; https://llvm.org/docs/SourceLevelDebugging.html#fixing-errors
5
- ; RUN: opt < %s -enable-debugify -passes=correlated-propagation -S 2>&1 | \
6
- ; RUN: FileCheck %s -check-prefix=DEBUG
7
- ; DEBUG: CheckModuleDebugify: PASS
8
-
9
- ; CHECK-LABEL: @test1
10
4
define void @test1 (i32 %n ) {
5
+ ; CHECK-LABEL: define void @test1(
6
+ ; CHECK-SAME: i32 [[N:%.*]]) {
7
+ ; CHECK-NEXT: [[ENTRY:.*]]:
8
+ ; CHECK-NEXT: br label %[[FOR_COND:.*]]
9
+ ; CHECK: [[FOR_COND]]:
10
+ ; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[FOR_BODY:.*]] ]
11
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 1
12
+ ; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
13
+ ; CHECK: [[FOR_BODY]]:
14
+ ; CHECK-NEXT: [[SHR]] = lshr i32 [[A]], 5
15
+ ; CHECK-NEXT: br label %[[FOR_COND]]
16
+ ; CHECK: [[FOR_END]]:
17
+ ; CHECK-NEXT: ret void
18
+ ;
11
19
entry:
12
20
br label %for.cond
13
21
@@ -17,7 +25,6 @@ for.cond: ; preds = %for.body, %entry
17
25
br i1 %cmp , label %for.body , label %for.end
18
26
19
27
for.body: ; preds = %for.cond
20
- ; CHECK: lshr i32 %a, 5
21
28
%shr = ashr i32 %a , 5
22
29
br label %for.cond
23
30
@@ -26,8 +33,21 @@ for.end: ; preds = %for.cond
26
33
}
27
34
28
35
;; Negative test to show transform doesn't happen unless n > 0.
29
- ; CHECK-LABEL: @test2
30
36
define void @test2 (i32 %n ) {
37
+ ; CHECK-LABEL: define void @test2(
38
+ ; CHECK-SAME: i32 [[N:%.*]]) {
39
+ ; CHECK-NEXT: [[ENTRY:.*]]:
40
+ ; CHECK-NEXT: br label %[[FOR_COND:.*]]
41
+ ; CHECK: [[FOR_COND]]:
42
+ ; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[FOR_BODY:.*]] ]
43
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], -2
44
+ ; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_END:.*]]
45
+ ; CHECK: [[FOR_BODY]]:
46
+ ; CHECK-NEXT: [[SHR]] = ashr i32 [[A]], 2
47
+ ; CHECK-NEXT: br label %[[FOR_COND]]
48
+ ; CHECK: [[FOR_END]]:
49
+ ; CHECK-NEXT: ret void
50
+ ;
31
51
entry:
32
52
br label %for.cond
33
53
@@ -37,7 +57,6 @@ for.cond: ; preds = %for.body, %entry
37
57
br i1 %cmp , label %for.body , label %for.end
38
58
39
59
for.body: ; preds = %for.cond
40
- ; CHECK: ashr i32 %a, 2
41
60
%shr = ashr i32 %a , 2
42
61
br label %for.cond
43
62
@@ -46,14 +65,23 @@ for.end: ; preds = %for.cond
46
65
}
47
66
48
67
;; Non looping test case.
49
- ; CHECK-LABEL: @test3
50
68
define void @test3 (i32 %n ) {
69
+ ; CHECK-LABEL: define void @test3(
70
+ ; CHECK-SAME: i32 [[N:%.*]]) {
71
+ ; CHECK-NEXT: [[ENTRY:.*:]]
72
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
73
+ ; CHECK-NEXT: br i1 [[CMP]], label %[[BB:.*]], label %[[EXIT:.*]]
74
+ ; CHECK: [[BB]]:
75
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr exact i32 [[N]], 4
76
+ ; CHECK-NEXT: br label %[[EXIT]]
77
+ ; CHECK: [[EXIT]]:
78
+ ; CHECK-NEXT: ret void
79
+ ;
51
80
entry:
52
81
%cmp = icmp sgt i32 %n , 0
53
82
br i1 %cmp , label %bb , label %exit
54
83
55
84
bb:
56
- ; CHECK: lshr exact i32 %n, 4
57
85
%shr = ashr exact i32 %n , 4
58
86
br label %exit
59
87
@@ -65,14 +93,26 @@ exit:
65
93
; at the point of ashr, we know that the operand is always greater than 0,
66
94
; because of the guard before it, so we can transform it to lshr.
67
95
declare void @llvm.experimental.guard (i1 ,...)
68
- ; CHECK-LABEL: @test4
69
96
define void @test4 (i32 %n ) {
97
+ ; CHECK-LABEL: define void @test4(
98
+ ; CHECK-SAME: i32 [[N:%.*]]) {
99
+ ; CHECK-NEXT: [[ENTRY:.*]]:
100
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
101
+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP:.*]], label %[[EXIT:.*]]
102
+ ; CHECK: [[LOOP]]:
103
+ ; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[LOOP]] ]
104
+ ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[A]], 2
105
+ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
106
+ ; CHECK-NEXT: [[SHR]] = lshr i32 [[A]], 1
107
+ ; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT]]
108
+ ; CHECK: [[EXIT]]:
109
+ ; CHECK-NEXT: ret void
110
+ ;
70
111
entry:
71
112
%cmp = icmp sgt i32 %n , 0
72
113
br i1 %cmp , label %loop , label %exit
73
114
74
115
loop:
75
- ; CHECK: lshr i32 %a, 1
76
116
%a = phi i32 [ %n , %entry ], [ %shr , %loop ]
77
117
%cond = icmp sgt i32 %a , 2
78
118
call void (i1 ,...) @llvm.experimental.guard (i1 %cond ) [ "deopt" () ]
@@ -85,14 +125,27 @@ exit:
85
125
86
126
; same test as above with assume instead of guard.
87
127
declare void @llvm.assume (i1 )
88
- ; CHECK-LABEL: @test5
89
128
define void @test5 (i32 %n ) {
129
+ ; CHECK-LABEL: define void @test5(
130
+ ; CHECK-SAME: i32 [[N:%.*]]) {
131
+ ; CHECK-NEXT: [[ENTRY:.*]]:
132
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
133
+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP:.*]], label %[[EXIT:.*]]
134
+ ; CHECK: [[LOOP]]:
135
+ ; CHECK-NEXT: [[A:%.*]] = phi i32 [ [[N]], %[[ENTRY]] ], [ [[SHR:%.*]], %[[LOOP]] ]
136
+ ; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A]], 4
137
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
138
+ ; CHECK-NEXT: [[SHR]] = lshr i32 [[A]], 1
139
+ ; CHECK-NEXT: [[LOOPCOND:%.*]] = icmp ugt i32 [[SHR]], 8
140
+ ; CHECK-NEXT: br i1 [[LOOPCOND]], label %[[LOOP]], label %[[EXIT]]
141
+ ; CHECK: [[EXIT]]:
142
+ ; CHECK-NEXT: ret void
143
+ ;
90
144
entry:
91
145
%cmp = icmp sgt i32 %n , 0
92
146
br i1 %cmp , label %loop , label %exit
93
147
94
148
loop:
95
- ; CHECK: lshr i32 %a, 1
96
149
%a = phi i32 [ %n , %entry ], [ %shr , %loop ]
97
150
%cond = icmp sgt i32 %a , 4
98
151
call void @llvm.assume (i1 %cond )
@@ -105,54 +158,72 @@ exit:
105
158
}
106
159
107
160
; check that ashr of -1 or 0 is optimized away
108
- ; CHECK-LABEL: @test6
109
161
define i32 @test6 (i32 %f , i32 %g ) {
162
+ ; CHECK-LABEL: define i32 @test6(
163
+ ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
164
+ ; CHECK-NEXT: [[ENTRY:.*:]]
165
+ ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[F]], 1
166
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 2
167
+ ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]])
168
+ ; CHECK-NEXT: ret i32 [[F]]
169
+ ;
110
170
entry:
111
171
%0 = add i32 %f , 1
112
172
%1 = icmp ult i32 %0 , 2
113
173
tail call void @llvm.assume (i1 %1 )
114
- ; CHECK: ret i32 %f
115
174
%shr = ashr i32 %f , %g
116
175
ret i32 %shr
117
176
}
118
177
119
178
; same test as above with different numbers
120
- ; CHECK-LABEL: @test7
121
179
define i32 @test7 (i32 %f , i32 %g ) {
180
+ ; CHECK-LABEL: define i32 @test7(
181
+ ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
182
+ ; CHECK-NEXT: [[ENTRY:.*:]]
183
+ ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[F]], -2
184
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 6
185
+ ; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]])
186
+ ; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[F]], -7
187
+ ; CHECK-NEXT: ret i32 [[SUB]]
188
+ ;
122
189
entry:
123
190
%0 = and i32 %f , -2
124
191
%1 = icmp eq i32 %0 , 6
125
192
tail call void @llvm.assume (i1 %1 )
126
193
%sub = add nsw i32 %f , -7
127
- ; CHECK: ret i32 %sub
128
194
%shr = ashr i32 %sub , %g
129
195
ret i32 %shr
130
196
}
131
197
132
198
; check that ashr of -2 or 1 is not optimized away
133
- ; CHECK-LABEL: @test8
134
199
define i32 @test8 (i32 %f , i32 %g , i1 %s ) {
200
+ ; CHECK-LABEL: define i32 @test8(
201
+ ; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]], i1 [[S:%.*]]) {
202
+ ; CHECK-NEXT: [[ENTRY:.*:]]
203
+ ; CHECK-NEXT: [[TMP0:%.*]] = ashr i32 -2, [[F]]
204
+ ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 1, [[G]]
205
+ ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[S]], i32 [[TMP0]], i32 [[TMP1]]
206
+ ; CHECK-NEXT: ret i32 [[TMP2]]
207
+ ;
135
208
entry:
136
- ; CHECK: ashr i32 -2, %f
137
209
%0 = ashr i32 -2 , %f
138
- ; CHECK: lshr i32 1, %g
139
210
%1 = ashr i32 1 , %g
140
211
%2 = select i1 %s , i32 %0 , i32 %1
141
212
ret i32 %2
142
213
}
143
214
144
215
define i32 @may_including_undef (i1 %c.1 , i1 %c.2 ) {
145
- ; CHECK-LABEL: define i32 @may_including_undef
146
- ; CHECK-SAME: ( i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
147
- ; CHECK-NEXT: br i1 [[C_1]], label [[TRUE_1:% .*]], label [[FALSE:% .*]]
148
- ; CHECK: true.1 :
149
- ; CHECK-NEXT: br i1 [[C_2]], label [[TRUE_2:% .*]], label [[EXIT:% .*]]
150
- ; CHECK: true.2 :
151
- ; CHECK-NEXT: br label [[EXIT]]
152
- ; CHECK: false :
153
- ; CHECK-NEXT: br label [[EXIT]]
154
- ; CHECK: exit :
155
- ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 2, [[TRUE_1]] ], [ 4, [[TRUE_2]] ], [ undef, [[FALSE]] ]
216
+ ; CHECK-LABEL: define i32 @may_including_undef(
217
+ ; CHECK-SAME: i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
218
+ ; CHECK-NEXT: br i1 [[C_1]], label % [[TRUE_1:.*]], label % [[FALSE:.*]]
219
+ ; CHECK: [[TRUE_1]] :
220
+ ; CHECK-NEXT: br i1 [[C_2]], label % [[TRUE_2:.*]], label % [[EXIT:.*]]
221
+ ; CHECK: [[TRUE_2]] :
222
+ ; CHECK-NEXT: br label % [[EXIT]]
223
+ ; CHECK: [[FALSE]] :
224
+ ; CHECK-NEXT: br label % [[EXIT]]
225
+ ; CHECK: [[EXIT]] :
226
+ ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 2, % [[TRUE_1]] ], [ 4, % [[TRUE_2]] ], [ undef, % [[FALSE]] ]
156
227
; CHECK-NEXT: [[R:%.*]] = ashr i32 [[P]], 1
157
228
; CHECK-NEXT: ret i32 [[R]]
158
229
;
0 commit comments