[llvm] [RISCV] Relax VL constraint in convertSameMaskVMergeToVMv (PR #189797)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 06:30:51 PDT 2026
https://github.com/tclin914 updated https://github.com/llvm/llvm-project/pull/189797
>From e32d3b77d02e41557ef0bd2248524ec99c2b32e1 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 1 Apr 2026 08:43:59 +0800
Subject: [PATCH 1/4] [RISCV] Pre-commit
---
.../RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
index cc1229ed96c91..fa80ce88aee9a 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
@@ -207,3 +207,75 @@ body: |
%mask:vmv0 = COPY $v0
%true:vrnov0 = PseudoVADD_VV_M1_MASK $noreg, $noreg, $noreg, %mask, 2, 5 /* e32 */, 3 /* ta, ma */
%5:vrnov0 = PseudoVMERGE_VVM_M1 %pt, %false, %true, %mask, 1, 5 /* e32 */
+...
+---
+# Can convert because False == Passthru and True's tail policy is TU,
+# so True's tail lanes preserve passthru (= False = Passthru).
+name: same_mask_false_eq_passthru_true_tu
+body: |
+ bb.0:
+ liveins: $v8, $v0, $x8, $x9
+ ; CHECK-LABEL: name: same_mask_false_eq_passthru_true_tu
+ ; CHECK: liveins: $v8, $v0, $x8, $x9
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %false:vrnov0 = COPY $v8
+ ; CHECK-NEXT: %mask:vmv0 = COPY $v0
+ ; CHECK-NEXT: %avl1:gprnox0 = COPY $x8
+ ; CHECK-NEXT: %avl2:gprnox0 = COPY $x9
+ ; CHECK-NEXT: %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: [[PseudoVMERGE_VVM_M1_:%[0-9]+]]:vrnov0 = PseudoVMERGE_VVM_M1 %false, %false, %true, %mask, %avl2 /* vl */, 5 /* e32 */
+ %false:vrnov0 = COPY $v8
+ %mask:vmv0 = COPY $v0
+ %avl1:gprnox0 = COPY $x8
+ %avl2:gprnox0 = COPY $x9
+ %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1, 5 /* e32 */, 0 /* tu, mu */
+ %5:vrnov0 = PseudoVMERGE_VVM_M1 %false, %false, %true, %mask, %avl2, 5 /* e32 */
+...
+---
+# Shouldn't be converted because True's tail policy is TA, so tail lanes
+# past TrueVL could be agnostic, even though False == Passthru.
+name: same_mask_false_eq_passthru_true_ta
+body: |
+ bb.0:
+ liveins: $v8, $v0, $x8, $x9
+ ; CHECK-LABEL: name: same_mask_false_eq_passthru_true_ta
+ ; CHECK: liveins: $v8, $v0, $x8, $x9
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %false:vrnov0 = COPY $v8
+ ; CHECK-NEXT: %mask:vmv0 = COPY $v0
+ ; CHECK-NEXT: %avl1:gprnox0 = COPY $x8
+ ; CHECK-NEXT: %avl2:gprnox0 = COPY $x9
+ ; CHECK-NEXT: %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1 /* vl */, 5 /* e32 */, 1 /* ta, mu */
+ ; CHECK-NEXT: [[PseudoVMERGE_VVM_M1_:%[0-9]+]]:vrnov0 = PseudoVMERGE_VVM_M1 %false, %false, %true, %mask, %avl2 /* vl */, 5 /* e32 */
+ %false:vrnov0 = COPY $v8
+ %mask:vmv0 = COPY $v0
+ %avl1:gprnox0 = COPY $x8
+ %avl2:gprnox0 = COPY $x9
+ %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1, 5 /* e32 */, 1 /* ta, mu */
+ %5:vrnov0 = PseudoVMERGE_VVM_M1 %false, %false, %true, %mask, %avl2, 5 /* e32 */
+...
+---
+# Shouldn't be converted because False != Passthru, even though True's
+# tail policy is TU and MIVL could be > TrueVL.
+name: same_mask_false_ne_passthru_true_tu
+body: |
+ bb.0:
+ liveins: $v8, $v9, $v0, $x8, $x9
+ ; CHECK-LABEL: name: same_mask_false_ne_passthru_true_tu
+ ; CHECK: liveins: $v8, $v9, $v0, $x8, $x9
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %pt:vrnov0 = COPY $v8
+ ; CHECK-NEXT: %false:vrnov0 = COPY $v9
+ ; CHECK-NEXT: %mask:vmv0 = COPY $v0
+ ; CHECK-NEXT: %avl1:gprnox0 = COPY $x8
+ ; CHECK-NEXT: %avl2:gprnox0 = COPY $x9
+ ; CHECK-NEXT: %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+ ; CHECK-NEXT: [[PseudoVMERGE_VVM_M1_:%[0-9]+]]:vrnov0 = PseudoVMERGE_VVM_M1 %pt, %false, %true, %mask, %avl2 /* vl */, 5 /* e32 */
+ %pt:vrnov0 = COPY $v8
+ %false:vrnov0 = COPY $v9
+ %mask:vmv0 = COPY $v0
+ %avl1:gprnox0 = COPY $x8
+ %avl2:gprnox0 = COPY $x9
+ %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1, 5 /* e32 */, 0 /* tu, mu */
+ %5:vrnov0 = PseudoVMERGE_VVM_M1 %pt, %false, %true, %mask, %avl2, 5 /* e32 */
+...
>From a97edd1ecf2028d342c749340a84a6520671ddf2 Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 1 Apr 2026 08:44:49 +0800
Subject: [PATCH 2/4] [RISCV] Relax VL constraint in convertSameMaskVMergeToVMv
When converting a PseudoVMERGE_VVM to PseudoVMV_V_V, we previously
required MIVL <= TrueVL to avoid losing False elements in the tail.
Relax this constraint when the vmerge's False operand equals its
Passthru operand and the True instruction's tail policy is TU
(tail undisturbed). In this case, True's tail lanes preserve its
passthru value (which equals False and Passthru), so the conversion
is safe even when MIVL > TrueVL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply at anthropic.com>
---
llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp | 18 +++++++++++++++---
.../RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir | 2 +-
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
index 6fc2274b026e8..eaffae4be936e 100644
--- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
@@ -339,12 +339,24 @@ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv(MachineInstr &MI) {
// Masked off lanes past TrueVL will come from False, and converting to vmv
// will lose these lanes unless MIVL <= TrueVL.
- // TODO: We could relax this for False == Passthru and True policy == TU
+ // We can relax this when False == Passthru and True's tail policy is TU,
+ // because True's tail lanes will preserve its passthru (= False = Passthru).
const MachineOperand &MIVL = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
const MachineOperand &TrueVL =
True->getOperand(RISCVII::getVLOpNum(True->getDesc()));
- if (!RISCV::isVLKnownLE(MIVL, TrueVL))
- return false;
+ if (!RISCV::isVLKnownLE(MIVL, TrueVL)) {
+ Register FalseReg = MI.getOperand(2).getReg();
+ Register PassthruReg = MI.getOperand(1).getReg();
+ if (!PassthruReg.isValid() || FalseReg != PassthruReg)
+ return false;
+ if (!RISCVII::hasVecPolicyOp(True->getDesc().TSFlags))
+ return false;
+ uint64_t TruePolicy =
+ True->getOperand(RISCVII::getVecPolicyOpNum(True->getDesc()))
+ .getImm();
+ if (TruePolicy & RISCVVType::TAIL_AGNOSTIC)
+ return false;
+ }
// True's passthru needs to be equivalent to False
Register TruePassthruReg = True->getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
index fa80ce88aee9a..192c8381c42c3 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-to-vmv.mir
@@ -223,7 +223,7 @@ body: |
; CHECK-NEXT: %avl1:gprnox0 = COPY $x8
; CHECK-NEXT: %avl2:gprnox0 = COPY $x9
; CHECK-NEXT: %true:vrnov0 = PseudoVADD_VV_M1_MASK %false, $noreg, $noreg, %mask, %avl1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
- ; CHECK-NEXT: [[PseudoVMERGE_VVM_M1_:%[0-9]+]]:vrnov0 = PseudoVMERGE_VVM_M1 %false, %false, %true, %mask, %avl2 /* vl */, 5 /* e32 */
+ ; CHECK-NEXT: [[PseudoVMV_V_V_M1_:%[0-9]+]]:vr = PseudoVMV_V_V_M1 %false, %true, %avl2 /* vl */, 5 /* e32 */, 0 /* tu, mu */
%false:vrnov0 = COPY $v8
%mask:vmv0 = COPY $v0
%avl1:gprnox0 = COPY $x8
>From a58b6895e6e636c5f3441897e401619c38de515b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 1 Apr 2026 15:14:29 +0800
Subject: [PATCH 3/4] Address comments
---
llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
index eaffae4be936e..ed15820c8a64c 100644
--- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
@@ -344,10 +344,10 @@ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv(MachineInstr &MI) {
const MachineOperand &MIVL = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
const MachineOperand &TrueVL =
True->getOperand(RISCVII::getVLOpNum(True->getDesc()));
+ Register FalseReg = MI.getOperand(2).getReg();
if (!RISCV::isVLKnownLE(MIVL, TrueVL)) {
- Register FalseReg = MI.getOperand(2).getReg();
Register PassthruReg = MI.getOperand(1).getReg();
- if (!PassthruReg.isValid() || FalseReg != PassthruReg)
+ if (FalseReg.isValid() && FalseReg != PassthruReg)
return false;
if (!RISCVII::hasVecPolicyOp(True->getDesc().TSFlags))
return false;
@@ -360,7 +360,6 @@ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv(MachineInstr &MI) {
// True's passthru needs to be equivalent to False
Register TruePassthruReg = True->getOperand(1).getReg();
- Register FalseReg = MI.getOperand(2).getReg();
if (TruePassthruReg != FalseReg) {
// If True's passthru is undef see if we can change it to False
if (TruePassthruReg.isValid() ||
>From 993169e3dc6a6abf3b0462fb8fa2da382803bf6d Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Wed, 1 Apr 2026 21:27:59 +0800
Subject: [PATCH 4/4] Fix formatting
---
llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
index ed15820c8a64c..4a03932313b8a 100644
--- a/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp
@@ -352,8 +352,7 @@ bool RISCVVectorPeephole::convertSameMaskVMergeToVMv(MachineInstr &MI) {
if (!RISCVII::hasVecPolicyOp(True->getDesc().TSFlags))
return false;
uint64_t TruePolicy =
- True->getOperand(RISCVII::getVecPolicyOpNum(True->getDesc()))
- .getImm();
+ True->getOperand(RISCVII::getVecPolicyOpNum(True->getDesc())).getImm();
if (TruePolicy & RISCVVType::TAIL_AGNOSTIC)
return false;
}
More information about the llvm-commits
mailing list