Skip to content

[RISCV] Attach an implicit source operand on vector copies #126155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,11 @@ void RISCVInstrInfo::copyPhysRegVector(
MIB.addReg(RISCV::VL, RegState::Implicit);
MIB.addReg(RISCV::VTYPE, RegState::Implicit);
}
// Add an implicit read of the original source to silence the verifier
// in the cases where some of the smaller VRs we're copying from might be
// undef, caused by the fact that the original, larger source VR might not
// be fully initialized at the time this COPY happens.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At what time the COPY happens? Why doesn't InitUndef work at this time?

Copy link
Member Author

@mshockwave mshockwave Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case I saw was created by register coalescer where it generates something like this:

%8.sub_vrm2_0:vrn32 = ...
%15.sub_vrm1_0_sub_vrm1_1_sub_vrm1_2_sub_vrm1_3_sub_vrm1_4:vrn3m2 = COPY %8.sub_vrm1_0_sub_vrm1_1_sub_vrm1_2_sub_vrm1_3_sub_vrm1_4

what happened was that the first instruction only initializes part of %8 and the second one COPY from another partially initialized (or partially undef) sub-register of %8. In this case we can't mark the source operand of COPY with undef. This COPY will eventually got broken down into smaller copies, in which one of those copies were copied from an undef register, hence the verifier error.

An alternative solution would be adding undef on source operand of the lowered, smaller copy instructions when needed. But that requires LiveIntervalsAnaysis.

MIB.addReg(SrcReg, RegState::Implicit);

// If we are copying reversely, we should decrease the encoding.
SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
Expand Down
24 changes: 24 additions & 0 deletions llvm/test/CodeGen/RISCV/postra-copy-expand.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=postrapseudos %s -o - | FileCheck %s

---
name: copy
isSSA: false
noVRegs: true
liveins:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should set tracksRegLiveness

- { reg: '$v0', virtual-reg: '' }
body: |
bb.0:
liveins: $v0
; CHECK-LABEL: name: copy
; CHECK: liveins: $v0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $v20m2 = VMV2R_V $v14m2, implicit $vtype, implicit $v14_v15_v16_v17_v18
; CHECK-NEXT: $v22m2 = VMV2R_V $v16m2, implicit $vtype, implicit $v14_v15_v16_v17_v18
; CHECK-NEXT: $v24 = VMV1R_V $v18, implicit $vtype, implicit $v14_v15_v16_v17_v18, implicit $vtype
; CHECK-NEXT: PseudoRET implicit $v0
renamable $v20_v21_v22_v23_v24 = COPY renamable $v14_v15_v16_v17_v18, implicit $vtype
PseudoRET implicit $v0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test undef and kill flags

...
Loading