From 687e56614fa072c7b40044e5566ce7e92383fbde Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Thu, 9 Jun 2022 23:25:18 +0800 Subject: [PATCH] [RISCV] Fixing undefined physical register issue when subreg liveness tracking enabled. RISC-V expand register tuple spilling into series of register spilling after register allocation phase by the pseudo instruction expansion, however part of register tuple might be still undefined during spilling, machine verifier will complain the spill instruction is using an undefined physical register. Optimal solution should be doing liveness analysis and do not emit spill and reload for those undefined parts, but accurate liveness info at that point is not so easy to get. So the suboptimal solution is still spill and reload those undefined parts, but adding implicit-use of super register to spill function, then machine verifier will only report report using undefined physical register if the when whole super register is undefined, and this behavior are also documented in MachineVerifier::checkLiveness[1]. Example for demo what happend: ``` v10m2 = xxx # v12m2 not define yet PseudoVSPILL2_M2 v10m2_v12m2 ... ``` After expansion: ``` v10m2 = xxx # v12m2 not define yet # Expand PseudoVSPILL2_M2 v10m2_v12m2 to 2 vs2r VS2R_V v10m2 VS2R_V v12m2 # Use undef reg! ``` What this patch did: ``` v10m2 = xxx # v12m2 not define yet # Expand PseudoVSPILL2_M2 v10m2_v12m2 to 2 vs2r VS2R_V v10m2 implicit v10m2_v12m2 # Use undef reg (v12m2), but v10m2_v12m2 ins't totally undef, so # that's OK. VS2R_V v12m2 implicit v10m2_v12m2 ``` [1] https://github.com/llvm-mirror/llvm/blob/master/lib/CodeGen/MachineVerifier.cpp#L2016-L2019 Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D127642 --- .../Target/RISCV/RISCVExpandPseudoInsts.cpp | 7 +++- .../CodeGen/RISCV/rvv/undef-subreg-range.mir | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/RISCV/rvv/undef-subreg-range.mir diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp index e8e1784f5226..e4e01d9f6f2f 100644 --- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp +++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp @@ -314,10 +314,15 @@ bool RISCVExpandPseudo::expandVSPILL(MachineBasicBlock &MBB, assert(LMUL == 1 && "LMUL must be 1, 2, or 4."); for (unsigned I = 0; I < NF; ++I) { + // Adding implicit-use of super register to describe we are using part of + // super register, that prevents machine verifier complaining when part of + // subreg is undef, see comment in MachineVerifier::checkLiveness for more + // detail. BuildMI(MBB, MBBI, DL, TII->get(Opcode)) .addReg(TRI->getSubReg(SrcReg, SubRegIdx + I)) .addReg(Base) - .addMemOperand(*(MBBI->memoperands_begin())); + .addMemOperand(*(MBBI->memoperands_begin())) + .addReg(SrcReg, RegState::Implicit); if (I != NF - 1) BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), Base) .addReg(Base) diff --git a/llvm/test/CodeGen/RISCV/rvv/undef-subreg-range.mir b/llvm/test/CodeGen/RISCV/rvv/undef-subreg-range.mir new file mode 100644 index 000000000000..e1707003b651 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/undef-subreg-range.mir @@ -0,0 +1,32 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc %s -O2 -mtriple riscv64 -riscv-enable-subreg-liveness \ +# RUN: -verify-machineinstrs -run-pass=riscv-expand-pseudo -o - 2>&1 \ +# RUN: | FileCheck %s +--- | + define void @foo() #0 { + entry: + ret void + } +... +--- +name: foo +alignment: 4 +tracksRegLiveness: true +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: 0, size: 32, alignment: 8, + stack-id: scalable-vector, callee-saved-register: '', callee-saved-restored: true } +body: | + bb.0.entry: + liveins: $v8m2, $x10, $x11 + ; CHECK-LABEL: name: foo + ; CHECK: liveins: $v8m2, $x10, $x11 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: VS2R_V $v8m2, $x10, implicit $v8m2_v10m2 :: (store unknown-size into %stack.0, align 8) + ; CHECK-NEXT: $x10 = ADD $x10, $x11 + ; CHECK-NEXT: VS2R_V $v10m2, $x10, implicit $v8m2_v10m2 :: (store unknown-size into %stack.0, align 8) + ; CHECK-NEXT: PseudoRET + PseudoVSPILL2_M2 killed $v8m2_v10m2, killed $x10, killed $x11 :: (store unknown-size into %stack.0, align 8) + PseudoRET + +... -- 2.34.1