[llvm] [RISCV][MachineVerifier] Use RegUnit for register liveness checking (PR #115980)

Piyou Chen via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 17 20:13:53 PST 2024


https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/115980

>From ad9a2ad28533167758f13e7e6a7197ec123cd7f1 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Mon, 11 Nov 2024 05:27:09 -0800
Subject: [PATCH 1/6] [RISCV][MachineVerifier] Treat register as live when all
 its units belong 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.
---
 llvm/lib/CodeGen/MachineVerifier.cpp        | 10 +++
 llvm/test/CodeGen/RISCV/subreg-liveness.mir | 73 +++++++++++++++++++++
 2 files changed, 83 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/subreg-liveness.mir

diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 3910046a1652b1..f0ed7dbac6d7fa 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -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()),
+                       [&](const MCRegister MOPSubReg) {
+                         return all_of(TRI->regunits(Reg),
+                                       [&](const MCRegUnit RegUnit) {
+                                         return llvm::is_contained(
+                                             TRI->regunits(MOPSubReg), RegUnit);
+                                       });
+                       }))
+              Bad = false;
           }
         }
         if (Bad)
diff --git a/llvm/test/CodeGen/RISCV/subreg-liveness.mir b/llvm/test/CodeGen/RISCV/subreg-liveness.mir
new file mode 100644
index 00000000000000..173253e20e5d99
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/subreg-liveness.mir
@@ -0,0 +1,73 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=machineverifier %s -o - | FileCheck %s
+
+...
+---
+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: $x2 = frame-setup ADDI $x2, -16
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
+    ; CHECK-NEXT: $x10 = frame-setup PseudoReadVLENB
+    ; CHECK-NEXT: $x11 = frame-setup ADDI $x0, 10
+    ; CHECK-NEXT: $x10 = frame-setup MUL killed $x10, killed $x11
+    ; CHECK-NEXT: $x2 = frame-setup SUB $x2, killed $x10
+    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x0a, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
+    ; CHECK-NEXT: dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
+    ; CHECK-NEXT: renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: renamable $v12m2 = PseudoVMERGE_VIM_M2 undef renamable $v12m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: $v0 = VMV1R_V killed $v8, implicit $v8
+    ; CHECK-NEXT: renamable $v24m2 = PseudoVMERGE_VIM_M2 undef renamable $v24m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: $v18m2 = VMV2R_V $v12m2, implicit $v12_v13_v14_v15_v16
+    ; CHECK-NEXT: $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
+    ; CHECK-NEXT: $v22 = VMV1R_V $v16, implicit $v12_v13_v14_v15_v16
+    ; CHECK-NEXT: $v0 = VMV1R_V $v9, implicit $v9
+    ; CHECK-NEXT: $v19 = VMV1R_V $v24, implicit $v24
+    ; CHECK-NEXT: renamable $v14m2 = PseudoVMERGE_VIM_M2 undef renamable $v14m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: $x12 = ADDI $x0, 1
+    ; CHECK-NEXT: early-clobber renamable $v0 = PseudoVSLIDEUP_VX_M1 killed renamable $v0, killed renamable $v9, killed renamable $x12, $noreg, 3 /* e8 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
+    ; CHECK-NEXT: early-clobber renamable $v8 = PseudoVMSNE_VI_M2 killed renamable $v10m2, 0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    ; CHECK-NEXT: $x10 = frame-destroy PseudoReadVLENB
+    ; CHECK-NEXT: $x11 = frame-destroy ADDI $x0, 10
+    ; CHECK-NEXT: $x10 = frame-destroy MUL killed $x10, killed $x11
+    ; CHECK-NEXT: $x2 = frame-destroy ADD $x2, killed $x10
+    ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
+    ; CHECK-NEXT: PseudoRET implicit $v0, implicit $v8
+    $x2 = frame-setup ADDI $x2, -16
+    frame-setup CFI_INSTRUCTION def_cfa_offset 16
+    $x10 = frame-setup PseudoReadVLENB
+    $x11 = frame-setup ADDI $x0, 10
+    $x10 = frame-setup MUL killed $x10, killed $x11
+    $x2 = frame-setup SUB $x2, killed $x10
+    frame-setup CFI_INSTRUCTION escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x0a, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
+    dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
+    renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    renamable $v12m2 = PseudoVMERGE_VIM_M2 undef renamable $v12m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    $v0 = VMV1R_V killed $v8, implicit $v8
+    renamable $v24m2 = PseudoVMERGE_VIM_M2 undef renamable $v24m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    $v18m2 = VMV2R_V $v12m2, implicit $v12_v13_v14_v15_v16
+    $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
+    $v22 = VMV1R_V $v16, implicit $v12_v13_v14_v15_v16
+    $v0 = VMV1R_V $v9, implicit $v9
+    $v19 = VMV1R_V $v24, implicit $v24
+    renamable $v14m2 = PseudoVMERGE_VIM_M2 undef renamable $v14m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    $x12 = ADDI $x0, 1
+    early-clobber renamable $v0 = PseudoVSLIDEUP_VX_M1 killed renamable $v0, killed renamable $v9, killed renamable $x12, $noreg, 3 /* e8 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
+    dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
+    early-clobber renamable $v8 = PseudoVMSNE_VI_M2 killed renamable $v10m2, 0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
+    $x10 = frame-destroy PseudoReadVLENB
+    $x11 = frame-destroy ADDI $x0, 10
+    $x10 = frame-destroy MUL killed $x10, killed $x11
+    $x2 = frame-destroy ADD $x2, killed $x10
+    $x2 = frame-destroy ADDI $x2, 16
+    PseudoRET implicit $v0, implicit $v8
+
+...

>From 152de89f1fb00e00efdde85abf2845cf369cebf1 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 13 Nov 2024 22:36:33 -0800
Subject: [PATCH 2/6] Move testcase into test/MachineVerifier/RISCV

---
 llvm/test/{CodeGen => MachineVerifier}/RISCV/subreg-liveness.mir | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename llvm/test/{CodeGen => MachineVerifier}/RISCV/subreg-liveness.mir (100%)

diff --git a/llvm/test/CodeGen/RISCV/subreg-liveness.mir b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
similarity index 100%
rename from llvm/test/CodeGen/RISCV/subreg-liveness.mir
rename to llvm/test/MachineVerifier/RISCV/subreg-liveness.mir

>From e30ab9bd478093f4b6d883074e1da4e5b2cb2d95 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 13 Nov 2024 22:55:17 -0800
Subject: [PATCH 3/6] Reduce the testcase

---
 .../MachineVerifier/RISCV/subreg-liveness.mir | 54 +------------------
 1 file changed, 1 insertion(+), 53 deletions(-)

diff --git a/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
index 173253e20e5d99..176e07b732e396 100644
--- a/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
+++ b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
@@ -1,5 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=machineverifier %s -o - | FileCheck %s
+# RUN: llc -mtriple=riscv64 -mattr=+v -run-pass=none %s -o - | FileCheck %s
 
 ...
 ---
@@ -13,61 +13,9 @@ body:             |
     ; CHECK-LABEL: name: func
     ; CHECK: liveins: $v0, $v8, $v9, $v10, $v11
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16
-    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
-    ; CHECK-NEXT: $x10 = frame-setup PseudoReadVLENB
-    ; CHECK-NEXT: $x11 = frame-setup ADDI $x0, 10
-    ; CHECK-NEXT: $x10 = frame-setup MUL killed $x10, killed $x11
-    ; CHECK-NEXT: $x2 = frame-setup SUB $x2, killed $x10
-    ; CHECK-NEXT: frame-setup CFI_INSTRUCTION escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x0a, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
-    ; CHECK-NEXT: dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
     ; CHECK-NEXT: renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: renamable $v12m2 = PseudoVMERGE_VIM_M2 undef renamable $v12m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: $v0 = VMV1R_V killed $v8, implicit $v8
-    ; CHECK-NEXT: renamable $v24m2 = PseudoVMERGE_VIM_M2 undef renamable $v24m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: $v18m2 = VMV2R_V $v12m2, implicit $v12_v13_v14_v15_v16
     ; CHECK-NEXT: $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
-    ; CHECK-NEXT: $v22 = VMV1R_V $v16, implicit $v12_v13_v14_v15_v16
-    ; CHECK-NEXT: $v0 = VMV1R_V $v9, implicit $v9
-    ; CHECK-NEXT: $v19 = VMV1R_V $v24, implicit $v24
-    ; CHECK-NEXT: renamable $v14m2 = PseudoVMERGE_VIM_M2 undef renamable $v14m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: $x12 = ADDI $x0, 1
-    ; CHECK-NEXT: early-clobber renamable $v0 = PseudoVSLIDEUP_VX_M1 killed renamable $v0, killed renamable $v9, killed renamable $x12, $noreg, 3 /* e8 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
-    ; CHECK-NEXT: early-clobber renamable $v8 = PseudoVMSNE_VI_M2 killed renamable $v10m2, 0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    ; CHECK-NEXT: $x10 = frame-destroy PseudoReadVLENB
-    ; CHECK-NEXT: $x11 = frame-destroy ADDI $x0, 10
-    ; CHECK-NEXT: $x10 = frame-destroy MUL killed $x10, killed $x11
-    ; CHECK-NEXT: $x2 = frame-destroy ADD $x2, killed $x10
-    ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
-    ; CHECK-NEXT: PseudoRET implicit $v0, implicit $v8
-    $x2 = frame-setup ADDI $x2, -16
-    frame-setup CFI_INSTRUCTION def_cfa_offset 16
-    $x10 = frame-setup PseudoReadVLENB
-    $x11 = frame-setup ADDI $x0, 10
-    $x10 = frame-setup MUL killed $x10, killed $x11
-    $x2 = frame-setup SUB $x2, killed $x10
-    frame-setup CFI_INSTRUCTION escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x0a, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22
-    dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
     renamable $v16m2 = PseudoVMV_V_I_M2 undef renamable $v16m2, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
-    renamable $v12m2 = PseudoVMERGE_VIM_M2 undef renamable $v12m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    $v0 = VMV1R_V killed $v8, implicit $v8
-    renamable $v24m2 = PseudoVMERGE_VIM_M2 undef renamable $v24m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    $v18m2 = VMV2R_V $v12m2, implicit $v12_v13_v14_v15_v16
     $v20m2 = VMV2R_V $v14m2, implicit $v12_v13_v14_v15_v16
-    $v22 = VMV1R_V $v16, implicit $v12_v13_v14_v15_v16
-    $v0 = VMV1R_V $v9, implicit $v9
-    $v19 = VMV1R_V $v24, implicit $v24
-    renamable $v14m2 = PseudoVMERGE_VIM_M2 undef renamable $v14m2, renamable $v16m2, 1, $v0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    $x12 = ADDI $x0, 1
-    early-clobber renamable $v0 = PseudoVSLIDEUP_VX_M1 killed renamable $v0, killed renamable $v9, killed renamable $x12, $noreg, 3 /* e8 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
-    dead renamable $x10 = PseudoVSETVLIX0 killed $x0, 193 /* e8, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
-    early-clobber renamable $v8 = PseudoVMSNE_VI_M2 killed renamable $v10m2, 0, -1, 3 /* e8 */, implicit $vl, implicit $vtype
-    $x10 = frame-destroy PseudoReadVLENB
-    $x11 = frame-destroy ADDI $x0, 10
-    $x10 = frame-destroy MUL killed $x10, killed $x11
-    $x2 = frame-destroy ADD $x2, killed $x10
-    $x2 = frame-destroy ADDI $x2, 16
-    PseudoRET implicit $v0, implicit $v8
 
 ...

>From 20c4b53ef5054e90c770c9495a9d038c7fd219a9 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 13 Nov 2024 23:52:42 -0800
Subject: [PATCH 4/6] Remove the redundant checking

---
 llvm/lib/CodeGen/MachineVerifier.cpp | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index f0ed7dbac6d7fa..4ca5a1b89adc57 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -3036,14 +3036,11 @@ 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()),
-                       [&](const MCRegister MOPSubReg) {
-                         return all_of(TRI->regunits(Reg),
-                                       [&](const MCRegUnit RegUnit) {
-                                         return llvm::is_contained(
-                                             TRI->regunits(MOPSubReg), RegUnit);
-                                       });
-                       }))
+            if (MOP.getReg() != Reg &&
+                all_of(TRI->regunits(Reg), [&](const MCRegUnit RegUnit) {
+                  return llvm::is_contained(TRI->regunits(MOP.getReg()),
+                                            RegUnit);
+                }))
               Bad = false;
           }
         }

>From 2a6399af16dee98282cedbd24e3fd6c7704dfc7c Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 17 Nov 2024 20:11:25 -0800
Subject: [PATCH 5/6] Add comment

---
 llvm/test/MachineVerifier/RISCV/subreg-liveness.mir | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
index 176e07b732e396..cb73f500ddc218 100644
--- a/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
+++ b/llvm/test/MachineVerifier/RISCV/subreg-liveness.mir
@@ -1,6 +1,11 @@
 # 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

>From 3f8f57f4407cad7e247a25384985c45e52eb8e4c Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 17 Nov 2024 20:13:31 -0800
Subject: [PATCH 6/6] Drop subreg check liveness

---
 llvm/lib/CodeGen/MachineVerifier.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 4ca5a1b89adc57..b08a93ae9a6d58 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -3033,9 +3033,6 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
             if (!MOP.getReg().isPhysical())
               continue;
 
-            if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg))
-              Bad = false;
-
             if (MOP.getReg() != Reg &&
                 all_of(TRI->regunits(Reg), [&](const MCRegUnit RegUnit) {
                   return llvm::is_contained(TRI->regunits(MOP.getReg()),



More information about the llvm-commits mailing list