[llvm] [RISCV] Avoid VMNOT by swapping VMERGE operands (PR #126751)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 17 04:55:38 PST 2025
https://github.com/llvm updated https://github.com/llvm/llvm-project/pull/126751
>From 7b8dcda0689c205a5a8edb3c64e322801be11208 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 17 Feb 2025 12:08:24 +0100
Subject: [PATCH 1/3] [RISCV][test] Add tests for extending negated mask
---
llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll | 56 ++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
diff --git a/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll b/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
new file mode 100644
index 0000000000000..1acbd6cc239a6
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs < %s | FileCheck %s
+
+define <vscale x 8 x i8> @mask_sext_not_nxv8i8(<vscale x 8 x i1> %m) {
+; CHECK-LABEL: mask_sext_not_nxv8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
+; CHECK-NEXT: vmnot.m v0, v0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, -1, v0
+; CHECK-NEXT: ret
+ %n = xor <vscale x 8 x i1> %m, splat (i1 true)
+ %ext = sext <vscale x 8 x i1> %n to <vscale x 8 x i8>
+ ret <vscale x 8 x i8> %ext
+}
+
+define <vscale x 8 x i8> @mask_zext_not_nxv8i8(<vscale x 8 x i1> %m) {
+; CHECK-LABEL: mask_zext_not_nxv8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
+; CHECK-NEXT: vmnot.m v0, v0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: ret
+ %n = xor <vscale x 8 x i1> %m, splat (i1 true)
+ %ext = zext <vscale x 8 x i1> %n to <vscale x 8 x i8>
+ ret <vscale x 8 x i8> %ext
+}
+
+define <8 x i8> @mask_sext_not_v8i8(<8 x i1> %m) {
+; CHECK-LABEL: mask_sext_not_v8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmnot.m v0, v0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, -1, v0
+; CHECK-NEXT: ret
+ %n = xor <8 x i1> %m, splat (i1 true)
+ %ext = sext <8 x i1> %n to <8 x i8>
+ ret <8 x i8> %ext
+}
+
+define <8 x i8> @mask_zext_not_v8i8(<8 x i1> %m) {
+; CHECK-LABEL: mask_zext_not_v8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; CHECK-NEXT: vmnot.m v0, v0
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: ret
+ %n = xor <8 x i1> %m, splat (i1 true)
+ %ext = zext <8 x i1> %n to <8 x i8>
+ ret <8 x i8> %ext
+}
+
>From ca3ba6f4cd1934eadd060f5187f95a39010ee6f5 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 17 Feb 2025 12:31:02 +0100
Subject: [PATCH 2/3] [RISCV] Avoid VMNOT by swapping VMERGE operands for mask
extensions
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 17 +++++++++++++++++
llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll | 20 ++++++++------------
2 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c40ab0d09bdf6..11f532c25d311 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8965,6 +8965,9 @@ SDValue RISCVTargetLowering::lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
if (VecVT.isScalableVector()) {
SDValue SplatZero = DAG.getConstant(0, DL, VecVT);
SDValue SplatTrueVal = DAG.getSignedConstant(ExtTrueVal, DL, VecVT);
+ if (Src.getOpcode() == ISD::XOR &&
+ ISD::isConstantSplatVectorAllOnes(Src.getOperand(1).getNode(), false))
+ return DAG.getNode(ISD::VSELECT, DL, VecVT, Src.getOperand(0), SplatZero, SplatTrueVal);
return DAG.getNode(ISD::VSELECT, DL, VecVT, Src, SplatTrueVal, SplatZero);
}
@@ -8980,6 +8983,20 @@ SDValue RISCVTargetLowering::lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
SDValue SplatZero = DAG.getConstant(0, DL, XLenVT);
SDValue SplatTrueVal = DAG.getSignedConstant(ExtTrueVal, DL, XLenVT);
+ if (Src.getOpcode() == ISD::EXTRACT_SUBVECTOR) {
+ SDValue Xor = Src.getOperand(0);
+ if (Xor.getOpcode() == RISCVISD::VMXOR_VL) {
+ SDValue ScalableOnes = Xor.getOperand(1);
+ if (ScalableOnes.getOpcode() == ISD::INSERT_SUBVECTOR &&
+ ScalableOnes.getOperand(0).isUndef() &&
+ ISD::isConstantSplatVectorAllOnes(
+ ScalableOnes.getOperand(1).getNode(), false)) {
+ CC = Xor.getOperand(0);
+ std::swap(SplatZero, SplatTrueVal);
+ }
+ }
+ }
+
SplatZero = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
DAG.getUNDEF(ContainerVT), SplatZero, VL);
SplatTrueVal = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
diff --git a/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll b/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
index 1acbd6cc239a6..c72d717c033ea 100644
--- a/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/mask-exts-not.ll
@@ -6,9 +6,8 @@ define <vscale x 8 x i8> @mask_sext_not_nxv8i8(<vscale x 8 x i1> %m) {
; CHECK-LABEL: mask_sext_not_nxv8i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
-; CHECK-NEXT: vmnot.m v0, v0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, -1, v0
+; CHECK-NEXT: vmv.v.i v8, -1
+; CHECK-NEXT: vmerge.vim v8, v8, 0, v0
; CHECK-NEXT: ret
%n = xor <vscale x 8 x i1> %m, splat (i1 true)
%ext = sext <vscale x 8 x i1> %n to <vscale x 8 x i8>
@@ -19,9 +18,8 @@ define <vscale x 8 x i8> @mask_zext_not_nxv8i8(<vscale x 8 x i1> %m) {
; CHECK-LABEL: mask_zext_not_nxv8i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
-; CHECK-NEXT: vmnot.m v0, v0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vmv.v.i v8, 1
+; CHECK-NEXT: vmerge.vim v8, v8, 0, v0
; CHECK-NEXT: ret
%n = xor <vscale x 8 x i1> %m, splat (i1 true)
%ext = zext <vscale x 8 x i1> %n to <vscale x 8 x i8>
@@ -32,9 +30,8 @@ define <8 x i8> @mask_sext_not_v8i8(<8 x i1> %m) {
; CHECK-LABEL: mask_sext_not_v8i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmnot.m v0, v0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, -1, v0
+; CHECK-NEXT: vmv.v.i v8, -1
+; CHECK-NEXT: vmerge.vim v8, v8, 0, v0
; CHECK-NEXT: ret
%n = xor <8 x i1> %m, splat (i1 true)
%ext = sext <8 x i1> %n to <8 x i8>
@@ -45,9 +42,8 @@ define <8 x i8> @mask_zext_not_v8i8(<8 x i1> %m) {
; CHECK-LABEL: mask_zext_not_v8i8:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vmnot.m v0, v0
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
+; CHECK-NEXT: vmv.v.i v8, 1
+; CHECK-NEXT: vmerge.vim v8, v8, 0, v0
; CHECK-NEXT: ret
%n = xor <8 x i1> %m, splat (i1 true)
%ext = zext <8 x i1> %n to <8 x i8>
>From e3cbf3deadd71519fde3a6ecf075f8a60d412513 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 17 Feb 2025 12:49:10 +0100
Subject: [PATCH 3/3] [RISCV] clang-format
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 11f532c25d311..b27b7d75bbdd8 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8967,7 +8967,8 @@ SDValue RISCVTargetLowering::lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
SDValue SplatTrueVal = DAG.getSignedConstant(ExtTrueVal, DL, VecVT);
if (Src.getOpcode() == ISD::XOR &&
ISD::isConstantSplatVectorAllOnes(Src.getOperand(1).getNode(), false))
- return DAG.getNode(ISD::VSELECT, DL, VecVT, Src.getOperand(0), SplatZero, SplatTrueVal);
+ return DAG.getNode(ISD::VSELECT, DL, VecVT, Src.getOperand(0), SplatZero,
+ SplatTrueVal);
return DAG.getNode(ISD::VSELECT, DL, VecVT, Src, SplatTrueVal, SplatZero);
}
More information about the llvm-commits
mailing list