[llvm] [RISCV] Disable performCombineVMergeAndVOps for PseduoVIOTA_M. (PR #71483)
Yeting Kuo via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 6 23:33:48 PST 2023
https://github.com/yetingk updated https://github.com/llvm/llvm-project/pull/71483
>From a14c83a08a002ac4e289c2ad6673d59b25f6fca2 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 7 Nov 2023 00:05:12 +0800
Subject: [PATCH 1/4] [RISCV] Disable performCombineVMergeAndVOps for
PseduoVIOTA_M.
This transformation is illegal for PseduoVIOTA_M. The value of `viota.m vd, vs2`
is the prefix sum of vd2 and adding mask for it may cause wrong prefix sum.
Take an example, the result of following expression is `{5, 5, 5, 3}`,
```
; v4 = {1, 1, 1, 1}
viota.m v1, v4
; v0 = {0, 0, 0, 1}, v1 = {0, 1, 2, 3}, v8 = {5, 5, 5, 5}
vmerge.vvm v8, v8, v1, v0.t
; v8 = {5, 5, 5, 3}
```
but if we merge them to `viota.m v8, v4, v0.t`, then the result of is
`{5, 5, 5, 0}`
We still does the transformation when mask of vmerge.vvm is a true mask.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 13 +++++++++
.../rvv/rvv-peephole-vmerge-masked-vops.ll | 16 +++++++++++
.../RISCV/rvv/rvv-peephole-vmerge-vops.ll | 28 +++++++++++++++----
3 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 51a235bf2ca1861..f103d323648d16a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3501,6 +3501,19 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
if (!True.isMachineOpcode())
return false;
+ // This transformation is illegal for viota.m when Mask is not a true mask.
+ switch (True->getMachineOpcode()) {
+ case RISCV::PseudoVIOTA_M_MF8:
+ case RISCV::PseudoVIOTA_M_MF4:
+ case RISCV::PseudoVIOTA_M_MF2:
+ case RISCV::PseudoVIOTA_M_M1:
+ case RISCV::PseudoVIOTA_M_M2:
+ case RISCV::PseudoVIOTA_M_M4:
+ case RISCV::PseudoVIOTA_M_M8:
+ if (Mask && !usesAllOnesMask(Mask, Glue))
+ return false;
+ }
+
unsigned TrueOpc = True.getMachineOpcode();
const MCInstrDesc &TrueMCID = TII->get(TrueOpc);
uint64_t TrueTSFlags = TrueMCID.TSFlags;
diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-masked-vops.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-masked-vops.ll
index 7e137d6a6196921..f6d9d1e711e7169 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-masked-vops.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-masked-vops.ll
@@ -258,3 +258,19 @@ entry:
%res = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %i, <vscale x 2 x i32> %passthru, i32 %evl)
ret <vscale x 2 x i32> %res
}
+
+; Test VIOTA_M
+declare <vscale x 2 x i32> @llvm.riscv.viota.mask.nxv2i32(<vscale x 2 x i32>, <vscale x 2 x i1>, <vscale x 2 x i1>, i64, i64)
+define <vscale x 2 x i32> @vpmerge_viota(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, <vscale x 2 x i1> %vm, i32 zeroext %vl) {
+; CHECK-LABEL: vpmerge_viota:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu
+; CHECK-NEXT: viota.m v8, v9, v0.t
+; CHECK-NEXT: ret
+ %1 = zext i32 %vl to i64
+ %a = call <vscale x 2 x i32> @llvm.riscv.viota.mask.nxv2i32(<vscale x 2 x i32> undef, <vscale x 2 x i1> %vm, <vscale x 2 x i1> %m, i64 %1, i64 0)
+ %splat = insertelement <vscale x 2 x i1> poison, i1 -1, i32 0
+ %mask = shufflevector <vscale x 2 x i1> %splat, <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer
+ %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %mask, i64 %1)
+ ret <vscale x 2 x i32> %b
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll
index 1ea2b7ef57cf081..df119435611d167 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll
@@ -279,13 +279,15 @@ define <vscale x 2 x i32> @vpmerge_vid(<vscale x 2 x i32> %passthru, <vscale x 2
ret <vscale x 2 x i32> %b
}
-; Test riscv.viota
+; Test not combine VIOTA_M and VMERGE_VVM without true mask.
declare <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32>, <vscale x 2 x i1>, i64)
define <vscale x 2 x i32> @vpmerge_viota(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, <vscale x 2 x i1> %vm, i32 zeroext %vl) {
; CHECK-LABEL: vpmerge_viota:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu
-; CHECK-NEXT: viota.m v8, v9, v0.t
+; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
+; CHECK-NEXT: viota.m v10, v9
+; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, ma
+; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0
; CHECK-NEXT: ret
%1 = zext i32 %vl to i64
%a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> undef, <vscale x 2 x i1> %vm, i64 %1)
@@ -293,6 +295,21 @@ define <vscale x 2 x i32> @vpmerge_viota(<vscale x 2 x i32> %passthru, <vscale x
ret <vscale x 2 x i32> %b
}
+; Test combine VIOTA_M and VMERGE_VVM with true mask.
+define <vscale x 2 x i32> @vpmerge_viota2(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %vm, i32 zeroext %vl) {
+; CHECK-LABEL: vpmerge_viota2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma
+; CHECK-NEXT: viota.m v8, v0
+; CHECK-NEXT: ret
+ %1 = zext i32 %vl to i64
+ %a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> undef, <vscale x 2 x i1> %vm, i64 %1)
+ %splat = insertelement <vscale x 2 x i1> poison, i1 -1, i32 0
+ %true = shufflevector <vscale x 2 x i1> %splat, <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer
+ %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %true, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)
+ ret <vscale x 2 x i32> %b
+}
+
; Test riscv.vfclass
declare <vscale x 2 x i32> @llvm.riscv.vfclass.nxv2i32(<vscale x 2 x i32>, <vscale x 2 x float>, i64)
define <vscale x 2 x i32> @vpmerge_vflcass(<vscale x 2 x i32> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {
@@ -730,8 +747,9 @@ define <vscale x 2 x i32> @vpselect_vid(<vscale x 2 x i32> %passthru, <vscale x
define <vscale x 2 x i32> @vpselect_viota(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, <vscale x 2 x i1> %vm, i32 zeroext %vl) {
; CHECK-LABEL: vpselect_viota:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu
-; CHECK-NEXT: viota.m v8, v9, v0.t
+; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
+; CHECK-NEXT: viota.m v10, v9
+; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0
; CHECK-NEXT: ret
%1 = zext i32 %vl to i64
%a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> undef, <vscale x 2 x i1> %vm, i64 %1)
>From 540ce31776a33148da8ef6fabea09fe4a34ab2e6 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 7 Nov 2023 12:23:36 +0800
Subject: [PATCH 2/4] Use getRVVMCOpcode to avoid list all pseduo instruction.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index f103d323648d16a..33afb73100ebfd3 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3502,17 +3502,9 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
return false;
// This transformation is illegal for viota.m when Mask is not a true mask.
- switch (True->getMachineOpcode()) {
- case RISCV::PseudoVIOTA_M_MF8:
- case RISCV::PseudoVIOTA_M_MF4:
- case RISCV::PseudoVIOTA_M_MF2:
- case RISCV::PseudoVIOTA_M_M1:
- case RISCV::PseudoVIOTA_M_M2:
- case RISCV::PseudoVIOTA_M_M4:
- case RISCV::PseudoVIOTA_M_M8:
+ if (RISCV::getRVVMCOpcode(True->getMachineOpcode()) == RISCV::VIOTA_M)
if (Mask && !usesAllOnesMask(Mask, Glue))
return false;
- }
unsigned TrueOpc = True.getMachineOpcode();
const MCInstrDesc &TrueMCID = TII->get(TrueOpc);
>From a5bfcd08525ed3569c7dc313b2d3d34e85fa8afe Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 7 Nov 2023 13:13:38 +0800
Subject: [PATCH 3/4] Add isAccumulated bit for RISCVMaskedPseudoInfo.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 10 +++++-----
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 1 +
llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | 7 ++++---
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 33afb73100ebfd3..44e4e81d59a2d16 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3501,11 +3501,6 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
if (!True.isMachineOpcode())
return false;
- // This transformation is illegal for viota.m when Mask is not a true mask.
- if (RISCV::getRVVMCOpcode(True->getMachineOpcode()) == RISCV::VIOTA_M)
- if (Mask && !usesAllOnesMask(Mask, Glue))
- return false;
-
unsigned TrueOpc = True.getMachineOpcode();
const MCInstrDesc &TrueMCID = TII->get(TrueOpc);
uint64_t TrueTSFlags = TrueMCID.TSFlags;
@@ -3522,6 +3517,11 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
if (!Info)
return false;
+ // This transformation is illegal for accumlated operations, like viota.m,
+ // when Mask is not a true mask.
+ if (Info->IsAccumulatedOp && Mask && !usesAllOnesMask(Mask, Glue))
+ return false;
+
if (HasTiedDest && !isImplicitDef(True->getOperand(0))) {
// The vmerge instruction must be TU.
// FIXME: This could be relaxed, but we need to handle the policy for the
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 5c182a8699ec06e..c07901ea092e334 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -263,6 +263,7 @@ struct RISCVMaskedPseudoInfo {
uint16_t MaskedPseudo;
uint16_t UnmaskedPseudo;
uint8_t MaskOpIdx;
+ uint8_t IsAccumulatedOp : 1;
};
#define GET_RISCVVSSEGTable_DECL
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index bec67153b6543d4..fd151403f4deeb5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -570,16 +570,17 @@ def RISCVVIntrinsicsTable : GenericTable {
// unmasked variant. For all but compares, both the masked and
// unmasked variant have a passthru and policy operand. For compares,
// neither has a policy op, and only the masked version has a passthru.
-class RISCVMaskedPseudo<bits<4> MaskIdx> {
+class RISCVMaskedPseudo<bits<4> MaskIdx, bit IsAcc=false> {
Pseudo MaskedPseudo = !cast<Pseudo>(NAME);
Pseudo UnmaskedPseudo = !cast<Pseudo>(!subst("_MASK", "", NAME));
bits<4> MaskOpIdx = MaskIdx;
+ bit IsAccumulatedOp = IsAcc;
}
def RISCVMaskedPseudosTable : GenericTable {
let FilterClass = "RISCVMaskedPseudo";
let CppTypeName = "RISCVMaskedPseudoInfo";
- let Fields = ["MaskedPseudo", "UnmaskedPseudo", "MaskOpIdx"];
+ let Fields = ["MaskedPseudo", "UnmaskedPseudo", "MaskOpIdx", "IsAccumulatedOp"];
let PrimaryKey = ["MaskedPseudo"];
let PrimaryKeyName = "getMaskedPseudoInfo";
}
@@ -2092,7 +2093,7 @@ multiclass VPseudoVIOT_M {
SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
forceMergeOpRead=true>;
def "_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, VR, constraint>,
- RISCVMaskedPseudo<MaskIdx=2>,
+ RISCVMaskedPseudo<MaskIdx=2, IsAcc=true>,
SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
forceMergeOpRead=true>;
}
>From aed70ca762e0506a072077d3c96d1ac7d2af031f Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 7 Nov 2023 15:32:30 +0800
Subject: [PATCH 4/4] Rename IsAccumulatedOp to MaskAffectsResult.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 6 +++---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | 8 ++++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 44e4e81d59a2d16..920657a198d9b6b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3517,9 +3517,9 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
if (!Info)
return false;
- // This transformation is illegal for accumlated operations, like viota.m,
- // when Mask is not a true mask.
- if (Info->IsAccumulatedOp && Mask && !usesAllOnesMask(Mask, Glue))
+ // When Mask is not a true mask, this transformation is illegal for some
+ // operations whose results are affected by mask, like viota.m.
+ if (Info->MaskAffectsResult && Mask && !usesAllOnesMask(Mask, Glue))
return false;
if (HasTiedDest && !isImplicitDef(True->getOperand(0))) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index c07901ea092e334..77e174135a599f9 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -263,7 +263,7 @@ struct RISCVMaskedPseudoInfo {
uint16_t MaskedPseudo;
uint16_t UnmaskedPseudo;
uint8_t MaskOpIdx;
- uint8_t IsAccumulatedOp : 1;
+ uint8_t MaskAffectsResult : 1;
};
#define GET_RISCVVSSEGTable_DECL
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index fd151403f4deeb5..83faa5bbef7931f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -570,17 +570,17 @@ def RISCVVIntrinsicsTable : GenericTable {
// unmasked variant. For all but compares, both the masked and
// unmasked variant have a passthru and policy operand. For compares,
// neither has a policy op, and only the masked version has a passthru.
-class RISCVMaskedPseudo<bits<4> MaskIdx, bit IsAcc=false> {
+class RISCVMaskedPseudo<bits<4> MaskIdx, bit MaskAffectsRes=false> {
Pseudo MaskedPseudo = !cast<Pseudo>(NAME);
Pseudo UnmaskedPseudo = !cast<Pseudo>(!subst("_MASK", "", NAME));
bits<4> MaskOpIdx = MaskIdx;
- bit IsAccumulatedOp = IsAcc;
+ bit MaskAffectsResult = MaskAffectsRes;
}
def RISCVMaskedPseudosTable : GenericTable {
let FilterClass = "RISCVMaskedPseudo";
let CppTypeName = "RISCVMaskedPseudoInfo";
- let Fields = ["MaskedPseudo", "UnmaskedPseudo", "MaskOpIdx", "IsAccumulatedOp"];
+ let Fields = ["MaskedPseudo", "UnmaskedPseudo", "MaskOpIdx", "MaskAffectsResult"];
let PrimaryKey = ["MaskedPseudo"];
let PrimaryKeyName = "getMaskedPseudoInfo";
}
@@ -2093,7 +2093,7 @@ multiclass VPseudoVIOT_M {
SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
forceMergeOpRead=true>;
def "_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, VR, constraint>,
- RISCVMaskedPseudo<MaskIdx=2, IsAcc=true>,
+ RISCVMaskedPseudo<MaskIdx=2, MaskAffectsRes=true>,
SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
forceMergeOpRead=true>;
}
More information about the llvm-commits
mailing list