diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2256,14 +2256,22 @@ LaneBitmask LaneMask) { if (const VNInfo *VNI = LR.getVNInfoAt(DefIdx)) { assert(VNI && "NULL valno is not allowed"); - if (VNI->def != DefIdx) { - report("Inconsistent valno->def", MO, MONum); - report_context_liverange(LR); - report_context_vreg_regunit(VRegOrUnit); - if (LaneMask.any()) - report_context_lanemask(LaneMask); - report_context(*VNI); - report_context(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 + if (SubRangeCheck || MO->getSubReg() == 0) { + if (VNI->def != DefIdx) { + report("Inconsistent valno->def", MO, MONum); + report_context_liverange(LR); + report_context_vreg_regunit(VRegOrUnit); + if (LaneMask.any()) + report_context_lanemask(LaneMask); + report_context(*VNI); + report_context(DefIdx); + } } } else { report("No live segment at def", MO, MONum); diff --git a/llvm/test/MachineVerifier/verifier-ec-subreg-liveness.mir b/llvm/test/MachineVerifier/verifier-ec-subreg-liveness.mir new file mode 100644 --- /dev/null +++ b/llvm/test/MachineVerifier/verifier-ec-subreg-liveness.mir @@ -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 + +...