274 lines · plain
1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py2# 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 %s3 4# Tests to check the conservative lieness extension for the wwm registers during SGPR spill lowering.5 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 the8# wwm-operands.9---10name: test_single_block11tracksRegLiveness: true12frameInfo:13 maxAlignment: 414stack:15 - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }16machineFunctionInfo:17 isEntryFunction: false18 scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'19 stackPtrOffsetReg: '$sgpr32'20 frameOffsetReg: '$sgpr33'21 hasSpilledSGPRs: true22body: |23 bb.0:24 liveins: $sgpr4, $vgpr2_vgpr325 ; GCN-LABEL: name: test_single_block26 ; GCN: liveins: $sgpr4, $vgpr2_vgpr327 ; GCN-NEXT: {{ $}}28 ; GCN-NEXT: renamable $vgpr63 = IMPLICIT_DEF29 ; GCN-NEXT: $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr6330 ; GCN-NEXT: S_NOP 031 ; GCN-NEXT: $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 032 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec33 ; GCN-NEXT: GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_]], 0, 0, implicit $exec34 ; GCN-NEXT: SI_RETURN35 SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr3236 S_NOP 037 renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr3238 %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec39 GLOBAL_STORE_DWORD $vgpr2_vgpr3, %0:vgpr_32, 0, 0, implicit $exec40 SI_RETURN41...42 43# Due to the presence of wwm-operand in the divergent flow, the regular variable (%0) shouldn't get the same register44# allocated for the wwm-operand in writelane/readlane when the SGPR spill is lowered.45 46---47name: test_if_else48tracksRegLiveness: true49frameInfo:50 maxAlignment: 451stack:52 - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }53machineFunctionInfo:54 isEntryFunction: false55 scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'56 stackPtrOffsetReg: '$sgpr32'57 frameOffsetReg: '$sgpr33'58 hasSpilledSGPRs: true59body: |60 ; GCN-LABEL: name: test_if_else61 ; GCN: bb.0:62 ; GCN-NEXT: successors: %bb.1(0x80000000)63 ; GCN-NEXT: liveins: $sgpr6, $sgpr10_sgpr1164 ; GCN-NEXT: {{ $}}65 ; GCN-NEXT: S_BRANCH %bb.166 ; GCN-NEXT: {{ $}}67 ; GCN-NEXT: bb.1:68 ; GCN-NEXT: successors: %bb.3(0x40000000), %bb.2(0x40000000)69 ; GCN-NEXT: liveins: $sgpr6, $sgpr10_sgpr1170 ; GCN-NEXT: {{ $}}71 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec72 ; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec73 ; GCN-NEXT: {{ $}}74 ; GCN-NEXT: bb.2:75 ; GCN-NEXT: successors: %bb.3(0x80000000)76 ; GCN-NEXT: liveins: $sgpr6, $sgpr10_sgpr1177 ; GCN-NEXT: {{ $}}78 ; GCN-NEXT: renamable $vgpr63 = IMPLICIT_DEF79 ; GCN-NEXT: $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr6, 0, killed $vgpr6380 ; GCN-NEXT: S_NOP 081 ; GCN-NEXT: $sgpr6 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 082 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec83 ; GCN-NEXT: S_BRANCH %bb.384 ; GCN-NEXT: {{ $}}85 ; GCN-NEXT: bb.3:86 ; GCN-NEXT: liveins: $sgpr10_sgpr1187 ; GCN-NEXT: {{ $}}88 ; GCN-NEXT: $sgpr5 = V_READFIRSTLANE_B32 [[V_MOV_B32_e32_]], implicit $exec89 ; GCN-NEXT: S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 090 ; GCN-NEXT: SI_RETURN91 bb.0:92 liveins: $sgpr6, $sgpr10_sgpr1193 S_BRANCH %bb.194 bb.1:95 liveins: $sgpr6, $sgpr10_sgpr1196 %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec97 S_CBRANCH_EXECZ %bb.3, implicit $exec98 bb.2:99 liveins: $sgpr6, $sgpr10_sgpr11100 SI_SPILL_S32_SAVE killed $sgpr6, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32101 S_NOP 0102 renamable $sgpr6 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32103 %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec104 S_BRANCH %bb.3105 bb.3:106 liveins: $sgpr10_sgpr11107 $sgpr5 = V_READFIRSTLANE_B32 %0:vgpr_32, implicit $exec108 S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 0109 SI_RETURN110...111 112# The wwm-register usage outside the loop should have the interference marked with113# 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 of115# the wwm operand, an interference will always exist between them.116 117---118name: test_loop119tracksRegLiveness: true120frameInfo:121 maxAlignment: 4122stack:123 - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }124machineFunctionInfo:125 isEntryFunction: false126 scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'127 stackPtrOffsetReg: '$sgpr32'128 frameOffsetReg: '$sgpr33'129 hasSpilledSGPRs: true130body: |131 ; GCN-LABEL: name: test_loop132 ; GCN: bb.0:133 ; GCN-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)134 ; GCN-NEXT: liveins: $sgpr4, $sgpr10_sgpr11135 ; GCN-NEXT: {{ $}}136 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec137 ; GCN-NEXT: S_CBRANCH_EXECZ %bb.2, implicit $exec138 ; GCN-NEXT: {{ $}}139 ; GCN-NEXT: bb.1:140 ; GCN-NEXT: successors: %bb.2(0x80000000)141 ; GCN-NEXT: liveins: $sgpr4, $sgpr10_sgpr11142 ; GCN-NEXT: {{ $}}143 ; GCN-NEXT: renamable $vgpr63 = IMPLICIT_DEF144 ; GCN-NEXT: $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr63145 ; GCN-NEXT: S_NOP 0146 ; GCN-NEXT: $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0147 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec148 ; GCN-NEXT: S_BRANCH %bb.2149 ; GCN-NEXT: {{ $}}150 ; GCN-NEXT: bb.2:151 ; GCN-NEXT: successors: %bb.3(0x80000000)152 ; GCN-NEXT: liveins: $sgpr4, $sgpr10_sgpr11153 ; GCN-NEXT: {{ $}}154 ; GCN-NEXT: S_STORE_DWORD_IMM $sgpr4, $sgpr10_sgpr11, 0, 0155 ; GCN-NEXT: $sgpr5 = V_READFIRSTLANE_B32 [[V_MOV_B32_e32_]], implicit $exec156 ; GCN-NEXT: S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 4157 ; GCN-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 5, implicit $exec158 ; GCN-NEXT: S_CBRANCH_EXECZ %bb.3, implicit $exec159 ; GCN-NEXT: S_BRANCH %bb.3160 ; 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 $exec165 ; GCN-NEXT: $sgpr6_sgpr7 = S_AND_SAVEEXEC_B64 $vcc, implicit-def $exec, implicit-def $scc, implicit $exec166 ; GCN-NEXT: S_CBRANCH_SCC1 %bb.5, implicit $scc167 ; GCN-NEXT: {{ $}}168 ; GCN-NEXT: bb.4:169 ; GCN-NEXT: successors: %bb.3(0x80000000)170 ; GCN-NEXT: liveins: $sgpr6_sgpr7171 ; GCN-NEXT: {{ $}}172 ; GCN-NEXT: [[V_SUB_U32_e32_:%[0-9]+]]:vgpr_32 = V_SUB_U32_e32 1, [[V_MOV_B32_e32_1]], implicit $exec173 ; GCN-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[V_SUB_U32_e32_]], implicit $exec174 ; GCN-NEXT: S_BRANCH %bb.3175 ; GCN-NEXT: {{ $}}176 ; GCN-NEXT: bb.5:177 ; GCN-NEXT: liveins: $sgpr6_sgpr7178 ; GCN-NEXT: {{ $}}179 ; GCN-NEXT: $exec = S_OR_B64 $exec, $sgpr6_sgpr7, implicit-def $scc180 ; GCN-NEXT: SI_RETURN181 bb.0:182 liveins: $sgpr4, $sgpr10_sgpr11183 %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec184 S_CBRANCH_EXECZ %bb.2, implicit $exec185 bb.1:186 liveins: $sgpr4, $sgpr10_sgpr11187 SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32188 S_NOP 0189 renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32190 %0:vgpr_32 = V_MOV_B32_e32 20, implicit $exec191 S_BRANCH %bb.2192 bb.2:193 liveins: $sgpr4, $sgpr10_sgpr11194 S_STORE_DWORD_IMM $sgpr4, $sgpr10_sgpr11, 0, 0195 $sgpr5 = V_READFIRSTLANE_B32 %0:vgpr_32, implicit $exec196 S_STORE_DWORD_IMM $sgpr5, $sgpr10_sgpr11, 0, 4197 %1:vgpr_32 = V_MOV_B32_e32 5, implicit $exec198 S_CBRANCH_EXECZ %bb.3, implicit $exec199 S_BRANCH %bb.3200 bb.3:201 $vcc = V_CMP_EQ_U32_e64 0, %1:vgpr_32, implicit $exec202 $sgpr6_sgpr7 = S_AND_SAVEEXEC_B64 $vcc, implicit-def $exec, implicit-def $scc, implicit $exec203 S_CBRANCH_SCC1 %bb.5, implicit $scc204 bb.4:205 liveins: $sgpr6_sgpr7206 %2:vgpr_32 = V_SUB_U32_e32 1, %1:vgpr_32, implicit $exec207 %1:vgpr_32 = V_MOV_B32_e32 %2:vgpr_32, implicit $exec208 S_BRANCH %bb.3209 bb.5:210 liveins: $sgpr6_sgpr7211 $exec = S_OR_B64 $exec, $sgpr6_sgpr7, implicit-def $scc212 SI_RETURN213...214 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 ones217# allocated for the regular virtual registers.218 219---220name: test_multiple_return_blocks221tracksRegLiveness: true222frameInfo:223 maxAlignment: 4224stack:225 - { id: 0, type: spill-slot, size: 4, alignment: 4, stack-id: sgpr-spill }226machineFunctionInfo:227 isEntryFunction: false228 scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'229 stackPtrOffsetReg: '$sgpr32'230 frameOffsetReg: '$sgpr33'231 hasSpilledSGPRs: true232body: |233 ; GCN-LABEL: name: test_multiple_return_blocks234 ; GCN: bb.0:235 ; GCN-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)236 ; GCN-NEXT: liveins: $sgpr4, $vgpr2_vgpr3237 ; GCN-NEXT: {{ $}}238 ; GCN-NEXT: S_CBRANCH_EXECZ %bb.2, implicit $exec239 ; GCN-NEXT: {{ $}}240 ; GCN-NEXT: bb.1:241 ; GCN-NEXT: liveins: $sgpr4, $vgpr2_vgpr3242 ; GCN-NEXT: {{ $}}243 ; GCN-NEXT: renamable $vgpr63 = IMPLICIT_DEF244 ; GCN-NEXT: $vgpr63 = SI_SPILL_S32_TO_VGPR $sgpr4, 0, killed $vgpr63245 ; GCN-NEXT: S_NOP 0246 ; GCN-NEXT: $sgpr4 = SI_RESTORE_S32_FROM_VGPR killed $vgpr63, 0247 ; GCN-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec248 ; GCN-NEXT: GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_]], 0, 0, implicit $exec249 ; GCN-NEXT: SI_RETURN250 ; GCN-NEXT: {{ $}}251 ; GCN-NEXT: bb.2:252 ; GCN-NEXT: liveins: $vgpr2_vgpr3253 ; GCN-NEXT: {{ $}}254 ; GCN-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 20, implicit $exec255 ; GCN-NEXT: GLOBAL_STORE_DWORD $vgpr2_vgpr3, [[V_MOV_B32_e32_1]], 0, 0, implicit $exec256 ; GCN-NEXT: SI_RETURN257 bb.0:258 liveins: $sgpr4, $vgpr2_vgpr3259 S_CBRANCH_EXECZ %bb.2, implicit $exec260 bb.1:261 liveins: $sgpr4, $vgpr2_vgpr3262 SI_SPILL_S32_SAVE killed $sgpr4, %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32263 S_NOP 0264 renamable $sgpr4 = SI_SPILL_S32_RESTORE %stack.0, implicit $exec, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr32265 %0:vgpr_32 = V_MOV_B32_e32 10, implicit $exec266 GLOBAL_STORE_DWORD $vgpr2_vgpr3, %0:vgpr_32, 0, 0, implicit $exec267 SI_RETURN268 bb.2:269 liveins: $vgpr2_vgpr3270 %1:vgpr_32 = V_MOV_B32_e32 20, implicit $exec271 GLOBAL_STORE_DWORD $vgpr2_vgpr3, %1:vgpr_32, 0, 0, implicit $exec272 SI_RETURN273...274