-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV][MachineVerifier] Use RegUnit for register liveness checking #115980
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
Conversation
…long to live super-register For the RISC-V target, V14_V15 are not belong to subregisters of v14m4, even though they share some registers. Currently, the MachineVerifier reports an error when checking register liveness for segment load/store operations. This patch adds additional register liveness checking, using RegUnit instead of subregisters, to prevent this error.
Without this patch, the testcase will report
|
llvm/lib/CodeGen/MachineVerifier.cpp
Outdated
@@ -3035,6 +3035,16 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { | |||
|
|||
if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg)) | |||
Bad = false; | |||
|
|||
if (any_of(TRI->subregs(MOP.getReg()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The outer any_of should be redundant with checking the regunits of the raw register. This should also be redundant with the is_contained in subregs above.
Overall this whole verifier liveness tracking is not well implemented. BBInfo and the rest of the infrastructure should be implemented directly in terms of register units
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would encounter problems if we were to drop the outer any_of with subregs().
Take this testcase as example:
# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck -check-prefix=ERROR %s
# When the verifier was detecting the invalid liveness for vcc, it would assert when trying to iterate the subregisters of the implicit virtual register use.
# ERROR: *** Bad machine code: Using an undefined physical register ***
# ERROR: instruction: S_ENDPGM 0, implicit %0:vgpr_32, implicit $vcc
# ERROR: operand 2: implicit $vcc
...
name: invalid_implicit_physreg_use_with_implicit_virtreg
tracksRegLiveness: true
body: |
bb.0:
%0:vgpr_32 = IMPLICIT_DEF
S_ENDPGM 0, implicit %0, implicit $vcc
...
The verification process will try to check if $vcc belongs to $vcc, which will always evaluate to true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid this problem, I modified to check only when MOP.getReg()
does not equal Reg
.
if (MOP.getReg() != Reg && all_of(TRI->regunits(Reg), [&](const MCRegUnit RegUnit) {
return llvm::is_contained(TRI->regunits(MOP.getReg()),
RegUnit);
}))
llvm/lib/CodeGen/MachineVerifier.cpp
Outdated
@@ -3035,6 +3035,13 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { | |||
|
|||
if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg)) | |||
Bad = false; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Above is_contained still redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks for the reminder. Dropped.
@llvm/pr-subscribers-llvm-regalloc Author: Piyou Chen (BeMg) ChangesFor the RISC-V target, V14_V15 are not subregisters of v14m4, even though they share some registers. Currently, the MachineVerifier reports an error when checking register liveness for segment load/store operations. This patch adds additional register liveness checking, using RegUnit instead of subregisters, to prevent this error. Full diff: https://github.com/llvm/llvm-project/pull/115980.diff 2 Files Affected:
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 3910046a1652b1..b08a93ae9a6d58 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -3033,7 +3033,11 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (!MOP.getReg().isPhysical())
continue;
- if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg))
+ if (MOP.getReg() != Reg &&
+ all_of(TRI->regunits(Reg), [&](const MCRegUnit RegUnit) {
+ return llvm::is_contained(TRI->regunits(MOP.getReg()),
+ RegUnit);
+ }))
Bad = false;
}
}
diff --git a/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
new file mode 100644
index 00000000000000..cb73f500ddc218
--- /dev/null
+++ b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
@@ -0,0 +1,26 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=none %s -o - | FileCheck %s
+
+# During the MachineVerifier, it assumes that used registers have been defined
+# In this test case, while $v12_v13_v14_v15_v16 covers $v14_v15,
+# $v14_v15 is not a sub-register of $v14m2 even though they share the same register.
+# This corner case can be resolved by checking the register using RegUnit.
+
+...
+---
+name: func
+tracksRegLiveness: true
+tracksDebugUserValues: true
+body: |
+ bb.0:
+ liveins: $v0, $v8, $v9, $v10, $v11
+
+ ; CHECK-LABEL: name: func
+ ; CHECK: liveins: $v0, $v8, $v9, $v10, $v11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ ; CHECK-NEXT: $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
+ renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
+
+...
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/8959 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/12419 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/8169 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/8961 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/2494 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/133/builds/7350 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/88/builds/4980 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/8300 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/7989 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/8443 Here is the relevant piece of the build log for the reference
|
For the RISC-V target, V14_V15 are not subregisters of v14m4, even though they share some registers. Currently, the MachineVerifier reports an error when checking register liveness for segment load/store operations.
This patch adds additional register liveness checking, using RegUnit instead of subregisters, to prevent this error.