This revision was automatically updated to reflect the committed changes.
CarolineConcatto marked an inline comment as done.
Closed by commit rGfc8acb563ae0: [Clang][SVE2.1] Add clang support for builtins 
 using svcount_t (authored by CarolineConcatto).

Changed prior to commit:
  https://reviews.llvm.org/D150953?vs=527021&id=527068#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150953/new/

https://reviews.llvm.org/D150953

Files:
  clang/include/clang/Basic/Builtins.def
  clang/include/clang/Basic/arm_sve.td
  clang/include/clang/Basic/arm_sve_sme_incl.td
  clang/lib/AST/ASTContext.cpp
  clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c
  clang/utils/TableGen/SveEmitter.cpp

Index: clang/utils/TableGen/SveEmitter.cpp
===================================================================
--- clang/utils/TableGen/SveEmitter.cpp
+++ clang/utils/TableGen/SveEmitter.cpp
@@ -66,7 +66,8 @@
 class SVEType {
   TypeSpec TS;
   bool Float, Signed, Immediate, Void, Constant, Pointer, BFloat;
-  bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp;
+  bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp,
+      Svcount;
   unsigned Bitwidth, ElementBitwidth, NumVectors;
 
 public:
@@ -76,7 +77,8 @@
       : TS(TS), Float(false), Signed(true), Immediate(false), Void(false),
         Constant(false), Pointer(false), BFloat(false), DefaultType(false),
         IsScalable(true), Predicate(false), PredicatePattern(false),
-        PrefetchOp(false), Bitwidth(128), ElementBitwidth(~0U), NumVectors(1) {
+        PrefetchOp(false), Svcount(false), Bitwidth(128), ElementBitwidth(~0U),
+        NumVectors(1) {
     if (!TS.empty())
       applyTypespec();
     applyModifier(CharMod);
@@ -95,13 +97,16 @@
   bool isFloat() const { return Float && !BFloat; }
   bool isBFloat() const { return BFloat && !Float; }
   bool isFloatingPoint() const { return Float || BFloat; }
-  bool isInteger() const { return !isFloatingPoint() && !Predicate; }
+  bool isInteger() const {
+    return !isFloatingPoint() && !Predicate && !Svcount;
+  }
   bool isScalarPredicate() const {
     return !isFloatingPoint() && Predicate && NumVectors == 0;
   }
   bool isPredicateVector() const { return Predicate; }
   bool isPredicatePattern() const { return PredicatePattern; }
   bool isPrefetchOp() const { return PrefetchOp; }
+  bool isSvcount() const { return Svcount; }
   bool isConstant() const { return Constant; }
   unsigned getElementSizeInBits() const { return ElementBitwidth; }
   unsigned getNumVectors() const { return NumVectors; }
@@ -203,6 +208,9 @@
   /// ClassS, so will add type suffixes such as _u32/_s32.
   std::string getMangledName() const { return mangleName(ClassS); }
 
+  /// As above, but mangles the LLVM name instead.
+  std::string getMangledLLVMName() const { return mangleLLVMName(); }
+
   /// Returns true if the intrinsic is overloaded, in that it should also generate
   /// a short form without the type-specifiers, e.g. 'svld1(..)' instead of
   /// 'svld1_u32(..)'.
@@ -233,6 +241,7 @@
 private:
   std::string getMergeSuffix() const { return MergeSuffix; }
   std::string mangleName(ClassKind LocalCK) const;
+  std::string mangleLLVMName() const;
   std::string replaceTemplatedArgs(std::string Name, TypeSpec TS,
                                    std::string Proto) const;
 };
@@ -379,6 +388,9 @@
   if (isScalarPredicate())
     return "b";
 
+  if (isSvcount())
+    return "Qa";
+
   if (isVoidPointer())
     S += "v";
   else if (!isFloatingPoint())
@@ -442,13 +454,15 @@
   if (Void)
     S += "void";
   else {
-    if (isScalableVector())
+    if (isScalableVector() || isSvcount())
       S += "sv";
     if (!Signed && !isFloatingPoint())
       S += "u";
 
     if (Float)
       S += "float";
+    else if (isSvcount())
+      S += "count";
     else if (isScalarPredicate() || isPredicateVector())
       S += "bool";
     else if (isBFloat())
@@ -456,7 +470,7 @@
     else
       S += "int";
 
-    if (!isScalarPredicate() && !isPredicateVector())
+    if (!isScalarPredicate() && !isPredicateVector() && !isSvcount())
       S += utostr(ElementBitwidth);
     if (!isScalableVector() && isVector())
       S += "x" + utostr(getNumElements());
@@ -476,6 +490,9 @@
 void SVEType::applyTypespec() {
   for (char I : TS) {
     switch (I) {
+    case 'Q':
+      Svcount = true;
+      break;
     case 'P':
       Predicate = true;
       break;
@@ -570,6 +587,7 @@
     Float = false;
     BFloat = false;
     Predicate = true;
+    Svcount = false;
     Bitwidth = 16;
     ElementBitwidth = 1;
     break;
@@ -609,18 +627,21 @@
     break;
   case 'u':
     Predicate = false;
+    Svcount = false;
     Signed = false;
     Float = false;
     BFloat = false;
     break;
   case 'x':
     Predicate = false;
+    Svcount = false;
     Signed = true;
     Float = false;
     BFloat = false;
     break;
   case 'i':
     Predicate = false;
+    Svcount = false;
     Float = false;
     BFloat = false;
     ElementBitwidth = Bitwidth = 64;
@@ -630,6 +651,7 @@
     break;
   case 'I':
     Predicate = false;
+    Svcount = false;
     Float = false;
     BFloat = false;
     ElementBitwidth = Bitwidth = 32;
@@ -640,6 +662,7 @@
     break;
   case 'J':
     Predicate = false;
+    Svcount = false;
     Float = false;
     BFloat = false;
     ElementBitwidth = Bitwidth = 32;
@@ -650,6 +673,7 @@
     break;
   case 'k':
     Predicate = false;
+    Svcount = false;
     Signed = true;
     Float = false;
     BFloat = false;
@@ -658,6 +682,7 @@
     break;
   case 'l':
     Predicate = false;
+    Svcount = false;
     Signed = true;
     Float = false;
     BFloat = false;
@@ -666,6 +691,7 @@
     break;
   case 'm':
     Predicate = false;
+    Svcount = false;
     Signed = false;
     Float = false;
     BFloat = false;
@@ -674,6 +700,7 @@
     break;
   case 'n':
     Predicate = false;
+    Svcount = false;
     Signed = false;
     Float = false;
     BFloat = false;
@@ -712,17 +739,20 @@
     break;
   case 'O':
     Predicate = false;
+    Svcount = false;
     Float = true;
     ElementBitwidth = 16;
     break;
   case 'M':
     Predicate = false;
+    Svcount = false;
     Float = true;
     BFloat = false;
     ElementBitwidth = 32;
     break;
   case 'N':
     Predicate = false;
+    Svcount = false;
     Float = true;
     ElementBitwidth = 64;
     break;
@@ -821,6 +851,14 @@
     NumVectors = 0;
     Signed = false;
     break;
+  case '}':
+    Predicate = false;
+    Signed = true;
+    Svcount = true;
+    NumVectors = 0;
+    Float = false;
+    BFloat = false;
+    break;
   default:
     llvm_unreachable("Unhandled character!");
   }
@@ -901,6 +939,8 @@
     std::string TypeCode;
     if (T.isInteger())
       TypeCode = T.isSigned() ? 's' : 'u';
+    else if (T.isSvcount())
+      TypeCode = 'c';
     else if (T.isPredicateVector())
       TypeCode = 'b';
     else if (T.isBFloat())
@@ -913,6 +953,13 @@
   return Ret;
 }
 
+std::string Intrinsic::mangleLLVMName() const {
+  std::string S = getLLVMName();
+
+  // Replace all {d} like expressions with e.g. 'u32'
+  return replaceTemplatedArgs(S, getBaseTypeSpec(), getProto());
+}
+
 std::string Intrinsic::mangleName(ClassKind LocalCK) const {
   std::string S = getName();
 
@@ -995,7 +1042,7 @@
     return encodeEltType("EltTyBFloat16");
   }
 
-  if (T.isPredicateVector()) {
+  if (T.isPredicateVector() || T.isSvcount()) {
     switch (T.getElementSizeInBits()) {
     case 8:
       return encodeEltType("EltTyBool8");
@@ -1185,6 +1232,8 @@
   OS << "typedef __clang_svbfloat16x3_t svbfloat16x3_t;\n";
   OS << "typedef __clang_svbfloat16x4_t svbfloat16x4_t;\n";
 
+  OS << "typedef __SVCount_t svcount_t;\n\n";
+
   OS << "enum svpattern\n";
   OS << "{\n";
   OS << "  SV_POW2 = 0,\n";
@@ -1340,7 +1389,7 @@
     uint64_t Flags = Def->getFlags();
     auto FlagString = std::to_string(Flags);
 
-    std::string LLVMName = Def->getLLVMName();
+    std::string LLVMName = Def->getMangledLLVMName();
     std::string Builtin = Def->getMangledName();
     if (!LLVMName.empty())
       OS << "SVEMAP1(" << Builtin << ", " << LLVMName << ", " << FlagString
Index: clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c
@@ -0,0 +1,62 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
+
+#include <arm_sve.h>
+
+// CHECK-LABEL: @test_svptrue_c8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c8()
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z15test_svptrue_c8v(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c8()
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+svcount_t test_svptrue_c8(void) {
+  return svptrue_c8();
+}
+
+// CHECK-LABEL: @test_svptrue_c16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c16()
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svptrue_c16v(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c16()
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+svcount_t test_svptrue_c16(void) {
+  return svptrue_c16();
+}
+
+// CHECK-LABEL: @test_svptrue_c32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c32()
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svptrue_c32v(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c32()
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+svcount_t test_svptrue_c32(void) {
+  return svptrue_c32();
+}
+
+// CHECK-LABEL: @test_svptrue_c64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c64()
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svptrue_c64v(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.ptrue.c64()
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP0]]
+//
+svcount_t test_svptrue_c64(void) {
+  return svptrue_c64();
+}
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -11455,6 +11455,17 @@
     Type = Context.getScalableVectorType(ElementType, NumElements);
     break;
   }
+  case 'Q': {
+    switch (*Str++) {
+    case 'a': {
+      Type = Context.SveCountTy;
+      break;
+    }
+    default:
+      llvm_unreachable("Unexpected target builtin type");
+    }
+    break;
+  }
   case 'V': {
     char *End;
     unsigned NumElements = strtoul(Str, &End, 10);
Index: clang/include/clang/Basic/arm_sve_sme_incl.td
===================================================================
--- clang/include/clang/Basic/arm_sve_sme_incl.td
+++ clang/include/clang/Basic/arm_sve_sme_incl.td
@@ -55,6 +55,7 @@
 // ------------------
 // P: boolean
 // U: unsigned
+// Q: svcount
 
 // Prototype modifiers
 // -------------------
@@ -124,6 +125,9 @@
 // Y: const pointer to uint32_t
 // Z: const pointer to uint64_t
 
+// Prototype modifiers added for SVE2p1
+// }: svcount_t
+
 class MergeType<int val, string suffix=""> {
   int Value = val;
   string Suffix = suffix;
Index: clang/include/clang/Basic/arm_sve.td
===================================================================
--- clang/include/clang/Basic/arm_sve.td
+++ clang/include/clang/Basic/arm_sve.td
@@ -1861,6 +1861,7 @@
 
 let TargetGuard = "sve2p1" in {
 def SVFCLAMP   : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [], []>;
+def SVPTRUE_COUNT  : SInst<"svptrue_{d}", "}v", "QcQsQiQl", MergeNone, "aarch64_sve_ptrue_{d}", [IsOverloadNone], []>;
 }
 
 let TargetGuard = "sve2p1" in {
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -39,6 +39,8 @@
 //  A -> "reference" to __builtin_va_list
 //  V -> Vector, followed by the number of elements and the base type.
 //  q -> Scalable vector, followed by the number of elements and the base type.
+//  Q -> target builtin type, followed by a character to distinguish the builtin type
+//    Qa -> AArch64 svcount_t builtin type.
 //  E -> ext_vector, followed by the number of elements and the base type.
 //  X -> _Complex, followed by the base type.
 //  Y -> ptrdiff_t
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to