[llvm] [RISCV] Handle implicit defs when ensuring pseudo dominates in peephole (PR #148181)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 11 03:05:53 PDT 2025


https://github.com/lukel97 created https://github.com/llvm/llvm-project/pull/148181

Previously we just assumed that no instruction that needed to be moved would have an implicit def, but vnclip pseudos will.

We can still try to move them but we just need to check that no instructions between have any reads or writes to the physical register.

Fixes #147986


>From 1886e5e9a5574232dcf46838d07b6a3627c213e0 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 11 Jul 2025 18:03:04 +0800
Subject: [PATCH] [RISCV] Handle implicit defs when ensuring pseudo dominates
 in peephole

Previously we just assumed that no instruction that needed to be moved would have an implicit def, but vnclip pseudos will.

We can still try to move them but we just need to check that no instructions between have any reads or writes to the physical register.

Fixes #147986
---
 llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp | 13 +++++--
 .../CodeGen/RISCV/rvv/vmerge-peephole.mir     | 39 +++++++++++++++++++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
index 07907298386c3..84ef53985484f 100644
--- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
@@ -521,16 +521,23 @@ bool RISCVVectorPeephole::convertToUnmasked(MachineInstr &MI) const {
 /// Check if it's safe to move From down to To, checking that no physical
 /// registers are clobbered.
 static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To) {
-  assert(From.getParent() == To.getParent() && !From.hasImplicitDef());
-  SmallVector<Register> PhysUses;
+  assert(From.getParent() == To.getParent());
+  SmallVector<Register> PhysUses, PhysDefs;
   for (const MachineOperand &MO : From.all_uses())
     if (MO.getReg().isPhysical())
       PhysUses.push_back(MO.getReg());
+  for (const MachineOperand &MO : From.all_defs())
+    if (MO.getReg().isPhysical())
+      PhysDefs.push_back(MO.getReg());
   bool SawStore = false;
-  for (auto II = From.getIterator(); II != To.getIterator(); II++) {
+  for (auto II = std::next(From.getIterator()); II != To.getIterator(); II++) {
     for (Register PhysReg : PhysUses)
       if (II->definesRegister(PhysReg, nullptr))
         return false;
+    for (Register PhysReg : PhysDefs)
+      if (II->definesRegister(PhysReg, nullptr) ||
+          II->readsRegister(PhysReg, nullptr))
+        return false;
     if (II->mayStore()) {
       SawStore = true;
       break;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir b/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir
index 03204468dc14c..0b95e558d8236 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vmerge-peephole.mir
@@ -55,3 +55,42 @@ body: |
     %mask:vmv0 = COPY $v0
     %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %x, %mask, %avl, 5 /* e32 */
 ...
+---
+name: vnclip_move_past_passthru
+body: |
+  bb.0:
+    liveins: $x8, $v0, $v8
+    ; CHECK-LABEL: name: vnclip_move_past_passthru
+    ; CHECK: liveins: $x8, $v0, $v8
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+    ; CHECK-NEXT: %passthru:vrnov0 = COPY $v8
+    ; CHECK-NEXT: %mask:vmv0 = COPY $v0
+    ; CHECK-NEXT: %y:vrnov0 = PseudoVNCLIPU_WV_MF2_MASK %passthru, $noreg, $noreg, %mask, 0, %avl, 5 /* e32 */, 0 /* tu, mu */, implicit-def $vxsat
+    %avl:gprnox0 = COPY $x8
+    %x:vr = PseudoVNCLIPU_WV_MF2 $noreg, $noreg, $noreg, 0, -1, 5, 3, implicit-def $vxsat
+    %passthru:vrnov0 = COPY $v8
+    %mask:vmv0 = COPY $v0
+    %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %x, %mask, %avl, 5 /* e32 */
+...
+---
+name: vnclip_cant_move_past_passthru
+body: |
+  bb.0:
+    liveins: $x8, $v0, $v8
+    ; CHECK-LABEL: name: vnclip_cant_move_past_passthru
+    ; CHECK: liveins: $x8, $v0, $v8
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+    ; CHECK-NEXT: %x:vr = PseudoVNCLIPU_WV_MF2 $noreg, $noreg, $noreg, 0, -1, 5 /* e32 */, 3 /* ta, ma */, implicit-def $vxsat
+    ; CHECK-NEXT: %vxsat:gpr = COPY $vxsat
+    ; CHECK-NEXT: %passthru:vrnov0 = COPY $v8
+    ; CHECK-NEXT: %mask:vmv0 = COPY $v0
+    ; CHECK-NEXT: %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %x, %mask, %avl, 5 /* e32 */
+    %avl:gprnox0 = COPY $x8
+    %x:vr = PseudoVNCLIPU_WV_MF2 $noreg, $noreg, $noreg, 0, -1, 5, 3, implicit-def $vxsat
+    %vxsat:gpr = COPY $vxsat
+    %passthru:vrnov0 = COPY $v8
+    %mask:vmv0 = COPY $v0
+    %y:vrnov0 = PseudoVMERGE_VVM_M1 %passthru, %passthru, %x, %mask, %avl, 5 /* e32 */
+...



More information about the llvm-commits mailing list