Skip to content

Commit aa0a413

Browse files
committed
[AArch64][SME] Add some SME PSTATE setting/query intrinsics
This patch adds support for: * Querying the PSTATE.SM state with @llvm.aarch64.sme.get.pstatesm * Reading/writing the TPIDR2 register with new @llvm.aarch64.sme.get.tpidr2 and @llvm.aarch64.sme.set.tpidr2 intrinsics. Tests added here: CodeGen/AArch64/sme-get-pstatesm.ll CodeGen/AArch64/sme-read-write-tpidr2.ll Differential Revision: https://reviews.llvm.org/D127957
1 parent 20869c5 commit aa0a413

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

llvm/include/llvm/IR/IntrinsicsAArch64.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,4 +2663,19 @@ let TargetPrefix = "aarch64" in {
26632663
def int_aarch64_sme_cntsh : AdvSIMD_SME_CNTSB_Intrinsic;
26642664
def int_aarch64_sme_cntsw : AdvSIMD_SME_CNTSB_Intrinsic;
26652665
def int_aarch64_sme_cntsd : AdvSIMD_SME_CNTSB_Intrinsic;
2666+
2667+
//
2668+
// PSTATE Functions
2669+
//
2670+
2671+
def int_aarch64_sme_get_pstatesm
2672+
: DefaultAttrsIntrinsic<[llvm_i64_ty], [],
2673+
[IntrReadMem, IntrInaccessibleMemOnly]>;
2674+
2675+
def int_aarch64_sme_get_tpidr2
2676+
: DefaultAttrsIntrinsic<[llvm_i64_ty], [],
2677+
[IntrNoMem, IntrHasSideEffects]>;
2678+
def int_aarch64_sme_set_tpidr2
2679+
: DefaultAttrsIntrinsic<[], [llvm_i64_ty],
2680+
[IntrNoMem, IntrHasSideEffects]>;
26662681
}

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
10761076
setOperationAction(ISD::FADD, VT, Custom);
10771077
}
10781078

1079+
if (Subtarget->hasSME()) {
1080+
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
1081+
}
1082+
10791083
if (Subtarget->hasSVE()) {
10801084
for (auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
10811085
setOperationAction(ISD::BITREVERSE, VT, Custom);
@@ -4309,12 +4313,12 @@ static SDValue lowerConvertToSVBool(SDValue Op, SelectionDAG &DAG) {
43094313
SDValue AArch64TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
43104314
SelectionDAG &DAG) const {
43114315
unsigned IntNo = Op.getConstantOperandVal(1);
4316+
SDLoc DL(Op);
43124317
switch (IntNo) {
43134318
default:
43144319
return SDValue(); // Don't custom lower most intrinsics.
43154320
case Intrinsic::aarch64_mops_memset_tag: {
43164321
auto Node = cast<MemIntrinsicSDNode>(Op.getNode());
4317-
SDLoc DL(Op);
43184322
SDValue Chain = Node->getChain();
43194323
SDValue Dst = Op.getOperand(2);
43204324
SDValue Val = Op.getOperand(3);
@@ -4336,6 +4340,15 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
43364340
// changed.
43374341
return DAG.getMergeValues({MS.getValue(0), MS.getValue(2)}, DL);
43384342
}
4343+
case Intrinsic::aarch64_sme_get_pstatesm: {
4344+
SDValue Chain = Op.getOperand(0);
4345+
SDValue MRS = DAG.getNode(
4346+
AArch64ISD::MRS, DL, DAG.getVTList(MVT::i64, MVT::Glue, MVT::Other),
4347+
Chain, DAG.getConstant(AArch64SysReg::SVCR, DL, MVT::i64));
4348+
SDValue Mask = DAG.getConstant(/* PSTATE.SM */ 1, DL, MVT::i64);
4349+
SDValue And = DAG.getNode(ISD::AND, DL, MVT::i64, MRS, Mask);
4350+
return DAG.getMergeValues({And, Chain}, DL);
4351+
}
43394352
}
43404353
}
43414354

llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ def : InstAlias<"smstop", (MSRpstatesvcrImm1 0b011, 0b0)>;
138138
def : InstAlias<"smstop sm", (MSRpstatesvcrImm1 0b001, 0b0)>;
139139
def : InstAlias<"smstop za", (MSRpstatesvcrImm1 0b010, 0b0)>;
140140

141+
// Read and write TPIDR2_EL0
142+
def : Pat<(int_aarch64_sme_set_tpidr2 i64:$val),
143+
(MSR 0xde85, GPR64:$val)>;
144+
def : Pat<(i64 (int_aarch64_sme_get_tpidr2)),
145+
(MRS 0xde85)>;
146+
141147
//===----------------------------------------------------------------------===//
142148
// SVE2 instructions
143149
//===----------------------------------------------------------------------===//
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -verify-machineinstrs < %s | FileCheck %s
3+
4+
define i64 @is_streaming() {
5+
; CHECK-LABEL: is_streaming:
6+
; CHECK: // %bb.0:
7+
; CHECK-NEXT: mrs x8, SVCR
8+
; CHECK-NEXT: and x0, x8, #0x1
9+
; CHECK-NEXT: ret
10+
%pstate = call i64 @llvm.aarch64.sme.get.pstatesm()
11+
ret i64 %pstate
12+
}
13+
14+
declare i64 @llvm.aarch64.sme.get.pstatesm()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=aarch64 -mattr=+sme < %s | FileCheck %s
3+
4+
define i64 @get_tpidr2_el0() {
5+
; CHECK-LABEL: get_tpidr2_el0:
6+
; CHECK: // %bb.0:
7+
; CHECK-NEXT: mrs x0, TPIDR2_EL0
8+
; CHECK-NEXT: ret
9+
%res = call i64 @llvm.aarch64.sme.get.tpidr2()
10+
ret i64 %res
11+
}
12+
13+
define void @set_tpidr2_el0(i64 %v) {
14+
; CHECK-LABEL: set_tpidr2_el0:
15+
; CHECK: // %bb.0:
16+
; CHECK-NEXT: msr TPIDR2_EL0, x0
17+
; CHECK-NEXT: ret
18+
call void @llvm.aarch64.sme.set.tpidr2(i64 %v)
19+
ret void
20+
}
21+
22+
declare i64 @llvm.aarch64.sme.get.tpidr2()
23+
declare void @llvm.aarch64.sme.set.tpidr2(i64 %v)

0 commit comments

Comments
 (0)