Skip to content

Commit 46ecdfa

Browse files
authored
[LLVM][XTHeadVector] Implement 16.1 vmand{n}/vmnand/vmxor/vmor{n}/vmnor/vmxnor (llvm#95)
* [LLVM][XTHeadVector] Implement 16.1 `vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor` * [LLVM][XTHeadVector] Test 16.1 `vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor` * [LLVM][XTHeadVector] Implement 16.1 `vmclr/vmset` * [LLVM][XTHeadVector] Test 16.1 `vmclr/vmset`
1 parent a547f9d commit 46ecdfa

File tree

13 files changed

+1306
-1
lines changed

13 files changed

+1306
-1
lines changed

llvm/include/llvm/IR/IntrinsicsRISCVXTHeadV.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,4 +897,17 @@ let TargetPrefix = "riscv" in {
897897
defm th_vfmul : XVBinaryAAXRoundingMode;
898898
defm th_vfdiv : XVBinaryAAXRoundingMode;
899899
defm th_vfrdiv : XVBinaryAAXRoundingMode;
900+
901+
// 16.1. Vector Mask-Register Logical Operations
902+
def int_riscv_th_vmand: RISCVBinaryAAAUnMasked;
903+
def int_riscv_th_vmnand: RISCVBinaryAAAUnMasked;
904+
def int_riscv_th_vmandnot: RISCVBinaryAAAUnMasked;
905+
def int_riscv_th_vmxor: RISCVBinaryAAAUnMasked;
906+
def int_riscv_th_vmor: RISCVBinaryAAAUnMasked;
907+
def int_riscv_th_vmnor: RISCVBinaryAAAUnMasked;
908+
def int_riscv_th_vmornot: RISCVBinaryAAAUnMasked;
909+
def int_riscv_th_vmxnor: RISCVBinaryAAAUnMasked;
910+
def int_riscv_th_vmclr : RISCVNullaryIntrinsic;
911+
def int_riscv_th_vmset : RISCVNullaryIntrinsic;
912+
900913
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
146146
case RISCV::PseudoVMSET_M_B64:
147147
// vmset.m vd => vmxnor.mm vd, vd, vd
148148
return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM);
149+
case RISCV::PseudoTH_VMCLR_M_B8:
150+
case RISCV::PseudoTH_VMCLR_M_B16:
151+
case RISCV::PseudoTH_VMCLR_M_B32:
152+
case RISCV::PseudoTH_VMCLR_M_B64:
153+
// th.vmclr.m vd => th.vmxor.mm vd, vd, vd
154+
return expandVMSET_VMCLR(MBB, MBBI, RISCV::TH_VMXOR_MM);
155+
case RISCV::PseudoTH_VMSET_M_B8:
156+
case RISCV::PseudoTH_VMSET_M_B16:
157+
case RISCV::PseudoTH_VMSET_M_B32:
158+
case RISCV::PseudoTH_VMSET_M_B64:
159+
// th.vmset.m vd => th.vmxnor.mm vd, vd, vd
160+
return expandVMSET_VMCLR(MBB, MBBI, RISCV::TH_VMXNOR_MM);
149161
}
150162

151163
return false;

llvm/lib/Target/RISCV/RISCVInstrInfoXTHeadVPseudos.td

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ defset list<VTypeInfoToWide> AllWidenableFloatXVectors = {
124124
def : VTypeInfoToWide<VF32M4, VF64M8>;
125125
}
126126

127+
// Redefine `AllMasks` from RISCVInstrInfoVPseudos.td to remove fractionally-grouped register groups.
128+
// TODO: riscv-v-intrinsics.pdf declares there are functions accepting vbool<16,32,64>_t, but they need
129+
// to be connected to MF2, MF4, MF8, which are not supported by the 'V' extension 0.7.1.
130+
defset list<MTypeInfo> AllXMasks = {
131+
// vbool<n>_t, <n> = SEW/LMUL, we assume SEW=8 and corresponding LMUL.
132+
def : MTypeInfo<vbool8_t, V_M1, "B8">;
133+
def : MTypeInfo<vbool4_t, V_M2, "B16">;
134+
def : MTypeInfo<vbool2_t, V_M4, "B32">;
135+
def : MTypeInfo<vbool1_t, V_M8, "B64">;
136+
}
137+
127138
class GetXVTypePredicates<VTypeInfo vti> {
128139
// TODO: distinguish different types (like F16, F32, F64, AnyF)? Is it needed?
129140
list<Predicate> Predicates = !cond(!eq(vti.Scalar, f16) : [HasVendorXTHeadV],
@@ -1666,6 +1677,19 @@ class XVPseudoBinaryMaskNoPolicy<VReg RetClass,
16661677
let HasSEWOp = 1;
16671678
}
16681679

1680+
multiclass XVPseudoNullaryPseudoM <string BaseInst> {
1681+
foreach mti = AllXMasks in {
1682+
defvar mx = mti.LMul.MX;
1683+
defvar WriteVMALUV_MX = !cast<SchedWrite>("WriteVMALUV_" # mx);
1684+
defvar ReadVMALUV_MX = !cast<SchedRead>("ReadVMALUV_" # mx);
1685+
1686+
let VLMul = mti.LMul.value in {
1687+
def "_M_" # mti.BX : VPseudoNullaryPseudoM<BaseInst # "_MM">,
1688+
Sched<[WriteVMALUV_MX, ReadVMALUV_MX, ReadVMALUV_MX]>;
1689+
}
1690+
}
1691+
}
1692+
16691693
class XVPseudoUnaryNoMask<DAGOperand RetClass, DAGOperand OpClass,
16701694
string Constraint = ""> :
16711695
Pseudo<(outs RetClass:$rd),
@@ -2480,6 +2504,19 @@ multiclass XVPseudoVFRDIV_VF_RM {
24802504
}
24812505
}
24822506

2507+
multiclass XVPseudoVALU_MM {
2508+
foreach m = MxListXTHeadV in {
2509+
defvar mx = m.MX;
2510+
defvar WriteVMALUV_MX = !cast<SchedWrite>("WriteVMALUV_" # mx);
2511+
defvar ReadVMALUV_MX = !cast<SchedRead>("ReadVMALUV_" # mx);
2512+
2513+
let VLMul = m.value in {
2514+
def "_MM_" # mx : VPseudoBinaryNoMask<VR, VR, VR, "">,
2515+
Sched<[WriteVMALUV_MX, ReadVMALUV_MX, ReadVMALUV_MX]>;
2516+
}
2517+
}
2518+
}
2519+
24832520
//===----------------------------------------------------------------------===//
24842521
// Helpers to define the intrinsic patterns for the XTHeadVector extension.
24852522
//===----------------------------------------------------------------------===//
@@ -2943,6 +2980,21 @@ multiclass XVPatBinaryM_VI<string intrinsic, string instruction,
29432980
vti.RegClass, simm5>;
29442981
}
29452982

2983+
multiclass XVPatBinaryM_MM<string intrinsic, string instruction> {
2984+
foreach mti = AllXMasks in
2985+
def : VPatBinaryM<intrinsic, instruction # "_MM_" # mti.LMul.MX,
2986+
mti.Mask, mti.Mask, mti.Mask,
2987+
mti.Log2SEW, VR, VR>;
2988+
}
2989+
2990+
multiclass XVPatNullaryM<string intrinsic, string inst> {
2991+
foreach mti = AllXMasks in
2992+
def : Pat<(mti.Mask (!cast<Intrinsic>(intrinsic)
2993+
VLOpFrag)),
2994+
(!cast<Instruction>(inst#"_M_"#mti.BX)
2995+
GPR:$vl, mti.Log2SEW)>;
2996+
}
2997+
29462998
multiclass XVPatCompare_VI<string intrinsic, string inst,
29472999
ImmLeaf ImmType> {
29483000
foreach vti = AllIntegerXVectors in {
@@ -3818,12 +3870,45 @@ let Predicates = [HasVendorXTHeadV], mayRaiseFPException = true,
38183870
} // Predicates = [HasVendorXTHeadV]
38193871

38203872
let Predicates = [HasVendorXTHeadV] in {
3821-
defm : XVPatBinaryV_VV_VX_RM<"int_riscv_th_vfmul", "PseudoTH_VFMUL",
3873+
defm : XVPatBinaryV_VV_VX_RM<"int_riscv_th_vfmul", "PseudoTH_VFMUL",
38223874
AllFloatXVectors>;
38233875
defm : XVPatBinaryV_VV_VX_RM<"int_riscv_th_vfdiv", "PseudoTH_VFDIV",
38243876
AllFloatXVectors, isSEWAware=1>;
38253877
defm : XVPatBinaryV_VX_RM<"int_riscv_th_vfrdiv", "PseudoTH_VFRDIV",
38263878
AllFloatXVectors, isSEWAware=1>;
38273879
} // Predicates = [HasVendorXTHeadV]
38283880

3881+
//===----------------------------------------------------------------------===//
3882+
// 16.1. Vector Mask-Register Logical Operations
3883+
//===----------------------------------------------------------------------===//
3884+
3885+
defm PseudoTH_VMAND: XVPseudoVALU_MM;
3886+
defm PseudoTH_VMNAND: XVPseudoVALU_MM;
3887+
defm PseudoTH_VMANDN: XVPseudoVALU_MM;
3888+
defm PseudoTH_VMXOR: XVPseudoVALU_MM;
3889+
defm PseudoTH_VMOR: XVPseudoVALU_MM;
3890+
defm PseudoTH_VMNOR: XVPseudoVALU_MM;
3891+
defm PseudoTH_VMORN: XVPseudoVALU_MM;
3892+
defm PseudoTH_VMXNOR: XVPseudoVALU_MM;
3893+
3894+
// Pseudo instructions, processed by the RISCVExpandPseudoInsts pass.
3895+
defm PseudoTH_VMCLR : XVPseudoNullaryPseudoM<"TH_VMXOR">;
3896+
defm PseudoTH_VMSET : XVPseudoNullaryPseudoM<"TH_VMXNOR">;
3897+
3898+
// Patterns
3899+
let Predicates = [HasVendorXTHeadV] in {
3900+
defm : XVPatBinaryM_MM<"int_riscv_th_vmand", "PseudoTH_VMAND">;
3901+
defm : XVPatBinaryM_MM<"int_riscv_th_vmnand", "PseudoTH_VMNAND">;
3902+
defm : XVPatBinaryM_MM<"int_riscv_th_vmandnot", "PseudoTH_VMANDN">;
3903+
defm : XVPatBinaryM_MM<"int_riscv_th_vmxor", "PseudoTH_VMXOR">;
3904+
defm : XVPatBinaryM_MM<"int_riscv_th_vmor", "PseudoTH_VMOR">;
3905+
defm : XVPatBinaryM_MM<"int_riscv_th_vmnor", "PseudoTH_VMNOR">;
3906+
defm : XVPatBinaryM_MM<"int_riscv_th_vmornot", "PseudoTH_VMORN">;
3907+
defm : XVPatBinaryM_MM<"int_riscv_th_vmxnor", "PseudoTH_VMXNOR">;
3908+
3909+
// pseudo instructions
3910+
defm : XVPatNullaryM<"int_riscv_th_vmclr", "PseudoTH_VMCLR">;
3911+
defm : XVPatNullaryM<"int_riscv_th_vmset", "PseudoTH_VMSET">;
3912+
}
3913+
38293914
include "RISCVInstrInfoXTHeadVVLPatterns.td"
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+xtheadvector \
3+
; RUN: -verify-machineinstrs | FileCheck %s
4+
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+xtheadvector \
5+
; RUN: -verify-machineinstrs | FileCheck %s
6+
7+
declare <vscale x 8 x i1> @llvm.riscv.th.vmand.nxv8i1(
8+
<vscale x 8 x i1>,
9+
<vscale x 8 x i1>,
10+
iXLen);
11+
12+
define <vscale x 8 x i1> @intrinsic_vmand_mm_nxv8i1(<vscale x 8 x i1> %0, <vscale x 8 x i1> %1, iXLen %2) nounwind {
13+
; CHECK-LABEL: intrinsic_vmand_mm_nxv8i1:
14+
; CHECK: # %bb.0: # %entry
15+
; CHECK-NEXT: csrr a1, vl
16+
; CHECK-NEXT: csrr a2, vtype
17+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
18+
; CHECK-NEXT: th.vsetvl zero, a1, a2
19+
; CHECK-NEXT: csrr a1, vl
20+
; CHECK-NEXT: csrr a2, vtype
21+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
22+
; CHECK-NEXT: th.vsetvl zero, a1, a2
23+
; CHECK-NEXT: th.vsetvli zero, a0, e8, m1, d1
24+
; CHECK-NEXT: th.vmand.mm v0, v0, v8
25+
; CHECK-NEXT: ret
26+
entry:
27+
%a = call <vscale x 8 x i1> @llvm.riscv.th.vmand.nxv8i1(
28+
<vscale x 8 x i1> %0,
29+
<vscale x 8 x i1> %1,
30+
iXLen %2)
31+
32+
ret <vscale x 8 x i1> %a
33+
}
34+
35+
declare <vscale x 16 x i1> @llvm.riscv.th.vmand.nxv16i1(
36+
<vscale x 16 x i1>,
37+
<vscale x 16 x i1>,
38+
iXLen);
39+
40+
define <vscale x 16 x i1> @intrinsic_vmand_mm_nxv16i1(<vscale x 16 x i1> %0, <vscale x 16 x i1> %1, iXLen %2) nounwind {
41+
; CHECK-LABEL: intrinsic_vmand_mm_nxv16i1:
42+
; CHECK: # %bb.0: # %entry
43+
; CHECK-NEXT: csrr a1, vl
44+
; CHECK-NEXT: csrr a2, vtype
45+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
46+
; CHECK-NEXT: th.vsetvl zero, a1, a2
47+
; CHECK-NEXT: csrr a1, vl
48+
; CHECK-NEXT: csrr a2, vtype
49+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
50+
; CHECK-NEXT: th.vsetvl zero, a1, a2
51+
; CHECK-NEXT: th.vsetvli zero, a0, e8, m2, d1
52+
; CHECK-NEXT: th.vmand.mm v0, v0, v8
53+
; CHECK-NEXT: csrr a0, vl
54+
; CHECK-NEXT: csrr a1, vtype
55+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
56+
; CHECK-NEXT: th.vsetvl zero, a0, a1
57+
; CHECK-NEXT: ret
58+
entry:
59+
%a = call <vscale x 16 x i1> @llvm.riscv.th.vmand.nxv16i1(
60+
<vscale x 16 x i1> %0,
61+
<vscale x 16 x i1> %1,
62+
iXLen %2)
63+
64+
ret <vscale x 16 x i1> %a
65+
}
66+
67+
declare <vscale x 32 x i1> @llvm.riscv.th.vmand.nxv32i1(
68+
<vscale x 32 x i1>,
69+
<vscale x 32 x i1>,
70+
iXLen);
71+
72+
define <vscale x 32 x i1> @intrinsic_vmand_mm_nxv32i1(<vscale x 32 x i1> %0, <vscale x 32 x i1> %1, iXLen %2) nounwind {
73+
; CHECK-LABEL: intrinsic_vmand_mm_nxv32i1:
74+
; CHECK: # %bb.0: # %entry
75+
; CHECK-NEXT: csrr a1, vl
76+
; CHECK-NEXT: csrr a2, vtype
77+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
78+
; CHECK-NEXT: th.vsetvl zero, a1, a2
79+
; CHECK-NEXT: csrr a1, vl
80+
; CHECK-NEXT: csrr a2, vtype
81+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
82+
; CHECK-NEXT: th.vsetvl zero, a1, a2
83+
; CHECK-NEXT: th.vsetvli zero, a0, e8, m4, d1
84+
; CHECK-NEXT: th.vmand.mm v0, v0, v8
85+
; CHECK-NEXT: csrr a0, vl
86+
; CHECK-NEXT: csrr a1, vtype
87+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
88+
; CHECK-NEXT: th.vsetvl zero, a0, a1
89+
; CHECK-NEXT: ret
90+
entry:
91+
%a = call <vscale x 32 x i1> @llvm.riscv.th.vmand.nxv32i1(
92+
<vscale x 32 x i1> %0,
93+
<vscale x 32 x i1> %1,
94+
iXLen %2)
95+
96+
ret <vscale x 32 x i1> %a
97+
}
98+
99+
declare <vscale x 64 x i1> @llvm.riscv.th.vmand.nxv64i1(
100+
<vscale x 64 x i1>,
101+
<vscale x 64 x i1>,
102+
iXLen);
103+
104+
define <vscale x 64 x i1> @intrinsic_vmand_mm_nxv64i1(<vscale x 64 x i1> %0, <vscale x 64 x i1> %1, iXLen %2) nounwind {
105+
; CHECK-LABEL: intrinsic_vmand_mm_nxv64i1:
106+
; CHECK: # %bb.0: # %entry
107+
; CHECK-NEXT: csrr a1, vl
108+
; CHECK-NEXT: csrr a2, vtype
109+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
110+
; CHECK-NEXT: th.vsetvl zero, a1, a2
111+
; CHECK-NEXT: csrr a1, vl
112+
; CHECK-NEXT: csrr a2, vtype
113+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
114+
; CHECK-NEXT: th.vsetvl zero, a1, a2
115+
; CHECK-NEXT: th.vsetvli zero, a0, e8, m8, d1
116+
; CHECK-NEXT: th.vmand.mm v0, v0, v8
117+
; CHECK-NEXT: csrr a0, vl
118+
; CHECK-NEXT: csrr a1, vtype
119+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
120+
; CHECK-NEXT: th.vsetvl zero, a0, a1
121+
; CHECK-NEXT: ret
122+
entry:
123+
%a = call <vscale x 64 x i1> @llvm.riscv.th.vmand.nxv64i1(
124+
<vscale x 64 x i1> %0,
125+
<vscale x 64 x i1> %1,
126+
iXLen %2)
127+
128+
ret <vscale x 64 x i1> %a
129+
}

0 commit comments

Comments
 (0)