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