1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -verify-coalescing -verify-machineinstrs -start-before=simple-register-coalescing -stop-after=machine-scheduler -o - %s | FileCheck %s
3
4# Tests that break due to the handling of partially undef registers
5# when whole register identity copies are erased.
6
7# Make sure there is no verifier error after
8# RenameIndepependentSubregs processes this. The coalescer would
9# remove the identity copy in %bb.1, and leave behind a dummy interval
10# across bb.1 with no corresponding value anywhere in the function.
11
12---
13name:            identity_copy_undef_subrange
14tracksRegLiveness: true
15body:             |
16  ; CHECK-LABEL: name: identity_copy_undef_subrange
17  ; CHECK: bb.0:
18  ; CHECK:   successors: %bb.1(0x80000000)
19  ; CHECK:   liveins: $vgpr0
20  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
21  ; CHECK: bb.1:
22  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
23  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
24  ; CHECK:   S_BRANCH %bb.2
25  ; CHECK: bb.2:
26  ; CHECK:   successors: %bb.1(0x80000000)
27  ; CHECK:   undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
28  ; CHECK:   S_BRANCH %bb.1
29  bb.0:
30    liveins: $vgpr0
31
32    undef %0.sub1:vreg_64 = COPY killed $vgpr0
33
34  bb.1:
35    successors: %bb.2, %bb.1
36
37    %0:vreg_64 = COPY %0
38    S_CBRANCH_EXECNZ %bb.1, implicit $exec
39    S_BRANCH %bb.2
40
41  bb.2:
42    undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec
43    S_BRANCH %bb.1
44
45...
46
47# Test another use of the register inside the block.
48---
49name:            identity_copy_undef_subrange_other_uses0
50tracksRegLiveness: true
51body:             |
52  ; CHECK-LABEL: name: identity_copy_undef_subrange_other_uses0
53  ; CHECK: bb.0:
54  ; CHECK:   successors: %bb.1(0x80000000)
55  ; CHECK:   liveins: $vgpr0
56  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
57  ; CHECK: bb.1:
58  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
59  ; CHECK:   S_NOP 0, implicit undef %0.sub0
60  ; CHECK:   S_NOP 0, implicit undef %0.sub0
61  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
62  ; CHECK:   S_BRANCH %bb.2
63  ; CHECK: bb.2:
64  ; CHECK:   successors: %bb.1(0x80000000)
65  ; CHECK:   undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
66  ; CHECK:   S_BRANCH %bb.1
67  bb.0:
68    liveins: $vgpr0
69    undef %0.sub1:vreg_64 = COPY killed $vgpr0
70
71  bb.1:
72    successors: %bb.2, %bb.1
73
74    %0:vreg_64 = COPY %0
75    S_NOP 0, implicit %0.sub0
76    S_NOP 0, implicit %0.sub0
77    S_CBRANCH_EXECNZ %bb.1, implicit $exec
78    S_BRANCH %bb.2
79
80  bb.2:
81    undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec
82    S_BRANCH %bb.1
83
84...
85
86---
87name: second_identity_copy
88tracksRegLiveness: true
89body:             |
90  ; CHECK-LABEL: name: second_identity_copy
91  ; CHECK: bb.0:
92  ; CHECK:   successors: %bb.1(0x80000000)
93  ; CHECK:   liveins: $vgpr0
94  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
95  ; CHECK: bb.1:
96  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
97  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
98  ; CHECK:   S_BRANCH %bb.2
99  ; CHECK: bb.2:
100  ; CHECK:   successors: %bb.1(0x80000000)
101  ; CHECK:   undef %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, %0.sub1, implicit $mode, implicit $exec
102  ; CHECK:   S_BRANCH %bb.1
103  bb.0:
104    liveins: $vgpr0
105
106    undef %0.sub1:vreg_64 = COPY killed $vgpr0
107
108  bb.1:
109    successors: %bb.2, %bb.1
110
111    %0:vreg_64 = COPY killed %0
112    %0:vreg_64 = COPY %0
113    S_CBRANCH_EXECNZ %bb.1, implicit $exec
114    S_BRANCH %bb.2
115
116  bb.2:
117    undef %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, killed %0.sub1, implicit $mode, implicit $exec
118    S_BRANCH %bb.1
119
120...
121
122---
123name: second_identity_copy_undef_lane_outblock
124tracksRegLiveness: true
125body:             |
126  ; CHECK-LABEL: name: second_identity_copy_undef_lane_outblock
127  ; CHECK: bb.0:
128  ; CHECK:   successors: %bb.1(0x80000000)
129  ; CHECK:   liveins: $vgpr0
130  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
131  ; CHECK: bb.1:
132  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
133  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
134  ; CHECK:   S_BRANCH %bb.2
135  ; CHECK: bb.2:
136  ; CHECK:   successors: %bb.1(0x80000000)
137  ; CHECK:   %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, %0.sub1, implicit $mode, implicit $exec
138  ; CHECK:   S_BRANCH %bb.1
139  bb.0:
140    liveins: $vgpr0
141
142    undef %0.sub1:vreg_64 = COPY killed $vgpr0
143
144  bb.1:
145    successors: %bb.2, %bb.1
146
147    %0:vreg_64 = COPY killed %0
148    %0:vreg_64 = COPY %0
149    S_CBRANCH_EXECNZ %bb.1, implicit $exec
150    S_BRANCH %bb.2
151
152  bb.2:
153    %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, killed %0.sub1, implicit $mode, implicit $exec
154    S_BRANCH %bb.1
155
156...
157
158# The same value number appears in multiple blocks
159---
160name: identity_copy_undef_subrange_null_vninfo_to_remove
161tracksRegLiveness: true
162body:             |
163  ; CHECK-LABEL: name: identity_copy_undef_subrange_null_vninfo_to_remove
164  ; CHECK: bb.0:
165  ; CHECK:   successors: %bb.1(0x80000000)
166  ; CHECK:   liveins: $vgpr0
167  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
168  ; CHECK: bb.1:
169  ; CHECK:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
170  ; CHECK:   S_CBRANCH_EXECNZ %bb.3, implicit $exec
171  ; CHECK: bb.2:
172  ; CHECK:   successors: %bb.1(0x80000000)
173  ; CHECK:   S_NOP 0, implicit undef %0.sub0
174  ; CHECK:   undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
175  ; CHECK:   S_BRANCH %bb.1
176  ; CHECK: bb.3:
177  ; CHECK:   S_NOP 0, implicit undef %0.sub0
178  bb.0:
179    liveins: $vgpr0
180
181    undef %0.sub1:vreg_64 = COPY killed $vgpr0
182
183  bb.1:
184    %0:vreg_64 = COPY %0
185    S_CBRANCH_EXECNZ %bb.3, implicit $exec
186
187  bb.2:
188    S_NOP 0, implicit %0.sub0
189    undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec
190    S_BRANCH %bb.1
191
192  bb.3:
193    S_NOP 0, implicit %0.sub0
194
195...
196
197---
198name: undef_copy_self_loop0
199tracksRegLiveness: true
200body:             |
201  ; CHECK-LABEL: name: undef_copy_self_loop0
202  ; CHECK: bb.0:
203  ; CHECK:   successors: %bb.1(0x80000000)
204  ; CHECK:   liveins: $vgpr0
205  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
206  ; CHECK: bb.1:
207  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
208  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
209  ; CHECK: bb.2:
210  ; CHECK:   S_NOP 0, implicit undef %0.sub0
211  bb.0:
212    liveins: $vgpr0
213
214    undef %0.sub1:vreg_64 = COPY killed $vgpr0
215
216  bb.1:
217    %0:vreg_64 = COPY %0
218    S_CBRANCH_EXECNZ %bb.1, implicit $exec
219
220  bb.2:
221    S_NOP 0, implicit %0.sub0
222
223...
224
225---
226name: undef_copy_self_loop1
227tracksRegLiveness: true
228body:             |
229  ; CHECK-LABEL: name: undef_copy_self_loop1
230  ; CHECK: bb.0:
231  ; CHECK:   successors: %bb.1(0x80000000)
232  ; CHECK:   liveins: $vgpr0
233  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
234  ; CHECK: bb.1:
235  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
236  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
237  ; CHECK: bb.2:
238  ; CHECK:   S_NOP 0, implicit %0.sub1
239  bb.0:
240    liveins: $vgpr0
241
242    undef %0.sub1:vreg_64 = COPY killed $vgpr0
243
244  bb.1:
245    %0:vreg_64 = COPY %0
246    S_CBRANCH_EXECNZ %bb.1, implicit $exec
247
248  bb.2:
249    S_NOP 0, implicit %0.sub1
250
251...
252
253# The coalescing of the %0 = %2 COPY in %bb.2 needs to prune the dead
254# phi range across %bb.1 after it is erased.
255---
256name: prune_subrange_phi_value_0
257tracksRegLiveness: true
258body:             |
259  ; CHECK-LABEL: name: prune_subrange_phi_value_0
260  ; CHECK: bb.0:
261  ; CHECK:   successors: %bb.1(0x80000000)
262  ; CHECK:   liveins: $vgpr0
263  ; CHECK:   undef %2.sub1:vreg_64 = COPY $vgpr0
264  ; CHECK: bb.1:
265  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
266  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
267  ; CHECK:   S_BRANCH %bb.2
268  ; CHECK: bb.2:
269  ; CHECK:   successors: %bb.1(0x80000000)
270  ; CHECK:   S_BRANCH %bb.1
271  bb.0:
272    liveins: $vgpr0
273
274    undef %0.sub1:vreg_64 = COPY killed $vgpr0
275
276  bb.1:
277    successors: %bb.2, %bb.1
278
279    %1:vreg_64 = COPY killed %0
280    %0:vreg_64 = COPY %1
281    S_CBRANCH_EXECNZ %bb.1, implicit $exec
282    S_BRANCH %bb.2
283
284  bb.2:
285    undef %2.sub1:vreg_64 = COPY %0.sub1
286    %0:vreg_64 = COPY killed %2
287    S_BRANCH %bb.1
288
289...
290
291---
292name: prune_subrange_phi_value_0_0
293tracksRegLiveness: true
294body:             |
295  ; CHECK-LABEL: name: prune_subrange_phi_value_0_0
296  ; CHECK: bb.0:
297  ; CHECK:   successors: %bb.1(0x80000000)
298  ; CHECK:   liveins: $vgpr0
299  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
300  ; CHECK: bb.1:
301  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
302  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
303  ; CHECK:   S_BRANCH %bb.2
304  ; CHECK: bb.2:
305  ; CHECK:   successors: %bb.1(0x80000000)
306  ; CHECK:   S_BRANCH %bb.1
307  bb.0:
308    liveins: $vgpr0
309
310    undef %0.sub1:vreg_64 = COPY killed $vgpr0
311
312  bb.1:
313    successors: %bb.2, %bb.1
314
315    %1:vreg_64 = COPY killed %0
316    %0:vreg_64 = COPY %1
317    S_CBRANCH_EXECNZ %bb.1, implicit $exec
318    S_BRANCH %bb.2
319
320  bb.2:
321    undef %0.sub1:vreg_64 = COPY %0.sub1
322    S_BRANCH %bb.1
323
324...
325
326---
327name: prune_subrange_phi_value_0_1
328tracksRegLiveness: true
329body:             |
330  ; CHECK-LABEL: name: prune_subrange_phi_value_0_1
331  ; CHECK: bb.0:
332  ; CHECK:   successors: %bb.1(0x80000000)
333  ; CHECK:   liveins: $vgpr0
334  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
335  ; CHECK: bb.1:
336  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
337  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
338  ; CHECK:   S_BRANCH %bb.2
339  ; CHECK: bb.2:
340  ; CHECK:   successors: %bb.1(0x80000000)
341  ; CHECK:   S_BRANCH %bb.1
342  bb.0:
343    liveins: $vgpr0
344
345    undef %0.sub1:vreg_64 = COPY killed $vgpr0
346
347  bb.1:
348    successors: %bb.2, %bb.1
349
350    %1:vreg_64 = COPY killed %0
351    %0:vreg_64 = COPY %1
352    S_CBRANCH_EXECNZ %bb.1, implicit $exec
353    S_BRANCH %bb.2
354
355  bb.2:
356    S_BRANCH %bb.1
357
358...
359
360# Variant of testcase that asserts since there wasn't already an
361# incoming segment at the erased copy, and no valid end point.
362---
363name:            prune_subrange_phi_value_1
364tracksRegLiveness: true
365body:             |
366  ; CHECK-LABEL: name: prune_subrange_phi_value_1
367  ; CHECK: bb.0:
368  ; CHECK:   successors: %bb.1(0x80000000)
369  ; CHECK:   liveins: $vgpr0
370  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
371  ; CHECK: bb.1:
372  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
373  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
374  ; CHECK:   S_BRANCH %bb.2
375  ; CHECK: bb.2:
376  ; CHECK:   successors: %bb.1(0x80000000)
377  ; CHECK:   undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
378  ; CHECK:   S_BRANCH %bb.1
379  bb.0:
380    liveins: $vgpr0
381
382    undef %0.sub1:vreg_64 = COPY killed $vgpr0
383
384  bb.1:
385    successors: %bb.2, %bb.1
386
387    %0:vreg_64 = COPY killed %0
388    S_CBRANCH_EXECNZ %bb.1, implicit $exec
389    S_BRANCH %bb.2
390
391  bb.2:
392    undef %1.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec
393    %0:vreg_64 = COPY killed %1
394    S_BRANCH %bb.1
395
396...
397
398---
399name:            prune_subrange_phi_value_2
400tracksRegLiveness: true
401body:             |
402  ; CHECK-LABEL: name: prune_subrange_phi_value_2
403  ; CHECK: bb.0:
404  ; CHECK:   successors: %bb.1(0x80000000)
405  ; CHECK:   liveins: $vgpr0
406  ; CHECK:   undef %0.sub1:vreg_64 = COPY $vgpr0
407  ; CHECK: bb.1:
408  ; CHECK:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
409  ; CHECK:   S_CBRANCH_EXECNZ %bb.1, implicit $exec
410  ; CHECK:   S_BRANCH %bb.2
411  ; CHECK: bb.2:
412  ; CHECK:   successors: %bb.1(0x80000000)
413  ; CHECK:   %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
414  ; CHECK:   S_BRANCH %bb.1
415  bb.0:
416    liveins: $vgpr0
417
418    undef %0.sub1:vreg_64 = COPY killed $vgpr0
419
420  bb.1:
421    successors: %bb.2, %bb.1
422
423    %0:vreg_64 = COPY killed %0
424    S_CBRANCH_EXECNZ %bb.1, implicit $exec
425    S_BRANCH %bb.2
426
427  bb.2:
428    %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec
429    S_BRANCH %bb.1
430
431...
432