mirror of
https://github.com/intel/llvm.git
synced 2026-02-05 22:17:23 +08:00
[Clang][AArch64][SME] Add ZA zeroing intrinsics
This patch adds support for the following SME ACLE intrinsics (as defined in https://arm-software.github.io/acle/main/acle.html): - svzero_mask_za - svzero_za Co-authored-by: Sagar Kulkarni <sagar.kulkarni1@huawei.com> Reviewed By: sdesmalen Differential Revision: https://reviews.llvm.org/D134677
This commit is contained in:
@@ -114,3 +114,14 @@ defm SVWRITE_ZA16 : ZAWrite<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, I
|
||||
defm SVWRITE_ZA32 : ZAWrite<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>, ImmCheck<2, ImmCheck0_3>]>;
|
||||
defm SVWRITE_ZA64 : ZAWrite<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>, ImmCheck<2, ImmCheck0_1>]>;
|
||||
defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_writeq", [ImmCheck<0, ImmCheck0_15>, ImmCheck<2, ImmCheck0_0>]>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SME - Zero
|
||||
|
||||
let TargetGuard = "sme" in {
|
||||
def SVZERO_MASK_ZA : SInst<"svzero_mask_za", "vi", "", MergeNone, "aarch64_sme_zero",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA],
|
||||
[ImmCheck<0, ImmCheck0_255>]>;
|
||||
def SVZERO_ZA : SInst<"svzero_za", "v", "", MergeNone, "aarch64_sme_zero",
|
||||
[IsOverloadNone, IsStreamingCompatible, IsSharedZA]>;
|
||||
}
|
||||
|
||||
@@ -245,6 +245,7 @@ def ImmCheck0_2 : ImmCheckType<14>; // 0..2
|
||||
def ImmCheck0_3 : ImmCheckType<15>; // 0..3
|
||||
def ImmCheck0_0 : ImmCheckType<16>; // 0..0
|
||||
def ImmCheck0_15 : ImmCheckType<17>; // 0..15
|
||||
def ImmCheck0_255 : ImmCheckType<18>; // 0..255
|
||||
|
||||
class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
|
||||
int Arg = arg;
|
||||
|
||||
@@ -9495,6 +9495,16 @@ Value *CodeGenFunction::EmitSMEReadWrite(SVETypeFlags TypeFlags,
|
||||
return Builder.CreateCall(F, Ops);
|
||||
}
|
||||
|
||||
Value *CodeGenFunction::EmitSMEZero(SVETypeFlags TypeFlags,
|
||||
SmallVectorImpl<Value *> &Ops,
|
||||
unsigned IntID) {
|
||||
// svzero_za() intrinsic zeros the entire za tile and has no paramters.
|
||||
if (Ops.size() == 0)
|
||||
Ops.push_back(llvm::ConstantInt::get(Int32Ty, 255));
|
||||
Function *F = CGM.getIntrinsic(IntID, {});
|
||||
return Builder.CreateCall(F, Ops);
|
||||
}
|
||||
|
||||
// Limit the usage of scalable llvm IR generated by the ACLE by using the
|
||||
// sve dup.x intrinsic instead of IRBuilder::CreateVectorSplat.
|
||||
Value *CodeGenFunction::EmitSVEDupX(Value *Scalar, llvm::Type *Ty) {
|
||||
@@ -9955,6 +9965,9 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID,
|
||||
return EmitSMELd1St1(TypeFlags, Ops, Builtin->LLVMIntrinsic);
|
||||
else if (TypeFlags.isReadZA() || TypeFlags.isWriteZA())
|
||||
return EmitSMEReadWrite(TypeFlags, Ops, Builtin->LLVMIntrinsic);
|
||||
else if (BuiltinID == SME::BI__builtin_sme_svzero_mask_za ||
|
||||
BuiltinID == SME::BI__builtin_sme_svzero_za)
|
||||
return EmitSMEZero(TypeFlags, Ops, Builtin->LLVMIntrinsic);
|
||||
|
||||
/// Should not happen
|
||||
return nullptr;
|
||||
|
||||
@@ -4283,6 +4283,9 @@ public:
|
||||
llvm::Value *EmitSMEReadWrite(SVETypeFlags TypeFlags,
|
||||
llvm::SmallVectorImpl<llvm::Value *> &Ops,
|
||||
unsigned IntID);
|
||||
llvm::Value *EmitSMEZero(SVETypeFlags TypeFlags,
|
||||
llvm::SmallVectorImpl<llvm::Value *> &Ops,
|
||||
unsigned IntID);
|
||||
llvm::Value *EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
||||
|
||||
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
|
||||
|
||||
@@ -3003,6 +3003,10 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
|
||||
if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 15))
|
||||
HasError = true;
|
||||
break;
|
||||
case SVETypeFlags::ImmCheck0_255:
|
||||
if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 255))
|
||||
HasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
46
clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c
Normal file
46
clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c
Normal file
@@ -0,0 +1,46 @@
|
||||
// REQUIRES: aarch64-registered-target
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,CHECK-C
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,CHECK-CXX
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -S -O1 -Werror -o /dev/null %s
|
||||
|
||||
#include <arm_sme_draft_spec_subject_to_change.h>
|
||||
|
||||
// CHECK-C-LABEL: @test_svzero_mask_za(
|
||||
// CHECK-CXX-LABEL: @_Z19test_svzero_mask_zav(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: tail call void @llvm.aarch64.sme.zero(i32 0)
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void test_svzero_mask_za() {
|
||||
svzero_mask_za(0);
|
||||
}
|
||||
|
||||
// CHECK-C-LABEL: @test_svzero_mask_za_1(
|
||||
// CHECK-CXX-LABEL: @_Z21test_svzero_mask_za_1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: tail call void @llvm.aarch64.sme.zero(i32 176)
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void test_svzero_mask_za_1() {
|
||||
svzero_mask_za(176);
|
||||
}
|
||||
|
||||
// CHECK-C-LABEL: @test_svzero_mask_za_2(
|
||||
// CHECK-CXX-LABEL: @_Z21test_svzero_mask_za_2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255)
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void test_svzero_mask_za_2() {
|
||||
svzero_mask_za(255);
|
||||
}
|
||||
|
||||
// CHECK-C-LABEL: @test_svzero_za(
|
||||
// CHECK-CXX-LABEL: @_Z14test_svzero_zav(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: tail call void @llvm.aarch64.sme.zero(i32 255)
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void test_svzero_za() {
|
||||
svzero_za();
|
||||
}
|
||||
@@ -192,6 +192,13 @@ void test_range_0_15(svbool_t pg, void *ptr) {
|
||||
SVE_ACLE_FUNC(svwrite_ver_za8, _s8, _m,)(0, -1, 16, pg, svundef_s8());
|
||||
}
|
||||
|
||||
void test_range_0_255(svbool_t pg, void *ptr) {
|
||||
// expected-error@+1 {{argument value 256 is outside the valid range [0, 255]}}
|
||||
SVE_ACLE_FUNC(svzero_mask_za,,,)(256);
|
||||
// expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 255]}}
|
||||
SVE_ACLE_FUNC(svzero_mask_za,,,)(-1);
|
||||
}
|
||||
|
||||
void test_constant(uint64_t u64, svbool_t pg, void *ptr) {
|
||||
SVE_ACLE_FUNC(svld1_hor_za8,,,)(u64, u64, 0, pg, ptr); // expected-error {{argument to 'svld1_hor_za8' must be a constant integer}}
|
||||
SVE_ACLE_FUNC(svld1_ver_za16,,,)(0, u64, u64, pg, ptr); // expected-error {{argument to 'svld1_ver_za16' must be a constant integer}}
|
||||
|
||||
Reference in New Issue
Block a user