[llvm] [RISCV] Add vector hasAndNot to enable optimizations (PR #132438)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 24 08:04:52 PDT 2025
https://github.com/pfusik updated https://github.com/llvm/llvm-project/pull/132438
>From 3f6dde9aafd178a18446561266ba541dd6129d21 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Fri, 21 Mar 2025 18:24:42 +0100
Subject: [PATCH 1/3] [RISCV][test] Add a test for vector hasAndNot
---
llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
index a4c64d6fa5ef5..5c24de2fd5601 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
@@ -2567,3 +2567,24 @@ for.body:
%exitcond.not = icmp eq i64 %indvars.iv.next, 256
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
}
+
+define <vscale x 1 x i8> @not_signbit_mask_nxv1i8(<vscale x 1 x i8> %a, <vscale x 1 x i8> %b) {
+; CHECK-LABEL: not_signbit_mask_nxv1i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli a0, zero, e8, mf8, ta, ma
+; CHECK-NEXT: vmsgt.vi v0, v8, -1
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0
+; CHECK-NEXT: ret
+;
+; CHECK-ZVKB-LABEL: not_signbit_mask_nxv1i8:
+; CHECK-ZVKB: # %bb.0:
+; CHECK-ZVKB-NEXT: vsetvli a0, zero, e8, mf8, ta, ma
+; CHECK-ZVKB-NEXT: vmsgt.vi v0, v8, -1
+; CHECK-ZVKB-NEXT: vmv.v.i v8, 0
+; CHECK-ZVKB-NEXT: vmerge.vvm v8, v8, v9, v0
+; CHECK-ZVKB-NEXT: ret
+ %cond = icmp sgt <vscale x 1 x i8> %a, splat (i8 -1)
+ %r = select <vscale x 1 x i1> %cond, <vscale x 1 x i8> %b, <vscale x 1 x i8> zeroinitializer
+ ret <vscale x 1 x i8> %r
+}
>From 2951c44e3ffdecbb73d94a40c4f0fe442605e474 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Fri, 21 Mar 2025 18:14:26 +0100
Subject: [PATCH 2/3] [RISCV] Add vector hasAndNot
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 10 +++++++++-
llvm/lib/Target/RISCV/RISCVISelLowering.h | 1 +
llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll | 6 +++---
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 132faf5b85c1a..97ec9123448a5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2051,7 +2051,6 @@ bool RISCVTargetLowering::isMaskAndCmp0FoldingBeneficial(
bool RISCVTargetLowering::hasAndNotCompare(SDValue Y) const {
EVT VT = Y.getValueType();
- // FIXME: Support vectors once we have tests.
if (VT.isVector())
return false;
@@ -2059,6 +2058,15 @@ bool RISCVTargetLowering::hasAndNotCompare(SDValue Y) const {
(!isa<ConstantSDNode>(Y) || cast<ConstantSDNode>(Y)->isOpaque());
}
+bool RISCVTargetLowering::hasAndNot(SDValue Y) const {
+ EVT VT = Y.getValueType();
+
+ if (!VT.isVector())
+ return hasAndNotCompare(Y);
+
+ return Subtarget.hasStdExtZvkb();
+}
+
bool RISCVTargetLowering::hasBitTest(SDValue X, SDValue Y) const {
// Zbs provides BEXT[_I], which can be used with SEQZ/SNEZ as a bit test.
if (Subtarget.hasStdExtZbs())
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index ffbc14a29006c..fb3931a561757 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -535,6 +535,7 @@ class RISCVTargetLowering : public TargetLowering {
bool isCheapToSpeculateCtlz(Type *Ty) const override;
bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
bool hasAndNotCompare(SDValue Y) const override;
+ bool hasAndNot(SDValue Y) const override;
bool hasBitTest(SDValue X, SDValue Y) const override;
bool shouldProduceAndByConstByHoistingConstFromShiftsLHSOfAnd(
SDValue X, ConstantSDNode *XC, ConstantSDNode *CC, SDValue Y,
diff --git a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
index 5c24de2fd5601..319cd94c651aa 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
@@ -2580,9 +2580,9 @@ define <vscale x 1 x i8> @not_signbit_mask_nxv1i8(<vscale x 1 x i8> %a, <vscale
; CHECK-ZVKB-LABEL: not_signbit_mask_nxv1i8:
; CHECK-ZVKB: # %bb.0:
; CHECK-ZVKB-NEXT: vsetvli a0, zero, e8, mf8, ta, ma
-; CHECK-ZVKB-NEXT: vmsgt.vi v0, v8, -1
-; CHECK-ZVKB-NEXT: vmv.v.i v8, 0
-; CHECK-ZVKB-NEXT: vmerge.vvm v8, v8, v9, v0
+; CHECK-ZVKB-NEXT: vsra.vi v8, v8, 7
+; CHECK-ZVKB-NEXT: vnot.v v8, v8
+; CHECK-ZVKB-NEXT: vand.vv v8, v8, v9
; CHECK-ZVKB-NEXT: ret
%cond = icmp sgt <vscale x 1 x i8> %a, splat (i8 -1)
%r = select <vscale x 1 x i1> %cond, <vscale x 1 x i8> %b, <vscale x 1 x i8> zeroinitializer
>From dec3bf255f5aca40af6a5bc43b8e3513a9a21644 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 24 Mar 2025 15:57:50 +0100
Subject: [PATCH 3/3] [RISCV] Match VANDN ignoring XOR constant bits above SEW
---
llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td | 9 ++++++---
llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll | 3 +--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
index fcbb2dbc76a37..904ce1b616c2d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td
@@ -603,13 +603,16 @@ multiclass VPatUnarySDNode_V<SDPatternOperator op, string instruction_name,
// This should match the logic in RISCVDAGToDAGISel::selectVSplat
def riscv_splat_vector : PatFrag<(ops node:$rs1),
(riscv_vmv_v_x_vl undef, node:$rs1, srcvalue)>;
-def riscv_vnot : PatFrag<(ops node:$rs1), (xor node:$rs1,
- (riscv_splat_vector -1))>;
+def allonessew8 : ImmLeaf<XLenVT, "return SignExtend64<8>(Imm) == -1LL;">;
+def allonessew16 : ImmLeaf<XLenVT, "return SignExtend64<16>(Imm) == -1LL;">;
+def allonessew32 : ImmLeaf<XLenVT, "return SignExtend64<32>(Imm) == -1LL;">;
+def allonessew64 : ImmLeaf<XLenVT, "return Imm == -1LL;">;
foreach vti = AllIntegerVectors in {
let Predicates = !listconcat([HasStdExtZvkb],
GetVTypePredicates<vti>.Predicates) in {
- def : Pat<(vti.Vector (and (riscv_vnot vti.RegClass:$rs1),
+ def : Pat<(vti.Vector (and (xor vti.RegClass:$rs1,
+ (riscv_splat_vector !cast<ImmLeaf>("allonessew"#vti.SEW))),
vti.RegClass:$rs2)),
(!cast<Instruction>("PseudoVANDN_VV_"#vti.LMul.MX)
(vti.Vector (IMPLICIT_DEF)),
diff --git a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
index 319cd94c651aa..aef46e1f5cf1b 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll
@@ -2581,8 +2581,7 @@ define <vscale x 1 x i8> @not_signbit_mask_nxv1i8(<vscale x 1 x i8> %a, <vscale
; CHECK-ZVKB: # %bb.0:
; CHECK-ZVKB-NEXT: vsetvli a0, zero, e8, mf8, ta, ma
; CHECK-ZVKB-NEXT: vsra.vi v8, v8, 7
-; CHECK-ZVKB-NEXT: vnot.v v8, v8
-; CHECK-ZVKB-NEXT: vand.vv v8, v8, v9
+; CHECK-ZVKB-NEXT: vandn.vv v8, v9, v8
; CHECK-ZVKB-NEXT: ret
%cond = icmp sgt <vscale x 1 x i8> %a, splat (i8 -1)
%r = select <vscale x 1 x i1> %cond, <vscale x 1 x i8> %b, <vscale x 1 x i8> zeroinitializer
More information about the llvm-commits
mailing list