[llvm] [RISCV] Remove vp.reverse mask check in performVP_REVERSECombine (PR #180724)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 03:36:30 PST 2026


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

Similar to #180706, the masked off lanes in vp.reverse are poison so can be replaced with anything. Because of this, we should be able to fold a masked vp.reverse(vp.load) into a vp.strided.load stride=-1 even when the mask isn't all ones.

>From 5de47f1d8502291160b71cce539515629bf09b39 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Tue, 10 Feb 2026 19:25:13 +0800
Subject: [PATCH 1/2] Precommit tests

---
 .../CodeGen/RISCV/rvv/vp-combine-reverse-load.ll  | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll b/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
index 75c60ad9382b5..2813f3dbd1678 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
@@ -48,6 +48,21 @@ define <vscale x 2 x float> @test_load_mask_not_all_one(<vscale x 2 x float>* %p
   ret <vscale x 2 x float> %rev
 }
 
+define <vscale x 2 x float> @test_load_reverse_mask_not_all_one(ptr %ptr, <vscale x 2 x i1> %notallones, i32 zeroext %evl) {
+; CHECK-LABEL: test_load_reverse_mask_not_all_one:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
+; CHECK-NEXT:    vle32.v v9, (a0)
+; CHECK-NEXT:    vid.v v8, v0.t
+; CHECK-NEXT:    addi a1, a1, -1
+; CHECK-NEXT:    vrsub.vx v10, v8, a1, v0.t
+; CHECK-NEXT:    vrgather.vv v8, v9, v10, v0.t
+; CHECK-NEXT:    ret
+  %load = call <vscale x 2 x float> @llvm.vp.load.nxv2f32.p0nxv2f32(ptr %ptr, <vscale x 2 x i1> splat (i1 true), i32 %evl)
+  %rev = call <vscale x 2 x float> @llvm.experimental.vp.reverse.nxv2f32(<vscale x 2 x float> %load, <vscale x 2 x i1> %notallones, i32 %evl)
+  ret <vscale x 2 x float> %rev
+}
+
 define <vscale x 2 x float> @test_different_evl(<vscale x 2 x float>* %ptr, <vscale x 2 x i1> %mask, i32 zeroext %evl1, i32 zeroext %evl2) {
 ; CHECK-LABEL: test_different_evl:
 ; CHECK:       # %bb.0:

>From c6554ee1e9546e3c972a27040864699302080427 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Tue, 10 Feb 2026 19:26:15 +0800
Subject: [PATCH 2/2] [RISCV] Remove vp.reverse mask check in
 performVP_REVERSECombine

Similar to #180706, the masked off lanes in vp.reverse are poison so can be replaced with anything. Because of this, we should be able to fold a masked vp.reverse(vp.load) into a vp.strided.load stride=-1 even when the mask isn't all ones.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp            |  4 ----
 llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll | 10 +++++-----
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 430946ebc2411..292a4a7708c5a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -19270,10 +19270,6 @@ static SDValue performVP_REVERSECombine(SDNode *N, SelectionDAG &DAG,
       !N->getOperand(0).hasOneUse())
     return SDValue();
 
-  // Check if the mask of outer vp.reverse are all 1's.
-  if (!isOneOrOneSplat(N->getOperand(1)))
-    return SDValue();
-
   SDValue LoadMask = VPLoad->getMask();
   // If Mask is all ones, then load is unmasked and can be reversed.
   if (!isOneOrOneSplat(LoadMask)) {
diff --git a/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll b/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
index 2813f3dbd1678..6db0048fa90d2 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vp-combine-reverse-load.ll
@@ -51,12 +51,12 @@ define <vscale x 2 x float> @test_load_mask_not_all_one(<vscale x 2 x float>* %p
 define <vscale x 2 x float> @test_load_reverse_mask_not_all_one(ptr %ptr, <vscale x 2 x i1> %notallones, i32 zeroext %evl) {
 ; CHECK-LABEL: test_load_reverse_mask_not_all_one:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    slli a2, a1, 2
+; CHECK-NEXT:    add a0, a2, a0
+; CHECK-NEXT:    addi a0, a0, -4
+; CHECK-NEXT:    li a2, -4
 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
-; CHECK-NEXT:    vle32.v v9, (a0)
-; CHECK-NEXT:    vid.v v8, v0.t
-; CHECK-NEXT:    addi a1, a1, -1
-; CHECK-NEXT:    vrsub.vx v10, v8, a1, v0.t
-; CHECK-NEXT:    vrgather.vv v8, v9, v10, v0.t
+; CHECK-NEXT:    vlse32.v v8, (a0), a2
 ; CHECK-NEXT:    ret
   %load = call <vscale x 2 x float> @llvm.vp.load.nxv2f32.p0nxv2f32(ptr %ptr, <vscale x 2 x i1> splat (i1 true), i32 %evl)
   %rev = call <vscale x 2 x float> @llvm.experimental.vp.reverse.nxv2f32(<vscale x 2 x float> %load, <vscale x 2 x i1> %notallones, i32 %evl)



More information about the llvm-commits mailing list