1
1
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
2
; RUN: opt %s -callbrprepare -S -o - | FileCheck %s
3
3
4
- ; TODO: update this test to split critical edges.
5
4
define i32 @test0 () {
6
5
; CHECK-LABEL: @test0(
7
6
; CHECK-NEXT: entry:
8
7
; CHECK-NEXT: [[OUT:%.*]] = callbr i32 asm "# $0", "=r,!i"()
9
- ; CHECK-NEXT: to label [[DIRECT:%.*]] [label %indirect]
8
+ ; CHECK-NEXT: to label [[DIRECT:%.*]] [label %entry.indirect_crit_edge]
9
+ ; CHECK: entry.indirect_crit_edge:
10
+ ; CHECK-NEXT: br label [[INDIRECT:%.*]]
10
11
; CHECK: direct:
11
12
; CHECK-NEXT: [[OUT2:%.*]] = callbr i32 asm "# $0", "=r,!i"()
12
- ; CHECK-NEXT: to label [[DIRECT2:%.*]] [label %indirect]
13
+ ; CHECK-NEXT: to label [[DIRECT2:%.*]] [label %direct.indirect_crit_edge]
14
+ ; CHECK: direct.indirect_crit_edge:
15
+ ; CHECK-NEXT: br label [[INDIRECT]]
13
16
; CHECK: direct2:
14
17
; CHECK-NEXT: ret i32 0
15
18
; CHECK: indirect:
16
- ; CHECK-NEXT: [[OUT3:%.*]] = phi i32 [ [[OUT]], [[ENTRY :%.*]] ], [ [[OUT2]], [[DIRECT ]] ]
19
+ ; CHECK-NEXT: [[OUT3:%.*]] = phi i32 [ [[OUT]], [[ENTRY_INDIRECT_CRIT_EDGE :%.*]] ], [ [[OUT2]], [[DIRECT_INDIRECT_CRIT_EDGE:%.* ]] ]
17
20
; CHECK-NEXT: ret i32 [[OUT3]]
18
21
;
19
22
entry:
@@ -28,3 +31,193 @@ indirect:
28
31
%out3 = phi i32 [%out , %entry ], [%out2 , %direct ]
29
32
ret i32 %out3
30
33
}
34
+
35
+ ; Don't split edges unless they are critical, and callbr produces output, and
36
+ ; that output is used.
37
+ ; Here we have none of the above.
38
+ define i32 @dont_split0 () {
39
+ ; CHECK-LABEL: @dont_split0(
40
+ ; CHECK-NEXT: entry:
41
+ ; CHECK-NEXT: callbr void asm "", "!i"()
42
+ ; CHECK-NEXT: to label [[X:%.*]] [label %y]
43
+ ; CHECK: x:
44
+ ; CHECK-NEXT: ret i32 42
45
+ ; CHECK: y:
46
+ ; CHECK-NEXT: ret i32 0
47
+ ;
48
+ entry:
49
+ callbr void asm "" , "!i" ()
50
+ to label %x [label %y ]
51
+
52
+ x:
53
+ ret i32 42
54
+
55
+ y:
56
+ ret i32 0
57
+ }
58
+
59
+ ; Don't split edges unless they are critical, and callbr produces output, and
60
+ ; that output is used.
61
+ ; Here we have output, but no critical edge.
62
+ define i32 @dont_split1 () {
63
+ ; CHECK-LABEL: @dont_split1(
64
+ ; CHECK-NEXT: entry:
65
+ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"()
66
+ ; CHECK-NEXT: to label [[X:%.*]] [label %y]
67
+ ; CHECK: x:
68
+ ; CHECK-NEXT: ret i32 42
69
+ ; CHECK: y:
70
+ ; CHECK-NEXT: ret i32 [[TMP0]]
71
+ ;
72
+ entry:
73
+ %0 = callbr i32 asm "" , "=r,!i" ()
74
+ to label %x [label %y ]
75
+
76
+ x:
77
+ ret i32 42
78
+
79
+ y:
80
+ ret i32 %0
81
+ }
82
+
83
+ ; Don't split edges unless they are critical, and callbr produces output, and
84
+ ; that output is used.
85
+ ; Here we have a critical edge along an indirect branch, but no output.
86
+ define i32 @dont_split2 () {
87
+ ; CHECK-LABEL: @dont_split2(
88
+ ; CHECK-NEXT: entry:
89
+ ; CHECK-NEXT: callbr void asm "", "!i"()
90
+ ; CHECK-NEXT: to label [[X:%.*]] [label %y]
91
+ ; CHECK: x:
92
+ ; CHECK-NEXT: br label [[Y:%.*]]
93
+ ; CHECK: y:
94
+ ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[X]] ], [ 42, [[ENTRY:%.*]] ]
95
+ ; CHECK-NEXT: ret i32 [[TMP0]]
96
+ ;
97
+ entry:
98
+ callbr void asm "" , "!i" ()
99
+ to label %x [label %y ]
100
+
101
+ x:
102
+ br label %y
103
+
104
+ y:
105
+ %0 = phi i32 [ 0 , %x ], [ 42 , %entry ]
106
+ ret i32 %0
107
+ }
108
+
109
+ ; Don't split edges unless they are critical, and callbr produces output, and
110
+ ; that output is used.
111
+ ; Here we're missing a use.
112
+ define i32 @dont_split3 () {
113
+ ; CHECK-LABEL: @dont_split3(
114
+ ; CHECK-NEXT: entry:
115
+ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"()
116
+ ; CHECK-NEXT: to label [[X:%.*]] [label %v]
117
+ ; CHECK: x:
118
+ ; CHECK-NEXT: br label [[V:%.*]]
119
+ ; CHECK: v:
120
+ ; CHECK-NEXT: ret i32 42
121
+ ;
122
+ entry:
123
+ %0 = callbr i32 asm "" , "=r,!i" () to label %x [label %v ]
124
+
125
+ x:
126
+ br label %v
127
+
128
+ v:
129
+ ret i32 42
130
+ }
131
+
132
+ ; Don't split edges unless they are critical, and callbr produces output, and
133
+ ; that output is used.
134
+ ; Here we have output and a critical edge along an indirect branch.
135
+ define i32 @split_me0 () {
136
+ ; CHECK-LABEL: @split_me0(
137
+ ; CHECK-NEXT: entry:
138
+ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"()
139
+ ; CHECK-NEXT: to label [[X:%.*]] [label %entry.y_crit_edge]
140
+ ; CHECK: entry.y_crit_edge:
141
+ ; CHECK-NEXT: br label [[Y:%.*]]
142
+ ; CHECK: x:
143
+ ; CHECK-NEXT: br label [[Y]]
144
+ ; CHECK: y:
145
+ ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY_Y_CRIT_EDGE:%.*]] ], [ 42, [[X]] ]
146
+ ; CHECK-NEXT: ret i32 [[TMP1]]
147
+ ;
148
+ entry:
149
+ %0 = callbr i32 asm "" , "=r,!i" ()
150
+ to label %x [label %y ]
151
+
152
+ x:
153
+ br label %y
154
+
155
+ y:
156
+ %1 = phi i32 [ %0 , %entry ], [ 42 , %x ]
157
+ ret i32 %1
158
+ }
159
+
160
+ ; Here we have output and a critical edge along an indirect branch.
161
+ ; Ensure that if we repeat the indirect destination, that we only split it
162
+ ; once.
163
+ define i32 @split_me1 (i1 %z ) {
164
+ ; CHECK-LABEL: @split_me1(
165
+ ; CHECK-NEXT: entry:
166
+ ; CHECK-NEXT: br i1 [[Z:%.*]], label [[W:%.*]], label [[V:%.*]]
167
+ ; CHECK: w:
168
+ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i"()
169
+ ; CHECK-NEXT: to label [[X:%.*]] [label [[W_V_CRIT_EDGE:%.*]], label %w.v_crit_edge]
170
+ ; CHECK: w.v_crit_edge:
171
+ ; CHECK-NEXT: br label [[V]]
172
+ ; CHECK: x:
173
+ ; CHECK-NEXT: ret i32 42
174
+ ; CHECK: v:
175
+ ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[W_V_CRIT_EDGE]] ], [ undef, [[ENTRY:%.*]] ]
176
+ ; CHECK-NEXT: ret i32 [[TMP1]]
177
+ ;
178
+ entry:
179
+ br i1 %z , label %w , label %v
180
+
181
+ w:
182
+ %0 = callbr i32 asm "" , "=r,!i,!i" ()
183
+ to label %x [label %v , label %v ]
184
+
185
+ x:
186
+ ret i32 42
187
+
188
+ v:
189
+ %1 = phi i32 [%0 , %w ], [%0 , %w ], [undef , %entry ]
190
+ ret i32 %1
191
+ }
192
+
193
+ ; A more interessting case of @split_me1. Check that we still only split the
194
+ ; critical edge from w to v once.
195
+ define i32 @split_me2 (i1 %z ) {
196
+ ; CHECK-LABEL: @split_me2(
197
+ ; CHECK-NEXT: entry:
198
+ ; CHECK-NEXT: br i1 [[Z:%.*]], label [[W:%.*]], label [[V:%.*]]
199
+ ; CHECK: w:
200
+ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i"()
201
+ ; CHECK-NEXT: to label [[X:%.*]] [label [[W_V_CRIT_EDGE:%.*]], label %w.v_crit_edge]
202
+ ; CHECK: w.v_crit_edge:
203
+ ; CHECK-NEXT: br label [[V]]
204
+ ; CHECK: x:
205
+ ; CHECK-NEXT: ret i32 42
206
+ ; CHECK: v:
207
+ ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[W_V_CRIT_EDGE]] ], [ 42, [[ENTRY:%.*]] ]
208
+ ; CHECK-NEXT: ret i32 [[TMP1]]
209
+ ;
210
+ entry:
211
+ br i1 %z , label %w , label %v
212
+
213
+ w:
214
+ %0 = callbr i32 asm "" , "=r,!i,!i" ()
215
+ to label %x [label %v , label %v ]
216
+
217
+ x:
218
+ ret i32 42
219
+
220
+ v:
221
+ %1 = phi i32 [ %0 , %w ], [ 42 , %entry ], [ %0 , %w ]
222
+ ret i32 %1
223
+ }
0 commit comments