[clang] Fix crashes when passing VLA to va_arg (#119563)
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / extend-wwm-virt-reg-liveness.mir
blob2f43c8264bf90ade9ff5d4592ddc6fb188f1ccb0
1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -start-before=si-lower-sgpr-spills -stop-after=virtregrewriter,1 -verify-machineinstrs %s -o - | FileCheck -check-prefix=GCN %s
4 # Tests to check the conservative lieness extension for the wwm registers during SGPR spill lowering.
6 # Even though the VGPR can be shared for the wwm-operand (writelane/readlane get inserted for the SGPR spills)
7 # and the regular operand (%0), they get different registers as we conservatively extend the liveness of the
8 # wwm-operands.
9 ---
10 name:            test_single_block
11 tracksRegLiveness: true
12 frameInfo:
13   maxAlignment:    4
14 stack:
15   - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }
16 machineFunctionInfo:
17   isEntryFunction: false
18   scratchRSrcReg:  '$sgpr0_sgpr1_sgpr2_sgpr3'
19   stackPtrOffsetReg: '$sgpr32'
20   frameOffsetReg: '$sgpr33'
21   hasSpilledSGPRs: true
22 body:             |
23   bb.0:
24     liveins: $sgpr4, $vgpr2_vgpr3
25     ; GCN-LABEL: name: test_single_block
26     ; GCN: liveins: $sgpr4, $vgpr2_vgpr3
27     ; GCN-NEXT: {{  $}}
28     ; GCN-NEXT: renamable $vgpr63 = IMPLICIT_DEF
29     ; GCN-NEXT: $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr63
30     ; GCN-NEXT: S_NOP 0
31     ; GCN-NEXT: $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0
32     ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
33     ; GCN-NEXT: GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_]], 0, 0, implicit $exec
34     ; GCN-NEXT: SI_RETURN
35     SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
36     S_NOP 0
37     renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
38     %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
39     GLOBAL_STORE_DWORD $vgpr2_vgpr3, %0:vgpr_32, 0, 0, implicit $exec
40     SI_RETURN
41 ...
43 # Due to the presence of wwm-operand in the divergent flow, the regular variable (%0) shouldn't get the same register
44 # allocated for the wwm-operand in writelane/readlane when the SGPR spill is lowered.
46 ---
47 name:            test_if_else
48 tracksRegLiveness: true
49 frameInfo:
50   maxAlignment:    4
51 stack:
52   - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }
53 machineFunctionInfo:
54   isEntryFunction: false
55   scratchRSrcReg:  '$sgpr0_sgpr1_sgpr2_sgpr3'
56   stackPtrOffsetReg: '$sgpr32'
57   frameOffsetReg: '$sgpr33'
58   hasSpilledSGPRs: true
59 body:             |
60   ; GCN-LABEL: name: test_if_else
61   ; GCN: bb.0:
62   ; GCN-NEXT:   successors: %bb.1(0x80000000)
63   ; GCN-NEXT:   liveins: $sgpr6, $sgpr10_sgpr11
64   ; GCN-NEXT: {{  $}}
65   ; GCN-NEXT:   S_BRANCH %bb.1
66   ; GCN-NEXT: {{  $}}
67   ; GCN-NEXT: bb.1:
68   ; GCN-NEXT:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
69   ; GCN-NEXT:   liveins: $sgpr6, $sgpr10_sgpr11
70   ; GCN-NEXT: {{  $}}
71   ; GCN-NEXT:   [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
72   ; GCN-NEXT:   S_CBRANCH_EXECZ %bb.3, implicit $exec
73   ; GCN-NEXT: {{  $}}
74   ; GCN-NEXT: bb.2:
75   ; GCN-NEXT:   successors: %bb.3(0x80000000)
76   ; GCN-NEXT:   liveins: $sgpr6, $sgpr10_sgpr11
77   ; GCN-NEXT: {{  $}}
78   ; GCN-NEXT:   renamable $vgpr63 = IMPLICIT_DEF
79   ; GCN-NEXT:   $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr6, 0, killed $vgpr63
80   ; GCN-NEXT:   S_NOP 0
81   ; GCN-NEXT:   $sgpr6 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0
82   ; GCN-NEXT:   [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
83   ; GCN-NEXT:   S_BRANCH %bb.3
84   ; GCN-NEXT: {{  $}}
85   ; GCN-NEXT: bb.3:
86   ; GCN-NEXT:   liveins: $sgpr10_sgpr11
87   ; GCN-NEXT: {{  $}}
88   ; GCN-NEXT:   $sgpr5 = V_READFIRSTLANE_B32 [[V_MOV_B32_e32_]], implicit $exec
89   ; GCN-NEXT:   S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 0
90   ; GCN-NEXT:   SI_RETURN
91   bb.0:
92     liveins: $sgpr6, $sgpr10_sgpr11
93     S_BRANCH %bb.1
94   bb.1:
95     liveins: $sgpr6, $sgpr10_sgpr11
96     %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
97     S_CBRANCH_EXECZ %bb.3, implicit $exec
98   bb.2:
99     liveins: $sgpr6, $sgpr10_sgpr11
100     SI_SPILL_S32_SAVE killed $sgpr6, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
101     S_NOP 0
102     renamable $sgpr6 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
103     %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
104     S_BRANCH %bb.3
105   bb.3:
106     liveins: $sgpr10_sgpr11
107     $sgpr5 = V_READFIRSTLANE_B32 %0:vgpr_32, implicit $exec
108     S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 0
109     SI_RETURN
112 # The wwm-register usage outside the loop should have the interference marked with
113 # all the regular virtual registers used in the test. The divergent loop index value (%1)
114 # can actually share the same VGPR as the wwm-operand. But since we extend the liveness of
115 # the wwm operand, an interference will always exist between them.
118 name:            test_loop
119 tracksRegLiveness: true
120 frameInfo:
121   maxAlignment:    4
122 stack:
123   - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }
124 machineFunctionInfo:
125   isEntryFunction: false
126   scratchRSrcReg:  '$sgpr0_sgpr1_sgpr2_sgpr3'
127   stackPtrOffsetReg: '$sgpr32'
128   frameOffsetReg: '$sgpr33'
129   hasSpilledSGPRs: true
130 body:             |
131   ; GCN-LABEL: name: test_loop
132   ; GCN: bb.0:
133   ; GCN-NEXT:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
134   ; GCN-NEXT:   liveins: $sgpr4, $sgpr10_sgpr11
135   ; GCN-NEXT: {{  $}}
136   ; GCN-NEXT:   [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
137   ; GCN-NEXT:   S_CBRANCH_EXECZ %bb.2, implicit $exec
138   ; GCN-NEXT: {{  $}}
139   ; GCN-NEXT: bb.1:
140   ; GCN-NEXT:   successors: %bb.2(0x80000000)
141   ; GCN-NEXT:   liveins: $sgpr4, $sgpr10_sgpr11
142   ; GCN-NEXT: {{  $}}
143   ; GCN-NEXT:   renamable $vgpr63 = IMPLICIT_DEF
144   ; GCN-NEXT:   $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr63
145   ; GCN-NEXT:   S_NOP 0
146   ; GCN-NEXT:   $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0
147   ; GCN-NEXT:   [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
148   ; GCN-NEXT:   S_BRANCH %bb.2
149   ; GCN-NEXT: {{  $}}
150   ; GCN-NEXT: bb.2:
151   ; GCN-NEXT:   successors: %bb.3(0x80000000)
152   ; GCN-NEXT:   liveins: $sgpr4, $sgpr10_sgpr11
153   ; GCN-NEXT: {{  $}}
154   ; GCN-NEXT:   S_STORE_DWORD_IMM $sgpr4, $sgpr10_sgpr11, 0, 0
155   ; GCN-NEXT:   $sgpr5 = V_READFIRSTLANE_B32 [[V_MOV_B32_e32_]], implicit $exec
156   ; GCN-NEXT:   S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 4
157   ; GCN-NEXT:   [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 5, implicit $exec
158   ; GCN-NEXT:   S_CBRANCH_EXECZ %bb.3, implicit $exec
159   ; GCN-NEXT:   S_BRANCH %bb.3
160   ; GCN-NEXT: {{  $}}
161   ; GCN-NEXT: bb.3:
162   ; GCN-NEXT:   successors: %bb.5(0x40000000), %bb.4(0x40000000)
163   ; GCN-NEXT: {{  $}}
164   ; GCN-NEXT:   $vcc = V_CMP_EQ_U32_e64 0, [[V_MOV_B32_e32_1]], implicit $exec
165   ; GCN-NEXT:   $sgpr6_sgpr7 = S_AND_SAVEEXEC_B64 $vcc, implicit-def $exec, implicit-def $scc, implicit $exec
166   ; GCN-NEXT:   S_CBRANCH_SCC1 %bb.5, implicit $scc
167   ; GCN-NEXT: {{  $}}
168   ; GCN-NEXT: bb.4:
169   ; GCN-NEXT:   successors: %bb.3(0x80000000)
170   ; GCN-NEXT:   liveins: $sgpr6_sgpr7
171   ; GCN-NEXT: {{  $}}
172   ; GCN-NEXT:   [[V_SUB_U32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_U32_e32 1, [[V_MOV_B32_e32_1]], implicit $exec
173   ; GCN-NEXT:   [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[V_SUB_U32_e32_]], implicit $exec
174   ; GCN-NEXT:   S_BRANCH %bb.3
175   ; GCN-NEXT: {{  $}}
176   ; GCN-NEXT: bb.5:
177   ; GCN-NEXT:   liveins: $sgpr6_sgpr7
178   ; GCN-NEXT: {{  $}}
179   ; GCN-NEXT:   $exec = S_OR_B64 $exec, $sgpr6_sgpr7, implicit-def $scc
180   ; GCN-NEXT:   SI_RETURN
181   bb.0:
182     liveins: $sgpr4, $sgpr10_sgpr11
183     %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
184     S_CBRANCH_EXECZ %bb.2, implicit $exec
185   bb.1:
186     liveins: $sgpr4, $sgpr10_sgpr11
187     SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
188     S_NOP 0
189     renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
190     %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
191     S_BRANCH %bb.2
192   bb.2:
193     liveins: $sgpr4, $sgpr10_sgpr11
194     S_STORE_DWORD_IMM $sgpr4, $sgpr10_sgpr11, 0, 0
195     $sgpr5 = V_READFIRSTLANE_B32 %0:vgpr_32, implicit $exec
196     S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 4
197     %1:vgpr_32 = V_MOV_B32_e32 5, implicit $exec
198     S_CBRANCH_EXECZ %bb.3, implicit $exec
199     S_BRANCH %bb.3
200   bb.3:
201     $vcc = V_CMP_EQ_U32_e64 0, %1:vgpr_32, implicit $exec
202     $sgpr6_sgpr7 = S_AND_SAVEEXEC_B64 $vcc, implicit-def $exec, implicit-def $scc, implicit $exec
203     S_CBRANCH_SCC1 %bb.5, implicit $scc
204   bb.4:
205     liveins: $sgpr6_sgpr7
206     %2:vgpr_32 = V_SUB_U32_e32 1, %1:vgpr_32, implicit $exec
207     %1:vgpr_32 = V_MOV_B32_e32 %2:vgpr_32, implicit $exec
208     S_BRANCH %bb.3
209   bb.5:
210     liveins: $sgpr6_sgpr7
211     $exec = S_OR_B64 $exec, $sgpr6_sgpr7, implicit-def $scc
212     SI_RETURN
215 # There must be one KILL instruction for the wwm-operand in every return block.
216 # Due to that, the wwm-register allocated should be different from the ones
217 # allocated for the regular virtual registers.
220 name:            test_multiple_return_blocks
221 tracksRegLiveness: true
222 frameInfo:
223   maxAlignment:    4
224 stack:
225   - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }
226 machineFunctionInfo:
227   isEntryFunction: false
228   scratchRSrcReg:  '$sgpr0_sgpr1_sgpr2_sgpr3'
229   stackPtrOffsetReg: '$sgpr32'
230   frameOffsetReg: '$sgpr33'
231   hasSpilledSGPRs: true
232 body:             |
233   ; GCN-LABEL: name: test_multiple_return_blocks
234   ; GCN: bb.0:
235   ; GCN-NEXT:   successors: %bb.2(0x40000000), %bb.1(0x40000000)
236   ; GCN-NEXT:   liveins: $sgpr4, $vgpr2_vgpr3
237   ; GCN-NEXT: {{  $}}
238   ; GCN-NEXT:   S_CBRANCH_EXECZ %bb.2, implicit $exec
239   ; GCN-NEXT: {{  $}}
240   ; GCN-NEXT: bb.1:
241   ; GCN-NEXT:   liveins: $sgpr4, $vgpr2_vgpr3
242   ; GCN-NEXT: {{  $}}
243   ; GCN-NEXT:   renamable $vgpr63 = IMPLICIT_DEF
244   ; GCN-NEXT:   $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr63
245   ; GCN-NEXT:   S_NOP 0
246   ; GCN-NEXT:   $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0
247   ; GCN-NEXT:   [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
248   ; GCN-NEXT:   GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_]], 0, 0, implicit $exec
249   ; GCN-NEXT:   SI_RETURN
250   ; GCN-NEXT: {{  $}}
251   ; GCN-NEXT: bb.2:
252   ; GCN-NEXT:   liveins: $vgpr2_vgpr3
253   ; GCN-NEXT: {{  $}}
254   ; GCN-NEXT:   [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
255   ; GCN-NEXT:   GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_1]], 0, 0, implicit $exec
256   ; GCN-NEXT:   SI_RETURN
257   bb.0:
258     liveins: $sgpr4, $vgpr2_vgpr3
259     S_CBRANCH_EXECZ %bb.2, implicit $exec
260   bb.1:
261     liveins: $sgpr4, $vgpr2_vgpr3
262     SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
263     S_NOP 0
264     renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32
265     %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec
266     GLOBAL_STORE_DWORD $vgpr2_vgpr3, %0:vgpr_32, 0, 0, implicit $exec
267     SI_RETURN
268   bb.2:
269     liveins: $vgpr2_vgpr3
270     %1:vgpr_32 = V_MOV_B32_e32 20, implicit $exec
271     GLOBAL_STORE_DWORD $vgpr2_vgpr3, %1:vgpr_32, 0, 0, implicit $exec
272     SI_RETURN