
Allocating wwm-registers and per-thread VGPR operands together imposes many challenges in the way the registers are reused during allocation. There are times when regalloc reuses the registers of regular VGPRs operations for wwm-operations in a small range leading to unwantedly clobbering their inactive lanes causing correctness issues that are hard to trace. This patch splits the VGPR allocation pipeline further to allocate wwm-registers first and the regular VGPR operands in a separate pipeline. The splitting would ensure that the physical registers used for wwm allocations won't take part in the next allocation pipeline to avoid any such clobbering.
159 lines
6.9 KiB
YAML
159 lines
6.9 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs -stress-regalloc=2 -start-before=greedy -stop-after=virtregmap -o - %s | FileCheck %s
|
|
|
|
# Test that a spill of a copy of exec is not folded to be a spill of exec directly.
|
|
|
|
---
|
|
|
|
name: merge_sgpr_spill_into_copy_from_exec_lo
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: merge_sgpr_spill_into_copy_from_exec_lo
|
|
; CHECK: S_NOP 0, implicit-def $exec_lo
|
|
; CHECK-NEXT: $sgpr0 = S_MOV_B32 $exec_lo
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: S_NOP 0, implicit-def dead renamable $sgpr1, implicit-def dead renamable $sgpr0, implicit killed renamable $sgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: $exec_lo = S_MOV_B32 killed $sgpr0
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def $exec_lo
|
|
%0:sreg_32 = COPY $exec_lo
|
|
S_NOP 0, implicit-def %1:sreg_32, implicit-def %2:sreg_32, implicit %0
|
|
$exec_lo = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|
|
---
|
|
|
|
name: merge_sgpr_spill_into_copy_from_exec_hi
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: merge_sgpr_spill_into_copy_from_exec_hi
|
|
; CHECK: S_NOP 0, implicit-def $exec_hi
|
|
; CHECK-NEXT: $sgpr0 = S_MOV_B32 $exec_hi
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: S_NOP 0, implicit-def dead renamable $sgpr1, implicit-def dead renamable $sgpr0, implicit killed renamable $sgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: $exec_hi = S_MOV_B32 killed $sgpr0
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def $exec_hi
|
|
%0:sreg_32 = COPY $exec_hi
|
|
S_NOP 0, implicit-def %1:sreg_32, implicit-def %2:sreg_32, implicit %0
|
|
$exec_hi = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|
|
---
|
|
|
|
name: merge_sgpr_spill_into_copy_from_exec
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: merge_sgpr_spill_into_copy_from_exec
|
|
; CHECK: S_NOP 0, implicit-def $exec
|
|
; CHECK-NEXT: $sgpr0_sgpr1 = S_MOV_B64 $exec
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0, implicit-def $sgpr0_sgpr1, implicit $sgpr0_sgpr1
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr1, 1, $vgpr0, implicit $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0, implicit-def $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr1 = V_READLANE_B32 $vgpr0, 1
|
|
; CHECK-NEXT: S_NOP 0, implicit-def dead renamable $sgpr2_sgpr3, implicit-def dead renamable $sgpr0_sgpr1, implicit killed renamable $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0, implicit-def $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr1 = V_READLANE_B32 $vgpr0, 1
|
|
; CHECK-NEXT: $exec = S_MOV_B64 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def $exec
|
|
%0:sreg_64 = COPY $exec
|
|
S_NOP 0, implicit-def %1:sreg_64, implicit-def %2:sreg_64, implicit %0
|
|
$exec = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|
|
|
|
# Test that a reload into a copy of exec is not folded to be a reload of exec directly.
|
|
|
|
---
|
|
|
|
name: reload_sgpr_spill_into_copy_to_exec_lo
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: reload_sgpr_spill_into_copy_to_exec_lo
|
|
; CHECK: S_NOP 0, implicit-def renamable $sgpr0, implicit-def dead renamable $sgpr1, implicit-def $exec_lo
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: S_NOP 0, implicit killed renamable $sgpr0, implicit-def dead renamable $sgpr1, implicit-def dead renamable $sgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: $exec_lo = S_MOV_B32 killed $sgpr0
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def %0:sreg_32, implicit-def %1:sreg_32, implicit-def $exec_lo
|
|
S_NOP 0, implicit %0, implicit-def %3:sreg_32, implicit-def %4:sreg_32
|
|
$exec_lo = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|
|
---
|
|
|
|
name: reload_sgpr_spill_into_copy_to_exec_hi
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: reload_sgpr_spill_into_copy_to_exec_hi
|
|
; CHECK: S_NOP 0, implicit-def renamable $sgpr0, implicit-def dead renamable $sgpr1, implicit-def $exec_hi
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: S_NOP 0, implicit killed renamable $sgpr0, implicit-def dead renamable $sgpr1, implicit-def dead renamable $sgpr0
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0
|
|
; CHECK-NEXT: $exec_hi = S_MOV_B32 killed $sgpr0
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def %0:sreg_32, implicit-def %1:sreg_32, implicit-def $exec_hi
|
|
S_NOP 0, implicit %0, implicit-def %3:sreg_32, implicit-def %4:sreg_32
|
|
$exec_hi = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|
|
---
|
|
|
|
name: reload_sgpr_spill_into_copy_to_exec
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo:
|
|
isEntryFunction: true
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: reload_sgpr_spill_into_copy_to_exec
|
|
; CHECK: S_NOP 0, implicit-def renamable $sgpr0_sgpr1, implicit-def dead renamable $sgpr2_sgpr3, implicit-def $exec
|
|
; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr0, 0, $vgpr0, implicit-def $sgpr0_sgpr1, implicit $sgpr0_sgpr1
|
|
; CHECK-NEXT: $vgpr0 = V_WRITELANE_B32 killed $sgpr1, 1, $vgpr0, implicit $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0, implicit-def $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr1 = V_READLANE_B32 $vgpr0, 1
|
|
; CHECK-NEXT: S_NOP 0, implicit killed renamable $sgpr0_sgpr1, implicit-def dead renamable $sgpr2_sgpr3, implicit-def dead renamable $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr0 = V_READLANE_B32 $vgpr0, 0, implicit-def $sgpr0_sgpr1
|
|
; CHECK-NEXT: $sgpr1 = V_READLANE_B32 $vgpr0, 1
|
|
; CHECK-NEXT: $exec = S_MOV_B64 killed $sgpr0_sgpr1
|
|
; CHECK-NEXT: S_SENDMSG 0, implicit $m0, implicit $exec
|
|
S_NOP 0, implicit-def %0:sreg_64, implicit-def %1:sreg_64, implicit-def $exec
|
|
S_NOP 0, implicit %0, implicit-def %3:sreg_64, implicit-def %4:sreg_64
|
|
$exec = COPY %0
|
|
S_SENDMSG 0, implicit $m0, implicit $exec
|
|
|
|
...
|