Skip to content

Commit 6859e5a

Browse files
[CLANG][LLVM][AArch64]Add SME2.1 intrinsics for MOVAZ array to vector (#88901)
According to the specification in ARM-software/acle#309 this adds the intrinsics Move and zero multiple ZA single-vector groups to vector registers // Variants are also available for _za8_u8, _za16_s16, _za16_u16, // _za16_f16, _za16_bf16, _za32_s32, _za32_u32, _za32_f32, // _za64_s64, _za64_u64 and _za64_f64 svint8x2_t svreadz_za8_s8_vg1x2(uint32_t slice) __arm_streaming __arm_inout("za"); // Variants are also available for _za8_u8, _za16_s16, _za16_u16, // _za16_f16, _za16_bf16, _za32_s32, _za32_u32, _za32_f32, // _za64_s64, _za64_u64 and _za64_f64 svint8x4_t svreadz_za8_s8_vg1x4(uint32_t slice) __arm_streaming __arm_inout("za");
1 parent 22c7317 commit 6859e5a

File tree

8 files changed

+1002
-11
lines changed

8 files changed

+1002
-11
lines changed

clang/include/clang/Basic/arm_sme.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,4 +805,16 @@ defm SVREADZ_ZA16 : ZAReadzSingle<"za16", "sUshb", "aarch64_sme_readz", [ImmChe
805805
defm SVREADZ_ZA32 : ZAReadzSingle<"za32", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>;
806806
defm SVREADZ_ZA64 : ZAReadzSingle<"za64", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>;
807807
defm SVREADZ_ZA128 : ZAReadzSingle<"za128", "csilUcUiUsUlbhfd", "aarch64_sme_readz_q", [ImmCheck<0, ImmCheck0_15>]>;
808+
809+
multiclass ZAReadzArray<string vg_num>{
810+
let SMETargetGuard = "sme2p1" in {
811+
def NAME # _B : SInst<"svreadz_za8_{d}_vg1x" # vg_num, vg_num # "m", "cUc", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>;
812+
def NAME # _H : SInst<"svreadz_za16_{d}_vg1x" # vg_num, vg_num # "m", "sUsbh", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>;
813+
def NAME # _S : SInst<"svreadz_za32_{d}_vg1x" # vg_num, vg_num # "m", "iUif", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>;
814+
def NAME # _D : SInst<"svreadz_za64_{d}_vg1x" # vg_num, vg_num # "m", "lUld", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>;
815+
}
816+
}
817+
818+
defm SVREADZ_VG2 : ZAReadzArray<"2">;
819+
defm SVREADZ_VG4 : ZAReadzArray<"4">;
808820
} // let SVETargetGuard = InvalidMode

clang/test/CodeGen/aarch64-sme2p1-intrinsics/acle_sme2p1_movaz.c

Lines changed: 705 additions & 0 deletions
Large diffs are not rendered by default.

llvm/include/llvm/IR/IntrinsicsAArch64.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2869,6 +2869,16 @@ let TargetPrefix = "aarch64" in {
28692869
def int_aarch64_sme_readz_q_horiz : SME_MOVAZ_TileToVector_Intrinsic;
28702870
def int_aarch64_sme_readz_q_vert : SME_MOVAZ_TileToVector_Intrinsic;
28712871

2872+
def int_aarch64_sme_readz_x2
2873+
: DefaultAttrsIntrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
2874+
[llvm_i32_ty],
2875+
[IntrNoMem, IntrHasSideEffects]>;
2876+
2877+
def int_aarch64_sme_readz_x4
2878+
: DefaultAttrsIntrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
2879+
[llvm_i32_ty],
2880+
[IntrNoMem, IntrHasSideEffects]>;
2881+
28722882
def int_aarch64_sme_zero : DefaultAttrsIntrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
28732883

28742884
class SME_OuterProduct_Intrinsic

llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
395395
template <unsigned MaxIdx, unsigned Scale>
396396
void SelectMultiVectorMove(SDNode *N, unsigned NumVecs, unsigned BaseReg,
397397
unsigned Op);
398-
void SelectMultiVectorMoveZ(SDNode *N, unsigned NumVecs, unsigned Op,
399-
unsigned MaxIdx, unsigned Scale);
398+
void SelectMultiVectorMoveZ(SDNode *N, unsigned NumVecs,
399+
unsigned Op, unsigned MaxIdx, unsigned Scale,
400+
unsigned BaseReg = 0);
400401
bool SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base, SDValue &OffImm);
401402
/// SVE Reg+Imm addressing mode.
402403
template <int64_t Min, int64_t Max>
@@ -2006,18 +2007,27 @@ void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *N, unsigned NumVecs,
20062007

20072008
void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *N, unsigned NumVecs,
20082009
unsigned Op, unsigned MaxIdx,
2009-
unsigned Scale) {
2010+
unsigned Scale, unsigned BaseReg) {
2011+
// Slice can be in different positions
2012+
// The array to vector: llvm.aarch64.sme.readz.<h/v>.<sz>(slice)
2013+
// The tile to vector: llvm.aarch64.sme.readz.<h/v>.<sz>(tile, slice)
2014+
SDValue SliceBase = N->getOperand(2);
2015+
if (BaseReg != AArch64::ZA)
2016+
SliceBase = N->getOperand(3);
20102017

2011-
SDValue SliceBase = N->getOperand(3);
20122018
SDValue Base, Offset;
20132019
if (!SelectSMETileSlice(SliceBase, MaxIdx, Base, Offset, Scale))
20142020
return;
20152021
// The correct Za tile number is computed in Machine Instruction
20162022
// See EmitZAInstr
20172023
// DAG cannot select Za tile as an output register with ZReg
20182024
SDLoc DL(N);
2019-
SDValue Ops[] = {/*TileNum*/ N->getOperand(2), Base, Offset,
2020-
/*Chain*/ N->getOperand(0)};
2025+
SmallVector<SDValue, 6> Ops;
2026+
if (BaseReg != AArch64::ZA )
2027+
Ops.push_back(N->getOperand(2));
2028+
Ops.push_back(Base);
2029+
Ops.push_back(Offset);
2030+
Ops.push_back(N->getOperand(0)); //Chain
20212031
SDNode *Mov = CurDAG->getMachineNode(Op, DL, {MVT::Untyped, MVT::Other}, Ops);
20222032

20232033
EVT VT = N->getValueType(0);
@@ -5342,6 +5352,16 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
53425352
}
53435353
break;
53445354
}
5355+
case Intrinsic::aarch64_sme_readz_x2: {
5356+
SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5357+
AArch64::ZA);
5358+
return;
5359+
}
5360+
case Intrinsic::aarch64_sme_readz_x4: {
5361+
SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5362+
AArch64::ZA);
5363+
return;
5364+
}
53455365
case Intrinsic::swift_async_context_addr: {
53465366
SDLoc DL(Node);
53475367
SDValue Chain = Node->getOperand(0);

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,6 +2995,11 @@ AArch64TargetLowering::EmitZAInstr(unsigned Opc, unsigned BaseReg,
29952995
MIB.addReg(BaseReg + MI.getOperand(StartIdx).getImm()); // Input Za Tile
29962996
StartIdx++;
29972997
} else {
2998+
// Avoids all instructions with mnemonic za.<sz>[Reg, Imm,
2999+
if (MI.getOperand(0).isReg() && !MI.getOperand(1).isImm()) {
3000+
MIB.add(MI.getOperand(StartIdx)); // Output ZPR
3001+
++StartIdx;
3002+
}
29983003
MIB.addReg(BaseReg, RegState::Define).addReg(BaseReg);
29993004
}
30003005
for (unsigned I = StartIdx; I < MI.getNumOperands(); ++I)

llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,8 @@ defm MOVAZ_ZMI : sme2p1_movaz_tile_to_vec<"movaz", int_aarch64_sme_readz_horiz,
818818
int_aarch64_sme_readz_q_horiz, int_aarch64_sme_readz_q_vert>;
819819
defm MOVAZ_2ZMI : sme2p1_movaz_tile_to_vec_vg2<"movaz">;
820820
defm MOVAZ_4ZMI : sme2p1_movaz_tile_to_vec_vg4<"movaz">;
821-
defm MOVAZ_VG2_2ZM : sme2_mova_array_to_vec_vg2_multi<0b010, "movaz">;
822-
defm MOVAZ_VG4_4ZM : sme2_mova_array_to_vec_vg4_multi<0b1100, "movaz">;
821+
defm MOVAZ_VG2_2ZMXI : sme2_movaz_array_to_vec_vg2_multi<"movaz">;
822+
defm MOVAZ_VG4_4ZMXI : sme2_movaz_array_to_vec_vg4_multi<"movaz">;
823823

824824
defm ZERO_MXI : sme2p1_zero_matrix<"zero">;
825825

llvm/lib/Target/AArch64/SMEInstrFormats.td

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ class sme2_movez_to_tile_pseudo<string name, Operand tile_imm, Operand imm_ty, R
117117
let SMEMatrixType = za_flag;
118118
let usesCustomInserter = 1;
119119
}
120+
121+
class sme2_movaz_array_to_tile_pseudo<string name, Operand index_ty, RegisterOperand multi_vector_ty,
122+
SMEMatrixTypeEnum za_flag>
123+
: SMEPseudo2Instr<name, 0>,
124+
Pseudo<(outs multi_vector_ty:$Zd), (ins MatrixIndexGPR32Op8_11:$Rv, index_ty:$imm3), []> {
125+
let SMEMatrixType = za_flag;
126+
let usesCustomInserter = 1;
127+
}
128+
120129
//===----------------------------------------------------------------------===//
121130
// SME pattern match helpers.
122131
//===----------------------------------------------------------------------===//
@@ -4287,7 +4296,7 @@ class sme2_mova_array_to_vec_vg24_multi<bits<4>op, RegisterOperand vector_ty,
42874296
// move array to vector, two registers.
42884297
multiclass sme2_mova_array_to_vec_vg2_multi<bits<3> opc, string mnemonic> {
42894298
def NAME : sme2_mova_array_to_vec_vg24_multi<{opc,?}, ZZ_d_mul_r, MatrixOp64,
4290-
mnemonic, "vgx2"> {
4299+
mnemonic, "vgx2">, SMEPseudo2Instr<NAME, 1>{
42914300
bits<4> Zd;
42924301
let Inst{4-1} = Zd;
42934302
}
@@ -4359,10 +4368,15 @@ multiclass sme2_mova_array_to_vec_vg2_multi<bits<3> opc, string mnemonic> {
43594368
}
43604369
}
43614370

4371+
multiclass sme2_movaz_array_to_vec_vg2_multi<string mnemonic> {
4372+
defm NAME : sme2_mova_array_to_vec_vg2_multi<0b010, mnemonic>;
4373+
def NAME # _PSEUDO : sme2_movaz_array_to_tile_pseudo<NAME, sme_elm_idx0_7, ZZ_d_mul_r, SMEMatrixArray>;
4374+
}
4375+
43624376
// move array to vector, four registers
43634377
multiclass sme2_mova_array_to_vec_vg4_multi<bits<4> opc, string mnemonic> {
43644378
def NAME : sme2_mova_array_to_vec_vg24_multi<opc, ZZZZ_d_mul_r, MatrixOp64,
4365-
mnemonic, "vgx4"> {
4379+
mnemonic, "vgx4">, SMEPseudo2Instr<NAME, 1> {
43664380
bits<3> Zd;
43674381
let Inst{4-2} = Zd;
43684382
}
@@ -4434,6 +4448,11 @@ multiclass sme2_mova_array_to_vec_vg4_multi<bits<4> opc, string mnemonic> {
44344448
}
44354449
}
44364450

4451+
multiclass sme2_movaz_array_to_vec_vg4_multi<string mnemonic> {
4452+
defm NAME : sme2_mova_array_to_vec_vg4_multi<0b1100, mnemonic>;
4453+
def NAME # _PSEUDO : sme2_movaz_array_to_tile_pseudo<NAME, sme_elm_idx0_7, ZZZZ_d_mul_r, SMEMatrixArray>;
4454+
}
4455+
44374456
//===----------------------------------------------------------------------===//
44384457
// SME2 multi-vec saturating shift right narrow
44394458
class sme2_sat_shift_vector_vg2<string mnemonic, bit op, bit u>

0 commit comments

Comments
 (0)