[clang] 578b0bd - [Clang][AArch64][SME] Add ZA zeroing intrinsics

Bryan Chan via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 20 02:57:42 PDT 2023


Author: Bryan Chan
Date: 2023-07-20T06:06:34-04:00
New Revision: 578b0bd4e621304a1ce367e87a53e59e404dec9b

URL: https://github.com/llvm/llvm-project/commit/578b0bd4e621304a1ce367e87a53e59e404dec9b
DIFF: https://github.com/llvm/llvm-project/commit/578b0bd4e621304a1ce367e87a53e59e404dec9b.diff

LOG: [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 at huawei.com>

Reviewed By: sdesmalen

Differential Revision: https://reviews.llvm.org/D134677

Added: 
    clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c

Modified: 
    clang/include/clang/Basic/arm_sme.td
    clang/include/clang/Basic/arm_sve_sme_incl.td
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CodeGenFunction.h
    clang/lib/Sema/SemaChecking.cpp
    clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td
index 4f82615bfb9d95..7c1daf46adfb13 100644
--- a/clang/include/clang/Basic/arm_sme.td
+++ b/clang/include/clang/Basic/arm_sme.td
@@ -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]>;
+}

diff  --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td
index e664b8b3e3f63a..74c9b9266771b0 100644
--- a/clang/include/clang/Basic/arm_sve_sme_incl.td
+++ b/clang/include/clang/Basic/arm_sve_sme_incl.td
@@ -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;

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9d9ad162c6f5d3..599539e1fa4343 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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;

diff  --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 246050b341d67b..8292163ab3365c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4283,6 +4283,9 @@ class CodeGenFunction : public CodeGenTypeCache {
   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,

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 077f560d4fe1bb..17d9889da85e2d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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;
     }
   }
 

diff  --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c
new file mode 100644
index 00000000000000..3ff9f6346c4921
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_zero.c
@@ -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();
+}

diff  --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp
index 2142dbe4c3a523..5c1b8fd3e3905a 100644
--- a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp
+++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_imm.cpp
@@ -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 at +1 {{argument value 256 is outside the valid range [0, 255]}}
+  SVE_ACLE_FUNC(svzero_mask_za,,,)(256);
+  // expected-error at +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}}


        


More information about the cfe-commits mailing list