|
| 1 | +# RUN: not llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -start-before=greedy,2 -filetype=null %s 2>&1 | FileCheck %s |
| 2 | + |
| 3 | +# This testcase fails register allocation at the same time it performs |
| 4 | +# virtual register splitting (by introducing VGPR to AGPR copies). We |
| 5 | +# still need to enqueue and allocate the newly split vregs after the |
| 6 | +# failure. |
| 7 | + |
| 8 | +# The machine verifier should not complain about usage of register |
| 9 | +# which is marked as killed in previous instruction. This happens due |
| 10 | +# to when register allocator is out of registers it takes the first |
| 11 | +# available register. |
| 12 | + |
| 13 | +# CHECK: error: <unknown>:0:0: ran out of registers during register allocation |
| 14 | + |
| 15 | +--- | |
| 16 | + |
| 17 | + define amdgpu_kernel void @alloc_failure_with_split_vregs(float %v0, float %v1) #0 { |
| 18 | + ret void |
| 19 | + } |
| 20 | + |
| 21 | + attributes #0 = { "amdgpu-waves-per-eu"="10,10" "target-cpu"="gfx908" } |
| 22 | + |
| 23 | +... |
| 24 | +--- |
| 25 | +name: alloc_failure_with_split_vregs |
| 26 | +alignment: 1 |
| 27 | +tracksRegLiveness: true |
| 28 | +noPhis: true |
| 29 | +isSSA: false |
| 30 | +noVRegs: false |
| 31 | +hasFakeUses: false |
| 32 | +tracksDebugUserValues: true |
| 33 | +registers: |
| 34 | + - { id: 0, class: sgpr_64, preferred-register: '$sgpr8_sgpr9', flags: [ ] } |
| 35 | + - { id: 1, class: areg_512, preferred-register: '%2', flags: [ ] } |
| 36 | + - { id: 2, class: vreg_512, preferred-register: '%1', flags: [ ] } |
| 37 | + - { id: 3, class: areg_512, preferred-register: '%4', flags: [ ] } |
| 38 | + - { id: 4, class: av_512, preferred-register: '$agpr0_agpr1_agpr2_agpr3_agpr4_agpr5_agpr6_agpr7_agpr8_agpr9_agpr10_agpr11_agpr12_agpr13_agpr14_agpr15', |
| 39 | + flags: [ ] } |
| 40 | + - { id: 5, class: areg_512, preferred-register: '%2', flags: [ ] } |
| 41 | + - { id: 6, class: vgpr_32, preferred-register: '', flags: [ ] } |
| 42 | + - { id: 7, class: vgpr_32, preferred-register: '', flags: [ ] } |
| 43 | + - { id: 8, class: vgpr_32, preferred-register: '', flags: [ ] } |
| 44 | +machineFunctionInfo: |
| 45 | + isEntryFunction: true |
| 46 | + scratchRSrcReg: '$sgpr56_sgpr57_sgpr58_sgpr59' |
| 47 | + stackPtrOffsetReg: '$sgpr32' |
| 48 | + occupancy: 8 |
| 49 | + vgprForAGPRCopy: '$vgpr23' |
| 50 | + sgprForEXECCopy: '$sgpr58_sgpr59' |
| 51 | +body: | |
| 52 | + bb.0: |
| 53 | + liveins: $sgpr8_sgpr9 |
| 54 | +
|
| 55 | + renamable $sgpr0_sgpr1 = S_LOAD_DWORDX2_IMM killed renamable $sgpr8_sgpr9, 0, 0 :: (dereferenceable invariant load (s64), align 16, addrspace 4) |
| 56 | + %6:vgpr_32 = COPY renamable $sgpr0 |
| 57 | + INLINEASM &"; def $0", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $agpr0 |
| 58 | + undef %4.sub0:av_512 = COPY $agpr0 |
| 59 | + %3:areg_512 = COPY %4 |
| 60 | + %7:vgpr_32 = COPY killed renamable $sgpr1 |
| 61 | + early-clobber %1:areg_512 = V_MFMA_F32_16X16X1F32_e64 %6, %7, %3, 0, 0, 0, implicit $mode, implicit $exec, implicit $mode, implicit $exec |
| 62 | + %2:vreg_512 = COPY %1 |
| 63 | + %2.sub8:vreg_512 = COPY %4.sub0 |
| 64 | + %5:areg_512 = COPY %2 |
| 65 | + %5:areg_512 = V_MFMA_F32_16X16X1F32_mac_e64 %6, %7, %5, 0, 0, 0, implicit $mode, implicit $exec |
| 66 | + %8:vgpr_32 = COPY %5.sub3 |
| 67 | + $agpr1 = COPY %8 |
| 68 | + INLINEASM &"; use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $agpr1 |
| 69 | + S_ENDPGM 0 |
| 70 | +
|
| 71 | +... |
0 commit comments