This revision was automatically updated to reflect the committed changes.
Closed by commit rG5087ace65197: [Clang][SVE] Parse builtin type string for
scalable vectors (authored by sdesmalen).
Changed prior to commit:
https://reviews.llvm.org/D75298?vs=249966&id=250421#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75298/new/
https://reviews.llvm.org/D75298
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/Basic/AArch64SVEACLETypes.def
clang/include/clang/Basic/Builtins.def
clang/include/clang/Basic/BuiltinsAArch64.def
clang/include/clang/Basic/arm_sve.td
clang/lib/AST/ASTContext.cpp
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Headers/CMakeLists.txt
clang/lib/Headers/module.modulemap
clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c
clang/utils/TableGen/CMakeLists.txt
clang/utils/TableGen/SveEmitter.cpp
clang/utils/TableGen/TableGen.cpp
clang/utils/TableGen/TableGenBackends.h
Index: clang/utils/TableGen/TableGenBackends.h
===================================================================
--- clang/utils/TableGen/TableGenBackends.h
+++ clang/utils/TableGen/TableGenBackends.h
@@ -91,6 +91,8 @@
void EmitNeonSema2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitNeonTest2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitSveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+
void EmitMveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitMveBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitMveBuiltinSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
Index: clang/utils/TableGen/TableGen.cpp
===================================================================
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -70,6 +70,7 @@
GenArmMveBuiltinSema,
GenArmMveBuiltinCG,
GenArmMveBuiltinAliases,
+ GenArmSveHeader,
GenArmCdeHeader,
GenArmCdeBuiltinDef,
GenArmCdeBuiltinSema,
@@ -185,6 +186,8 @@
"Generate ARM NEON sema support for clang"),
clEnumValN(GenArmNeonTest, "gen-arm-neon-test",
"Generate ARM NEON tests for clang"),
+ clEnumValN(GenArmSveHeader, "gen-arm-sve-header",
+ "Generate arm_sve.h for clang"),
clEnumValN(GenArmMveHeader, "gen-arm-mve-header",
"Generate arm_mve.h for clang"),
clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def",
@@ -366,6 +369,9 @@
case GenArmMveBuiltinAliases:
EmitMveBuiltinAliases(Records, OS);
break;
+ case GenArmSveHeader:
+ EmitSveHeader(Records, OS);
+ break;
case GenArmCdeHeader:
EmitCdeHeader(Records, OS);
break;
Index: clang/utils/TableGen/SveEmitter.cpp
===================================================================
--- /dev/null
+++ clang/utils/TableGen/SveEmitter.cpp
@@ -0,0 +1,128 @@
+//===- SveEmitter.cpp - Generate arm_sve.h for use with clang -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend is responsible for emitting arm_sve.h, which includes
+// a declaration and definition of each function specified by the ARM C/C++
+// Language Extensions (ACLE).
+//
+// For details, visit:
+// https://developer.arm.com/architectures/system-architectures/software-standards/acle
+//
+// Each SVE instruction is implemented in terms of 1 or more functions which
+// are suffixed with the element type of the input vectors. Functions may be
+// implemented in terms of generic vector operations such as +, *, -, etc. or
+// by calling a __builtin_-prefixed function which will be handled by clang's
+// CodeGen library.
+//
+// See also the documentation in include/clang/Basic/arm_sve.td.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/Error.h"
+#include <string>
+#include <sstream>
+#include <set>
+#include <cctype>
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// SVEEmitter
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class SVEEmitter {
+private:
+ RecordKeeper &Records;
+
+public:
+ SVEEmitter(RecordKeeper &R) : Records(R) {}
+
+ // run - Emit arm_sve.h
+ void run(raw_ostream &o);
+};
+
+} // end anonymous namespace
+
+
+//===----------------------------------------------------------------------===//
+// SVEEmitter implementation
+//===----------------------------------------------------------------------===//
+
+void SVEEmitter::run(raw_ostream &OS) {
+ OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
+ "-----------------------------------===\n"
+ " *\n"
+ " *\n"
+ " * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
+ "Exceptions.\n"
+ " * See https://llvm.org/LICENSE.txt for license information.\n"
+ " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
+ " *\n"
+ " *===-----------------------------------------------------------------"
+ "------===\n"
+ " */\n\n";
+
+ OS << "#ifndef __ARM_SVE_H\n";
+ OS << "#define __ARM_SVE_H\n\n";
+
+ OS << "#if !defined(__ARM_FEATURE_SVE)\n";
+ OS << "#error \"SVE support not enabled\"\n";
+ OS << "#else\n\n";
+
+ OS << "#include <stdint.h>\n\n";
+ OS << "#ifndef __cplusplus\n";
+ OS << "#include <stdbool.h>\n";
+ OS << "#endif\n\n";
+
+ OS << "typedef __fp16 float16_t;\n";
+ OS << "typedef float float32_t;\n";
+ OS << "typedef double float64_t;\n";
+ OS << "typedef bool bool_t;\n\n";
+
+ OS << "typedef __SVInt8_t svint8_t;\n";
+ OS << "typedef __SVInt16_t svint16_t;\n";
+ OS << "typedef __SVInt32_t svint32_t;\n";
+ OS << "typedef __SVInt64_t svint64_t;\n";
+ OS << "typedef __SVUint8_t svuint8_t;\n";
+ OS << "typedef __SVUint16_t svuint16_t;\n";
+ OS << "typedef __SVUint32_t svuint32_t;\n";
+ OS << "typedef __SVUint64_t svuint64_t;\n";
+ OS << "typedef __SVFloat16_t svfloat16_t;\n";
+ OS << "typedef __SVFloat32_t svfloat32_t;\n";
+ OS << "typedef __SVFloat64_t svfloat64_t;\n";
+ OS << "typedef __SVBool_t svbool_t;\n\n";
+
+ OS << "#define svld1_u8(...) __builtin_sve_svld1_u8(__VA_ARGS__)\n";
+ OS << "#define svld1_u16(...) __builtin_sve_svld1_u16(__VA_ARGS__)\n";
+ OS << "#define svld1_u32(...) __builtin_sve_svld1_u32(__VA_ARGS__)\n";
+ OS << "#define svld1_u64(...) __builtin_sve_svld1_u64(__VA_ARGS__)\n";
+ OS << "#define svld1_s8(...) __builtin_sve_svld1_s8(__VA_ARGS__)\n";
+ OS << "#define svld1_s16(...) __builtin_sve_svld1_s16(__VA_ARGS__)\n";
+ OS << "#define svld1_s32(...) __builtin_sve_svld1_s32(__VA_ARGS__)\n";
+ OS << "#define svld1_s64(...) __builtin_sve_svld1_s64(__VA_ARGS__)\n";
+ OS << "#define svld1_f16(...) __builtin_sve_svld1_f16(__VA_ARGS__)\n";
+ OS << "#define svld1_f32(...) __builtin_sve_svld1_f32(__VA_ARGS__)\n";
+ OS << "#define svld1_f64(...) __builtin_sve_svld1_f64(__VA_ARGS__)\n";
+
+ OS << "#endif /*__ARM_FEATURE_SVE */\n";
+ OS << "#endif /* __ARM_SVE_H */\n";
+}
+
+namespace clang {
+void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
+ SVEEmitter(Records).run(OS);
+}
+
+} // End namespace clang
Index: clang/utils/TableGen/CMakeLists.txt
===================================================================
--- clang/utils/TableGen/CMakeLists.txt
+++ clang/utils/TableGen/CMakeLists.txt
@@ -17,6 +17,7 @@
ClangTypeNodesEmitter.cpp
MveEmitter.cpp
NeonEmitter.cpp
+ SveEmitter.cpp
TableGen.cpp
)
set_target_properties(clang-tblgen PROPERTIES FOLDER "Clang tablegenning")
Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s -D__ARM_FEATURE_SVE | FileCheck %s
+
+#include <arm_sve.h>
+//
+// ld1
+//
+
+svint8_t test_svld1_s8(svbool_t pg, const int8_t *base)
+{
+ // CHECK-LABEL: test_svld1_s8
+ // CHECK: <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0nxv16i8(<vscale x 16 x i8>* %{{.*}}, i32 1, <vscale x 16 x i1> %{{.*}}, <vscale x 16 x i8> zeroinitializer)
+ return svld1_s8(pg, base);
+}
+
+svint16_t test_svld1_s16(svbool_t pg, const int16_t *base)
+{
+ // CHECK-LABEL: test_svld1_s16
+ // CHECK: <vscale x 8 x i16> @llvm.masked.load.nxv8i16.p0nxv8i16(<vscale x 8 x i16>* %{{.*}}, i32 1, <vscale x 8 x i1> %{{.*}}, <vscale x 8 x i16> zeroinitializer)
+ return svld1_s16(pg, base);
+}
+
+svint32_t test_svld1_s32(svbool_t pg, const int32_t *base)
+{
+ // CHECK-LABEL: test_svld1_s32
+ // CHECK: <vscale x 4 x i32> @llvm.masked.load.nxv4i32.p0nxv4i32(<vscale x 4 x i32>* %{{.*}}, i32 1, <vscale x 4 x i1> %{{.*}}, <vscale x 4 x i32> zeroinitializer)
+ return svld1_s32(pg, base);
+}
+
+svint64_t test_svld1_s64(svbool_t pg, const int64_t *base)
+{
+ // CHECK-LABEL: test_svld1_s64
+ // CHECK: <vscale x 2 x i64> @llvm.masked.load.nxv2i64.p0nxv2i64(<vscale x 2 x i64>* %{{.*}}, i32 1, <vscale x 2 x i1> %{{.*}}, <vscale x 2 x i64> zeroinitializer)
+ return svld1_s64(pg, base);
+}
+
+svuint8_t test_svld1_u8(svbool_t pg, const uint8_t *base)
+{
+ // CHECK-LABEL: test_svld1_u8
+ // CHECK: <vscale x 16 x i8> @llvm.masked.load.nxv16i8.p0nxv16i8(<vscale x 16 x i8>* %{{.*}}, i32 1, <vscale x 16 x i1> %{{.*}}, <vscale x 16 x i8> zeroinitializer)
+ return svld1_u8(pg, base);
+}
+
+svuint16_t test_svld1_u16(svbool_t pg, const uint16_t *base)
+{
+ // CHECK-LABEL: test_svld1_u16
+ // CHECK: <vscale x 8 x i16> @llvm.masked.load.nxv8i16.p0nxv8i16(<vscale x 8 x i16>* %{{.*}}, i32 1, <vscale x 8 x i1> %{{.*}}, <vscale x 8 x i16> zeroinitializer)
+ return svld1_u16(pg, base);
+}
+
+svuint32_t test_svld1_u32(svbool_t pg, const uint32_t *base)
+{
+ // CHECK-LABEL: test_svld1_u32
+ // CHECK: <vscale x 4 x i32> @llvm.masked.load.nxv4i32.p0nxv4i32(<vscale x 4 x i32>* %{{.*}}, i32 1, <vscale x 4 x i1> %{{.*}}, <vscale x 4 x i32> zeroinitializer)
+ return svld1_u32(pg, base);
+}
+
+svuint64_t test_svld1_u64(svbool_t pg, const uint64_t *base)
+{
+ // CHECK-LABEL: test_svld1_u64
+ // CHECK: <vscale x 2 x i64> @llvm.masked.load.nxv2i64.p0nxv2i64(<vscale x 2 x i64>* %{{.*}}, i32 1, <vscale x 2 x i1> %{{.*}}, <vscale x 2 x i64> zeroinitializer)
+ return svld1_u64(pg, base);
+}
+
+svfloat16_t test_svld1_f16(svbool_t pg, const float16_t *base)
+{
+ // CHECK-LABEL: test_svld1_f16
+ // CHECK: <vscale x 8 x half> @llvm.masked.load.nxv8f16.p0nxv8f16(<vscale x 8 x half>* %{{.*}}, i32 1, <vscale x 8 x i1> %{{.*}}, <vscale x 8 x half> zeroinitializer)
+ return svld1_f16(pg, base);
+}
+
+svfloat32_t test_svld1_f32(svbool_t pg, const float32_t *base)
+{
+ // CHECK-LABEL: test_svld1_f32
+ // CHECK: <vscale x 4 x float> @llvm.masked.load.nxv4f32.p0nxv4f32(<vscale x 4 x float>* %{{.*}}, i32 1, <vscale x 4 x i1> %{{.*}}, <vscale x 4 x float> zeroinitializer)
+ return svld1_f32(pg, base);
+}
+
+svfloat64_t test_svld1_f64(svbool_t pg, const float64_t *base)
+{
+ // CHECK-LABEL: test_svld1_f64
+ // CHECK: <vscale x 2 x double> @llvm.masked.load.nxv2f64.p0nxv2f64(<vscale x 2 x double>* %{{.*}}, i32 1, <vscale x 2 x i1> %{{.*}}, <vscale x 2 x double> zeroinitializer)
+ return svld1_f64(pg, base);
+}
Index: clang/lib/Headers/module.modulemap
===================================================================
--- clang/lib/Headers/module.modulemap
+++ clang/lib/Headers/module.modulemap
@@ -27,6 +27,12 @@
header "arm_fp16.h"
export *
}
+
+ explicit module sve {
+ requires sve
+ header "arm_sve.h"
+ export *
+ }
}
explicit module intel {
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -184,6 +184,8 @@
clang_generate_header(-gen-arm-neon arm_neon.td arm_neon.h)
# Generate arm_fp16.h
clang_generate_header(-gen-arm-fp16 arm_fp16.td arm_fp16.h)
+# Generate arm_sve.h
+clang_generate_header(-gen-arm-sve-header arm_sve.td arm_sve.h)
# Generate arm_mve.h
clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h)
# Generate arm_cde.h
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -3900,6 +3900,11 @@
llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
llvm::Type *Ty, bool usgn, const char *name);
llvm::Value *vectorWrapScalar16(llvm::Value *Op);
+
+ llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred, llvm::VectorType *VTy);
+ llvm::Value *EmitSVEMaskedLoad(llvm::Type *ReturnTy,
+ SmallVectorImpl<llvm::Value *> &Ops);
+
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
llvm::Triple::ArchType Arch);
llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -495,13 +495,15 @@
// Scan function arguments for vector width.
for (llvm::Argument &A : CurFn->args())
if (auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
- LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getFixedSize());
+ LargestVectorWidth =
+ std::max((uint64_t)LargestVectorWidth,
+ VT->getPrimitiveSizeInBits().getKnownMinSize());
// Update vector width based on return type.
if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType()))
- LargestVectorWidth = std::max((uint64_t)LargestVectorWidth,
- VT->getPrimitiveSizeInBits().getFixedSize());
+ LargestVectorWidth =
+ std::max((uint64_t)LargestVectorWidth,
+ VT->getPrimitiveSizeInBits().getKnownMinSize());
// Add the required-vector-width attribute. This contains the max width from:
// 1. min-vector-width attribute used in the source program.
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -7384,6 +7384,58 @@
return Op;
}
+// Reinterpret the input predicate so that it can be used to correctly isolate
+// the elements of the specified datatype.
+Value *CodeGenFunction::EmitSVEPredicateCast(Value *Pred,
+ llvm::VectorType *VTy) {
+ llvm::VectorType *RTy = llvm::VectorType::get(
+ IntegerType::get(getLLVMContext(), 1), VTy->getElementCount());
+ if (Pred->getType() == RTy)
+ return Pred;
+
+ unsigned IntID;
+ llvm::Type *IntrinsicTy;
+ switch (VTy->getNumElements()) {
+ default:
+ llvm_unreachable("unsupported element count!");
+ case 2:
+ case 4:
+ case 8:
+ IntID = Intrinsic::aarch64_sve_convert_from_svbool;
+ IntrinsicTy = RTy;
+ break;
+ case 16:
+ IntID = Intrinsic::aarch64_sve_convert_to_svbool;
+ IntrinsicTy = Pred->getType();
+ break;
+ }
+
+ Function *F = CGM.getIntrinsic(IntID, IntrinsicTy);
+ Value *C = Builder.CreateCall(F, Pred);
+ assert(C->getType() == RTy && "Unexpected return type!");
+ return C;
+}
+
+Value *CodeGenFunction::EmitSVEMaskedLoad(llvm::Type *ReturnTy,
+ SmallVectorImpl<Value *> &Ops) {
+ llvm::PointerType *PTy = cast<llvm::PointerType>(Ops[1]->getType());
+ llvm::Type *MemEltTy = PTy->getPointerElementType();
+
+ // The vector type that is returned may be different from the
+ // eventual type loaded from memory.
+ auto VectorTy = cast<llvm::VectorType>(ReturnTy);
+ auto MemoryTy =
+ llvm::VectorType::get(MemEltTy, VectorTy->getVectorElementCount());
+
+ Value *Offset = Builder.getInt32(0);
+ Value *Predicate = EmitSVEPredicateCast(Ops[0], MemoryTy);
+ Value *BasePtr = Builder.CreateBitCast(Ops[1], MemoryTy->getPointerTo());
+ BasePtr = Builder.CreateGEP(MemoryTy, BasePtr, Offset);
+
+ Value *Splat0 = Constant::getNullValue(MemoryTy);
+ return Builder.CreateMaskedLoad(BasePtr, Align(1), Predicate, Splat0);
+}
+
Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
const CallExpr *E,
llvm::Triple::ArchType Arch) {
@@ -7420,6 +7472,27 @@
return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
}
+ switch (BuiltinID) {
+ case AArch64::BI__builtin_sve_svld1_u8:
+ case AArch64::BI__builtin_sve_svld1_u16:
+ case AArch64::BI__builtin_sve_svld1_u32:
+ case AArch64::BI__builtin_sve_svld1_u64:
+ case AArch64::BI__builtin_sve_svld1_s8:
+ case AArch64::BI__builtin_sve_svld1_s16:
+ case AArch64::BI__builtin_sve_svld1_s32:
+ case AArch64::BI__builtin_sve_svld1_s64:
+ case AArch64::BI__builtin_sve_svld1_f16:
+ case AArch64::BI__builtin_sve_svld1_f32:
+ case AArch64::BI__builtin_sve_svld1_f64: {
+ llvm::SmallVector<Value *, 4> Ops = {EmitScalarExpr(E->getArg(0)),
+ EmitScalarExpr(E->getArg(1))};
+ llvm::Type *Ty = ConvertType(E->getType());
+ return EmitSVEMaskedLoad(Ty, Ops);
+ }
+ default:
+ break;
+ }
+
if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *RW = EmitScalarExpr(E->getArg(1));
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2100,16 +2100,16 @@
// Because the length is only known at runtime, we use a dummy value
// of 0 for the static length. The alignment values are those defined
// by the Procedure Call Standard for the Arm Architecture.
-#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\
- case BuiltinType::Id: \
- Width = 0; \
- Align = 128; \
- break;
-#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \
- case BuiltinType::Id: \
- Width = 0; \
- Align = 16; \
- break;
+#define SVE_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, IsSigned, IsFP) \
+ case BuiltinType::Id: \
+ Width = 0; \
+ Align = 128; \
+ break;
+#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
+ case BuiltinType::Id: \
+ Width = 0; \
+ Align = 16; \
+ break;
#include "clang/Basic/AArch64SVEACLETypes.def"
}
break;
@@ -3584,6 +3584,28 @@
return QualType(newType, 0);
}
+/// getScalableVectorType - Return the unique reference to a scalable vector
+/// type of the specified element type and size. VectorType must be a built-in
+/// type.
+QualType ASTContext::getScalableVectorType(QualType EltTy,
+ unsigned NumElts) const {
+ if (Target->hasAArch64SVETypes()) {
+ uint64_t EltTySize = getTypeSize(EltTy);
+#define SVE_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, IsSigned, IsFP) \
+ if (!EltTy->isBooleanType() && \
+ ((EltTy->hasIntegerRepresentation() && \
+ EltTy->hasSignedIntegerRepresentation() == IsSigned) || \
+ (EltTy->hasFloatingRepresentation() && IsFP)) && \
+ EltTySize == ElBits && NumElts == NumEls) \
+ return SingletonId;
+#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
+ if (EltTy->isBooleanType() && NumElts == NumEls) \
+ return SingletonId;
+#include "clang/Basic/AArch64SVEACLETypes.def"
+ }
+ return QualType();
+}
+
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
@@ -9699,6 +9721,19 @@
else
Type = Context.getLValueReferenceType(Type);
break;
+ case 'q': {
+ char *End;
+ unsigned NumElements = strtoul(Str, &End, 10);
+ assert(End != Str && "Missing vector size");
+ Str = End;
+
+ QualType ElementType = DecodeTypeFromStr(Str, Context, Error,
+ RequiresICE, false);
+ assert(!RequiresICE && "Can't require vector ICE");
+
+ Type = Context.getScalableVectorType(ElementType, NumElements);
+ break;
+ }
case 'V': {
char *End;
unsigned NumElements = strtoul(Str, &End, 10);
Index: clang/include/clang/Basic/arm_sve.td
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/arm_sve.td
@@ -0,0 +1,14 @@
+//===--- arm_sve.td - ARM SVE compiler interface ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TableGen definitions from which the ARM SVE header
+// file will be generated. See:
+//
+// https://developer.arm.com/architectures/system-architectures/software-standards/acle
+//
+//===----------------------------------------------------------------------===//
Index: clang/include/clang/Basic/BuiltinsAArch64.def
===================================================================
--- clang/include/clang/Basic/BuiltinsAArch64.def
+++ clang/include/clang/Basic/BuiltinsAArch64.def
@@ -99,6 +99,19 @@
BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
BUILTIN(__builtin_arm_ttest, "WUi", "nc")
+// SVE
+BUILTIN(__builtin_sve_svld1_s16, "q8sq16bSsC*", "n")
+BUILTIN(__builtin_sve_svld1_s32, "q4iq16bSiC*", "n")
+BUILTIN(__builtin_sve_svld1_s64, "q2Wiq16bSWiC*", "n")
+BUILTIN(__builtin_sve_svld1_s8, "q16Scq16bScC*", "n")
+BUILTIN(__builtin_sve_svld1_u16, "q8Usq16bUsC*", "n")
+BUILTIN(__builtin_sve_svld1_u32, "q4Uiq16bUiC*", "n")
+BUILTIN(__builtin_sve_svld1_u64, "q2UWiq16bUWiC*", "n")
+BUILTIN(__builtin_sve_svld1_u8, "q16Ucq16bUcC*", "n")
+BUILTIN(__builtin_sve_svld1_f64, "q2dq16bdC*", "n")
+BUILTIN(__builtin_sve_svld1_f32, "q4fq16bfC*", "n")
+BUILTIN(__builtin_sve_svld1_f16, "q8hq16bhC*", "n")
+
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -36,6 +36,7 @@
// a -> __builtin_va_list
// 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.
// E -> ext_vector, followed by the number of elements and the base type.
// X -> _Complex, followed by the base type.
// Y -> ptrdiff_t
Index: clang/include/clang/Basic/AArch64SVEACLETypes.def
===================================================================
--- clang/include/clang/Basic/AArch64SVEACLETypes.def
+++ clang/include/clang/Basic/AArch64SVEACLETypes.def
@@ -38,32 +38,32 @@
//===----------------------------------------------------------------------===//
#ifndef SVE_VECTOR_TYPE
-#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\
+#define SVE_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, IsSigned, IsFP) \
SVE_TYPE(Name, Id, SingletonId)
#endif
#ifndef SVE_PREDICATE_TYPE
-#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind)\
+#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, NumEls)\
SVE_TYPE(Name, Id, SingletonId)
#endif
//===- Vector point types -----------------------------------------------===//
-SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, SveElSInt8, 8, true, false)
-SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, SveElSInt16, 16, true, false)
-SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, SveElSInt32, 32, true, false)
-SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, SveElSInt64, 64, true, false)
+SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, true, false)
+SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, 8, 16, true, false)
+SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, 4, 32, true, false)
+SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, 2, 64, true, false)
-SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, SveElUInt8, 8, false, false)
-SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, SveElUInt16, 16, false, false)
-SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, SveElUInt32, 32, false, false)
-SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, SveElUInt64, 64, false, false)
+SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, 16, 8, false, false)
+SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, 8, 16, false, false)
+SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, 4, 32, false, false)
+SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, 2, 64, false, false)
-SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, SveElHalf, 16, true, true)
-SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, SveElFloat, 32, true, true)
-SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, SveElDouble, 64, true, true)
+SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 16, true, true)
+SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, true, true)
+SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, true, true)
-SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, SveElBool)
+SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, 16)
#undef SVE_VECTOR_TYPE
#undef SVE_PREDICATE_TYPE
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -1275,6 +1275,12 @@
/// Returns a vla type where known sizes are replaced with [*].
QualType getVariableArrayDecayedType(QualType Ty) const;
+ /// Return the unique reference to a scalable vector type of the specified
+ /// element type and scalable number of elements.
+ ///
+ /// \pre \p EltTy must be a built-in type.
+ QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;
+
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits