[MachineVerifier] Fix crash on early clobbered subreg operands.

MachineVerifier tried to checkLivenessAtDef() ignoring it is actually a subreg.

The issue was with processing two subregs of the same reg are used in the same
instruction (e.g. inline asm): "def early-clobber" and other just "def".

Reviewed By: foad

Differential Revision: https://reviews.llvm.org/D126661
This commit is contained in:
Daniil Fukalov 2022-09-05 17:07:55 +03:00
parent ffa6267300
commit 99d364d1f4
2 changed files with 43 additions and 2 deletions

View File

@ -2290,8 +2290,18 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
bool SubRangeCheck,
LaneBitmask LaneMask) {
if (const VNInfo *VNI = LR.getVNInfoAt(DefIdx)) {
assert(VNI && "NULL valno is not allowed");
if (VNI->def != DefIdx) {
// The LR can correspond to the whole reg and its def slot is not obliged
// to be the same as the MO' def slot. E.g. when we check here "normal"
// subreg MO but there is other EC subreg MO in the same instruction so the
// whole reg has EC def slot and differs from the currently checked MO' def
// slot. For example:
// %0 [16e,32r:0) 0@16e L..3 [16e,32r:0) 0@16e L..C [16r,32r:0) 0@16r
// Check that there is an early-clobber def of the same superregister
// somewhere is performed in visitMachineFunctionAfter()
if (((SubRangeCheck || MO->getSubReg() == 0) && VNI->def != DefIdx) ||
!SlotIndex::isSameInstr(VNI->def, DefIdx) ||
(VNI->def != DefIdx &&
(!VNI->def.isEarlyClobber() || !DefIdx.isRegister()))) {
report("Inconsistent valno->def", MO, MONum);
report_context_liverange(LR);
report_context_vreg_regunit(VRegOrUnit);

View File

@ -0,0 +1,31 @@
# RUN: llc -mtriple amdgcn-amd-amdhsa -run-pass=liveintervals,pipeliner -verify-machineinstrs -o - %s | FileCheck %s
# REQUIRES: amdgpu-registered-target
# This test checks that the verifier doesn't crash on early clobbered subreg arguments.
---
name: sub0
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0_vgpr1
; CHECK-NOT: *** Bad machine code: Inconsistent valno->def ***
INLINEASM &"", 0 /* attdialect */, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %0.sub0:vreg_64, 1835018 /* regdef:VGPR_32 */, def undef %0.sub1:vreg_64
FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %0, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
S_ENDPGM 0
...
---
name: sub1
tracksRegLiveness: true
body: |
bb.0:
liveins: $vgpr0_vgpr1
; CHECK-NOT: *** Bad machine code: Inconsistent valno->def ***
INLINEASM &"", 0 /* attdialect */, 1835018 /* regdef:VGPR_32 */, def undef %0.sub0:vreg_64, 1835019 /* regdef-ec:VGPR_32 */, def undef early-clobber %0.sub1:vreg_64
FLAT_STORE_DWORDX2 $vgpr0_vgpr1, %0, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64))
S_ENDPGM 0
...