[clang] fc8acb5 - [Clang][SVE2.1] Add clang support for builtins using svcount_t
Caroline Concatto via cfe-commits
cfe-commits at lists.llvm.org
Wed May 31 08:58:17 PDT 2023
Author: Caroline Concatto
Date: 2023-05-31T15:57:44Z
New Revision: fc8acb563ae019735e646f9964b254cab1efd529
URL: https://github.com/llvm/llvm-project/commit/fc8acb563ae019735e646f9964b254cab1efd529
DIFF: https://github.com/llvm/llvm-project/commit/fc8acb563ae019735e646f9964b254cab1efd529.diff
LOG: [Clang][SVE2.1] Add clang support for builtins using svcount_t
In this patch it is used for the prototype:
* svptrue_c8 (and _c16/_c32/_c64)
As described in: https://github.com/ARM-software/acle/pull/257
Patch by: Sander de Smalen <sander.desmalen at arm.com>
Reviewed By: sdesmalen, david-arm
Differential Revision: https://reviews.llvm.org/D150953
Added:
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c
Modified:
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/utils/TableGen/SveEmitter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index e8cd200257c2a..c8f955a1f4b28 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/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 -> ptr
diff _t
diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index aa7c0553671a5..894a0a1296b04 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -1861,6 +1861,7 @@ def SVBGRP_N : SInst<"svbgrp[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sv
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 {
diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td
index f68140d386473..6b1541d334a25 100644
--- a/clang/include/clang/Basic/arm_sve_sme_incl.td
+++ b/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;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7758c30725a3c..ef3242e81e65f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -11455,6 +11455,17 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
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);
diff --git a/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c b/clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_ptrue.c
new file mode 100644
index 0000000000000..c8fd843500560
--- /dev/null
+++ b/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();
+}
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 55a298eebfcf9..c423e35b5e3b6 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -66,7 +66,8 @@ class ImmCheck {
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 @@ class SVEType {
: 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 @@ class SVEType {
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 @@ class Intrinsic {
/// 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 @@ class Intrinsic {
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 @@ std::string SVEType::builtin_str() const {
if (isScalarPredicate())
return "b";
+ if (isSvcount())
+ return "Qa";
+
if (isVoidPointer())
S += "v";
else if (!isFloatingPoint())
@@ -442,13 +454,15 @@ std::string SVEType::str() const {
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 @@ std::string SVEType::str() const {
else
S += "int";
- if (!isScalarPredicate() && !isPredicateVector())
+ if (!isScalarPredicate() && !isPredicateVector() && !isSvcount())
S += utostr(ElementBitwidth);
if (!isScalableVector() && isVector())
S += "x" + utostr(getNumElements());
@@ -476,6 +490,9 @@ std::string SVEType::str() const {
void SVEType::applyTypespec() {
for (char I : TS) {
switch (I) {
+ case 'Q':
+ Svcount = true;
+ break;
case 'P':
Predicate = true;
break;
@@ -570,6 +587,7 @@ void SVEType::applyModifier(char Mod) {
Float = false;
BFloat = false;
Predicate = true;
+ Svcount = false;
Bitwidth = 16;
ElementBitwidth = 1;
break;
@@ -609,18 +627,21 @@ void SVEType::applyModifier(char Mod) {
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 @@ void SVEType::applyModifier(char Mod) {
break;
case 'I':
Predicate = false;
+ Svcount = false;
Float = false;
BFloat = false;
ElementBitwidth = Bitwidth = 32;
@@ -640,6 +662,7 @@ void SVEType::applyModifier(char Mod) {
break;
case 'J':
Predicate = false;
+ Svcount = false;
Float = false;
BFloat = false;
ElementBitwidth = Bitwidth = 32;
@@ -650,6 +673,7 @@ void SVEType::applyModifier(char Mod) {
break;
case 'k':
Predicate = false;
+ Svcount = false;
Signed = true;
Float = false;
BFloat = false;
@@ -658,6 +682,7 @@ void SVEType::applyModifier(char Mod) {
break;
case 'l':
Predicate = false;
+ Svcount = false;
Signed = true;
Float = false;
BFloat = false;
@@ -666,6 +691,7 @@ void SVEType::applyModifier(char Mod) {
break;
case 'm':
Predicate = false;
+ Svcount = false;
Signed = false;
Float = false;
BFloat = false;
@@ -674,6 +700,7 @@ void SVEType::applyModifier(char Mod) {
break;
case 'n':
Predicate = false;
+ Svcount = false;
Signed = false;
Float = false;
BFloat = false;
@@ -712,17 +739,20 @@ void SVEType::applyModifier(char Mod) {
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 @@ void SVEType::applyModifier(char Mod) {
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 Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
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 @@ std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
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 @@ uint64_t SVEEmitter::encodeTypeFlags(const SVEType &T) {
return encodeEltType("EltTyBFloat16");
}
- if (T.isPredicateVector()) {
+ if (T.isPredicateVector() || T.isSvcount()) {
switch (T.getElementSizeInBits()) {
case 8:
return encodeEltType("EltTyBool8");
@@ -1185,6 +1232,8 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
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 @@ void SVEEmitter::createCodeGenMap(raw_ostream &OS) {
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
More information about the cfe-commits
mailing list