[llvm] aa0a413 - [AArch64][SME] Add some SME PSTATE setting/query intrinsics
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 22 02:26:57 PDT 2022
Author: David Sherwood
Date: 2022-06-22T10:26:45+01:00
New Revision: aa0a413df819f80dbb22ee382dffeaad2e5caa55
URL: https://github.com/llvm/llvm-project/commit/aa0a413df819f80dbb22ee382dffeaad2e5caa55
DIFF: https://github.com/llvm/llvm-project/commit/aa0a413df819f80dbb22ee382dffeaad2e5caa55.diff
LOG: [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
Added:
llvm/test/CodeGen/AArch64/sme-get-pstatesm.ll
llvm/test/CodeGen/AArch64/sme-read-write-tpidr2.ll
Modified:
llvm/include/llvm/IR/IntrinsicsAArch64.td
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index a92993df5ee62..4d54a092c3038 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -2663,4 +2663,19 @@ let TargetPrefix = "aarch64" in {
def int_aarch64_sme_cntsh : AdvSIMD_SME_CNTSB_Intrinsic;
def int_aarch64_sme_cntsw : AdvSIMD_SME_CNTSB_Intrinsic;
def int_aarch64_sme_cntsd : AdvSIMD_SME_CNTSB_Intrinsic;
+
+ //
+ // PSTATE Functions
+ //
+
+ def int_aarch64_sme_get_pstatesm
+ : DefaultAttrsIntrinsic<[llvm_i64_ty], [],
+ [IntrReadMem, IntrInaccessibleMemOnly]>;
+
+ def int_aarch64_sme_get_tpidr2
+ : DefaultAttrsIntrinsic<[llvm_i64_ty], [],
+ [IntrNoMem, IntrHasSideEffects]>;
+ def int_aarch64_sme_set_tpidr2
+ : DefaultAttrsIntrinsic<[], [llvm_i64_ty],
+ [IntrNoMem, IntrHasSideEffects]>;
}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 61da79f8fbe3d..062ba61fd01a2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1076,6 +1076,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FADD, VT, Custom);
}
+ if (Subtarget->hasSME()) {
+ setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
+ }
+
if (Subtarget->hasSVE()) {
for (auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
setOperationAction(ISD::BITREVERSE, VT, Custom);
@@ -4309,12 +4313,12 @@ static SDValue lowerConvertToSVBool(SDValue Op, SelectionDAG &DAG) {
SDValue AArch64TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
SelectionDAG &DAG) const {
unsigned IntNo = Op.getConstantOperandVal(1);
+ SDLoc DL(Op);
switch (IntNo) {
default:
return SDValue(); // Don't custom lower most intrinsics.
case Intrinsic::aarch64_mops_memset_tag: {
auto Node = cast<MemIntrinsicSDNode>(Op.getNode());
- SDLoc DL(Op);
SDValue Chain = Node->getChain();
SDValue Dst = Op.getOperand(2);
SDValue Val = Op.getOperand(3);
@@ -4336,6 +4340,15 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
// changed.
return DAG.getMergeValues({MS.getValue(0), MS.getValue(2)}, DL);
}
+ case Intrinsic::aarch64_sme_get_pstatesm: {
+ SDValue Chain = Op.getOperand(0);
+ SDValue MRS = DAG.getNode(
+ AArch64ISD::MRS, DL, DAG.getVTList(MVT::i64, MVT::Glue, MVT::Other),
+ Chain, DAG.getConstant(AArch64SysReg::SVCR, DL, MVT::i64));
+ SDValue Mask = DAG.getConstant(/* PSTATE.SM */ 1, DL, MVT::i64);
+ SDValue And = DAG.getNode(ISD::AND, DL, MVT::i64, MRS, Mask);
+ return DAG.getMergeValues({And, Chain}, DL);
+ }
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 07a5c1bbf32cb..55f6311e5db71 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -138,6 +138,12 @@ def : InstAlias<"smstop", (MSRpstatesvcrImm1 0b011, 0b0)>;
def : InstAlias<"smstop sm", (MSRpstatesvcrImm1 0b001, 0b0)>;
def : InstAlias<"smstop za", (MSRpstatesvcrImm1 0b010, 0b0)>;
+// Read and write TPIDR2_EL0
+def : Pat<(int_aarch64_sme_set_tpidr2 i64:$val),
+ (MSR 0xde85, GPR64:$val)>;
+def : Pat<(i64 (int_aarch64_sme_get_tpidr2)),
+ (MRS 0xde85)>;
+
//===----------------------------------------------------------------------===//
// SVE2 instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/AArch64/sme-get-pstatesm.ll b/llvm/test/CodeGen/AArch64/sme-get-pstatesm.ll
new file mode 100644
index 0000000000000..2586a8c40793f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-get-pstatesm.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -verify-machineinstrs < %s | FileCheck %s
+
+define i64 @is_streaming() {
+; CHECK-LABEL: is_streaming:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mrs x8, SVCR
+; CHECK-NEXT: and x0, x8, #0x1
+; CHECK-NEXT: ret
+ %pstate = call i64 @llvm.aarch64.sme.get.pstatesm()
+ ret i64 %pstate
+}
+
+declare i64 @llvm.aarch64.sme.get.pstatesm()
diff --git a/llvm/test/CodeGen/AArch64/sme-read-write-tpidr2.ll b/llvm/test/CodeGen/AArch64/sme-read-write-tpidr2.ll
new file mode 100644
index 0000000000000..c266aa2febd4a
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-read-write-tpidr2.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64 -mattr=+sme < %s | FileCheck %s
+
+define i64 @get_tpidr2_el0() {
+; CHECK-LABEL: get_tpidr2_el0:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mrs x0, TPIDR2_EL0
+; CHECK-NEXT: ret
+ %res = call i64 @llvm.aarch64.sme.get.tpidr2()
+ ret i64 %res
+}
+
+define void @set_tpidr2_el0(i64 %v) {
+; CHECK-LABEL: set_tpidr2_el0:
+; CHECK: // %bb.0:
+; CHECK-NEXT: msr TPIDR2_EL0, x0
+; CHECK-NEXT: ret
+ call void @llvm.aarch64.sme.set.tpidr2(i64 %v)
+ ret void
+}
+
+declare i64 @llvm.aarch64.sme.get.tpidr2()
+declare void @llvm.aarch64.sme.set.tpidr2(i64 %v)
More information about the llvm-commits
mailing list