1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/test/CodeGen/AMDGPU/coalescer-remat-dead-use.mir
Stanislav Mekhanoshin 2ef5dd8386 Prevent dead uses in register coalescer after rematerialization
The coalescer does not check if register uses are available
at the point of rematerialization. If it attempts to rematerialize
an instruction with such uses it can end up with use without a def.

LiveRangeEdit does such check during rematerialization, so just
call LiveRangeEdit::allUsesAvailableAt() to avoid the problem.

Differential Revision: https://reviews.llvm.org/D106396
2021-07-21 15:19:55 -07:00

95 lines
3.4 KiB
YAML

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -march=amdgcn -mcpu=gfx900 -o - -verify-coalescing -run-pass=simple-register-coalescing %s | FileCheck -check-prefix=GCN %s
---
# Do not rematerialize V_MOV_B32 at COPY because source register %1 is killed.
name: no_remat_killed_src_in_inst
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0
; GCN-LABEL: name: no_remat_killed_src_in_inst
; GCN: liveins: $vgpr0
; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GCN: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 1, [[COPY]], implicit $exec
; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[V_ADD_U32_e32_]], implicit $exec
; GCN: $vgpr0 = COPY [[V_MOV_B32_e32_]]
; GCN: SI_RETURN_TO_EPILOG $vgpr0
%0:vgpr_32 = COPY $vgpr0
%1:vgpr_32 = V_ADD_U32_e32 1, %0, implicit $exec
%2:vgpr_32 = V_MOV_B32_e32 killed %1, implicit $exec
$vgpr0 = COPY killed %2
SI_RETURN_TO_EPILOG killed $vgpr0
...
---
# Do not rematerialize V_MOV_B32 at COPY because source register %1 is killed
# after the MOV but before the COPY.
name: no_remat_killed_src_after_inst
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0
; GCN-LABEL: name: no_remat_killed_src_after_inst
; GCN: liveins: $vgpr0
; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GCN: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 1, [[COPY]], implicit $exec
; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[V_ADD_U32_e32_]], implicit $exec
; GCN: KILL [[V_ADD_U32_e32_]]
; GCN: $vgpr0 = COPY [[V_MOV_B32_e32_]]
; GCN: SI_RETURN_TO_EPILOG $vgpr0
%0:vgpr_32 = COPY $vgpr0
%1:vgpr_32 = V_ADD_U32_e32 1, %0, implicit $exec
%2:vgpr_32 = V_MOV_B32_e32 %1, implicit $exec
KILL %1
$vgpr0 = COPY killed %2
SI_RETURN_TO_EPILOG killed $vgpr0
...
---
# Even if %1 is not killed do not rematerialize V_MOV_B32 so that we do not
# extend %1 liverange.
name: no_remat_alive_src_in_inst_unused
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0
; GCN-LABEL: name: no_remat_alive_src_in_inst_unused
; GCN: liveins: $vgpr0
; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GCN: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 1, [[COPY]], implicit $exec
; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[V_ADD_U32_e32_]], implicit $exec
; GCN: $vgpr0 = COPY [[V_MOV_B32_e32_]]
; GCN: SI_RETURN_TO_EPILOG $vgpr0
%0:vgpr_32 = COPY $vgpr0
%1:vgpr_32 = V_ADD_U32_e32 1, %0, implicit $exec
%2:vgpr_32 = V_MOV_B32_e32 %1, implicit $exec
$vgpr0 = COPY killed %2
SI_RETURN_TO_EPILOG killed $vgpr0
...
---
# Rematerialize V_MOV_B32 since %1 is available at COPY and still alive.
name: remat_alive_src_in_inst_used_and_available
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0
; GCN-LABEL: name: remat_alive_src_in_inst_used_and_available
; GCN: liveins: $vgpr0
; GCN: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0
; GCN: [[V_ADD_U32_e32_:%[0-9]+]]:vgpr_32 = V_ADD_U32_e32 1, [[COPY]], implicit $exec
; GCN: $vgpr0 = V_MOV_B32_e32 [[V_ADD_U32_e32_]], implicit $exec
; GCN: SI_RETURN_TO_EPILOG $vgpr0
%0:vgpr_32 = COPY $vgpr0
%1:vgpr_32 = V_ADD_U32_e32 1, %0, implicit $exec
%2:vgpr_32 = V_MOV_B32_e32 %1, implicit $exec
$vgpr0 = COPY killed %2, implicit %1
SI_RETURN_TO_EPILOG killed $vgpr0
...