Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
kito-cheng committed Jun 15, 2022
1 parent a36c801 commit 687e566
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
7 changes: 6 additions & 1 deletion llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
Expand Up @@ -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)
Expand Down
32 changes: 32 additions & 0 deletions 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
...

0 comments on commit 687e566

Please sign in to comment.