Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -145,8 +145,11 @@ Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, const Twine &Name, Address *Alloca) { - Address Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, - /*ArraySize=*/nullptr, Alloca); + Address Result = CreateTempAlloca( + ConvertTypeForMem(Ty, /*ForBitField=*/false, + /*EnforceFixedLengthSVEAttribute=*/false), + Align, Name, + /*ArraySize=*/nullptr, Alloca); if (Ty->isConstantMatrixType()) { auto *ArrayTy = cast(Result.getType()->getElementType()); @@ -1699,6 +1702,13 @@ } } + // If we're loading from a fixed-length address to a scalable vector, bitcast + // the pointer, e.g. bitcast [N x i8]* %addr.ptr to * + if (Ty->isVLST()) { + llvm::Type *VecTy = ConvertType(Ty); + Addr = Builder.CreateElementBitCast(Addr, VecTy, "cast.to.scalable"); + } + // Atomic operations have to be done on integral types. LValue AtomicLValue = LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); @@ -1810,6 +1820,13 @@ } } + // If we're storing a scalable vector to a fixed-length address, bitcast the + // pointer, e.g. bitcast [N x i8]* %addr.ptr to * + if (Ty->isVLST()) { + llvm::Type *VecTy = ConvertType(Ty); + Addr = Builder.CreateElementBitCast(Addr, VecTy, "cast.to.scalable"); + } + Value = EmitToMemory(Value, Ty); LValue AtomicLValue = Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -2257,7 +2257,8 @@ /// a terminate scope encloses a try. llvm::BasicBlock *getTerminateHandler(); - llvm::Type *ConvertTypeForMem(QualType T); + llvm::Type *ConvertTypeForMem(QualType T, bool ForBitField = false, + bool EnforceFixedLengthSVEAttribute = true); llvm::Type *ConvertType(QualType T); llvm::Type *ConvertType(const TypeDecl *T) { return ConvertType(getContext().getTypeDeclType(T)); Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -193,9 +193,11 @@ return MakeAddrLValue(Address(V, Align), T, BaseInfo, TBAAInfo); } - -llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { - return CGM.getTypes().ConvertTypeForMem(T); +llvm::Type * +CodeGenFunction::ConvertTypeForMem(QualType T, bool ForBitField, + bool EnforceFixedLengthSVEAttribute) { + return CGM.getTypes().ConvertTypeForMem(T, ForBitField, + EnforceFixedLengthSVEAttribute); } llvm::Type *CodeGenFunction::ConvertType(QualType T) { Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -3977,7 +3977,12 @@ // exists. A use may still exists, however, so we still may need // to do a RAUW. assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type"); - Init = EmitNullConstant(D->getType()); + // Lower global scalable vectors to fixed-length vectors. + if (auto MemTy = + getTypes().getFixedLengthSVETypeForMemory(ASTTy.getTypePtr())) + Init = llvm::Constant::getNullValue(*MemTy); + else + Init = EmitNullConstant(D->getType()); } else { initializedGlobalDecl = GlobalDecl(D); emitter.emplace(*this); Index: clang/lib/CodeGen/CodeGenTypes.h =================================================================== --- clang/lib/CodeGen/CodeGenTypes.h +++ clang/lib/CodeGen/CodeGenTypes.h @@ -134,7 +134,10 @@ /// ConvertType in that it is used to convert to the memory representation for /// a type. For example, the scalar representation for _Bool is i1, but the /// memory representation is usually i8 or i32, depending on the target. - llvm::Type *ConvertTypeForMem(QualType T, bool ForBitField = false); + /// If \arg EnforceFixedLengthSVEAttribute is specified \arg T is converted to + /// a fixed-length type. This only applies if T->isVLST(). + llvm::Type *ConvertTypeForMem(QualType T, bool ForBitField = false, + bool EnforceFixedLengthSVEAttribute = true); /// GetFunctionType - Get the LLVM function type for \arg Info. llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info); @@ -290,6 +293,11 @@ void getExpandedTypes(QualType Ty, SmallVectorImpl::iterator &TI); + /// Returns the fixed-length type for an SVE ACLE scalable vector attributed + /// with 'arm_sve_vector_bits' that can be used in certain places where + /// size is really needed, e.g. members of structs or arrays or globals. + llvm::Optional getFixedLengthSVETypeForMemory(const Type *T); + /// IsZeroInitializable - Return whether a type can be /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. bool isZeroInitializable(QualType T); Index: clang/lib/CodeGen/CodeGenTypes.cpp =================================================================== --- clang/lib/CodeGen/CodeGenTypes.cpp +++ clang/lib/CodeGen/CodeGenTypes.cpp @@ -77,11 +77,64 @@ Ty->setName(OS.str()); } +llvm::Optional +CodeGenTypes::getFixedLengthSVETypeForMemory(const Type *T) { + if (!T->isVLST()) + return {}; + + unsigned VectorSize = Context.getBitwidthForAttributedSveType(T); + + llvm::LLVMContext &Context = getLLVMContext(); + + llvm::Type *MemEltTy = nullptr; + switch (T->castAs()->getKind()) { + default: + llvm_unreachable("unhandled type!"); + case BuiltinType::SveInt8: + case BuiltinType::SveUint8: + case BuiltinType::SveBool: + // Represent predicates in memory as i8 rather than i1 to avoid any layout + // issues. The type is bitcasted to the appropriate scalable predicate type + // when dealing with memory. + MemEltTy = llvm::Type::getInt8Ty(Context); + break; + case BuiltinType::SveInt16: + case BuiltinType::SveUint16: + MemEltTy = llvm::Type::getInt16Ty(Context); + break; + case BuiltinType::SveInt32: + case BuiltinType::SveUint32: + MemEltTy = llvm::Type::getInt32Ty(Context); + break; + case BuiltinType::SveInt64: + case BuiltinType::SveUint64: + MemEltTy = llvm::Type::getInt64Ty(Context); + break; + case BuiltinType::SveFloat16: + MemEltTy = llvm::Type::getHalfTy(Context); + break; + case BuiltinType::SveFloat32: + MemEltTy = llvm::Type::getFloatTy(Context); + break; + case BuiltinType::SveFloat64: + MemEltTy = llvm::Type::getDoubleTy(Context); + break; + case BuiltinType::SveBFloat16: + MemEltTy = llvm::Type::getBFloatTy(Context); + break; + } + + return {llvm::ArrayType::get( + MemEltTy, VectorSize / MemEltTy->getPrimitiveSizeInBits())}; +} + /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from /// ConvertType in that it is used to convert to the memory representation for /// a type. For example, the scalar representation for _Bool is i1, but the /// memory representation is usually i8 or i32, depending on the target. -llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T, bool ForBitField) { +llvm::Type * +CodeGenTypes::ConvertTypeForMem(QualType T, bool ForBitField, + bool EnforceFixedLengthSVEAttribute) { if (T->isConstantMatrixType()) { const Type *Ty = Context.getCanonicalType(T).getTypePtr(); const ConstantMatrixType *MT = cast(Ty); @@ -89,6 +142,19 @@ MT->getNumRows() * MT->getNumColumns()); } + if (T->isConstantArrayType()) { + const ConstantArrayType *A = Context.getAsConstantArrayType(T); + const QualType EltTy = A->getElementType(); + + if (auto MemTy = getFixedLengthSVETypeForMemory(EltTy.getTypePtr())) + return llvm::ArrayType::get(*MemTy, A->getSize().getZExtValue()); + } + + if (EnforceFixedLengthSVEAttribute) { + if (auto MemTy = getFixedLengthSVETypeForMemory(T.getTypePtr())) + return *MemTy; + } + llvm::Type *R = ConvertType(T); // If this is a bool type, or an ExtIntType in a bitfield representation, Index: clang/test/Sema/attr-arm-sve-vector-bits-bitcast.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-bitcast.c @@ -0,0 +1,240 @@ +// 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 +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=256 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-256 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512 + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +#define DEFINE_STRUCT(ty) \ + struct struct_##ty { \ + fixed_##ty##_t x, y[3]; \ + } struct_##ty; + +DEFINE_STRUCT(int64) +DEFINE_STRUCT(float64) +DEFINE_STRUCT(bfloat16) +DEFINE_STRUCT(bool) + +//===----------------------------------------------------------------------===// +// int64 +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @read_int64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x i64]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-256-LABEL: @read_int64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x i64]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-256-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_int64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x i64]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-512-NEXT: ret [[TMP0]] +// +svint64_t read_int64(struct struct_int64 *s) { + return s->y[0]; +} + +// CHECK-128-LABEL: @write_int64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x i64]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-128-NEXT: ret void +// +// CHECK-256-LABEL: @write_int64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x i64]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-256-NEXT: ret void +// +// CHECK-512-LABEL: @write_int64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_INT64:%.*]], %struct.struct_int64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x i64]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !2 +// CHECK-512-NEXT: ret void +// +void write_int64(struct struct_int64 *s, svint64_t x) { + s->y[0] = x; +} + +//===----------------------------------------------------------------------===// +// float64 +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @read_float64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x double]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-256-LABEL: @read_float64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x double]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-256-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_float64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x double]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-512-NEXT: ret [[TMP0]] +// +svfloat64_t read_float64(struct struct_float64 *s) { + return s->y[0]; +} + +// CHECK-128-LABEL: @write_float64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x double]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-128-NEXT: ret void +// +// CHECK-256-LABEL: @write_float64( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x double]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-256-NEXT: ret void +// +// CHECK-512-LABEL: @write_float64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_FLOAT64:%.*]], %struct.struct_float64* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x double]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !6 +// CHECK-512-NEXT: ret void +// +void write_float64(struct struct_float64 *s, svfloat64_t x) { + s->y[0] = x; +} + +//===----------------------------------------------------------------------===// +// bfloat16 +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @read_bfloat16( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x bfloat]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-256-LABEL: @read_bfloat16( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [16 x bfloat]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-256-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_bfloat16( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [32 x bfloat]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-512-NEXT: ret [[TMP0]] +// +svbfloat16_t read_bfloat16(struct struct_bfloat16 *s) { + return s->y[0]; +} + +// CHECK-128-LABEL: @write_bfloat16( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x bfloat]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-128-NEXT: ret void +// +// CHECK-256-LABEL: @write_bfloat16( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [16 x bfloat]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-256-NEXT: ret void +// +// CHECK-512-LABEL: @write_bfloat16( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BFLOAT16:%.*]], %struct.struct_bfloat16* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [32 x bfloat]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 16, !tbaa !8 +// CHECK-512-NEXT: ret void +// +void write_bfloat16(struct struct_bfloat16 *s, svbfloat16_t x) { + s->y[0] = x; +} + +//===----------------------------------------------------------------------===// +// bool +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @read_bool( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x i8]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-256-LABEL: @read_bool( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x i8]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-256-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_bool( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x i8]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-512-NEXT: ret [[TMP0]] +// +svbool_t read_bool(struct struct_bool *s) { + return s->y[0]; +} + +// CHECK-128-LABEL: @write_bool( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-128-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [2 x i8]* [[ARRAYIDX]] to * +// CHECK-128-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-128-NEXT: ret void +// +// CHECK-256-LABEL: @write_bool( +// CHECK-256-NEXT: entry: +// CHECK-256-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-256-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [4 x i8]* [[ARRAYIDX]] to * +// CHECK-256-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-256-NEXT: ret void +// +// CHECK-512-LABEL: @write_bool( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_STRUCT_BOOL:%.*]], %struct.struct_bool* [[S:%.*]], i64 0, i32 1, i64 0 +// CHECK-512-NEXT: [[CAST_TO_SCALABLE:%.*]] = bitcast [8 x i8]* [[ARRAYIDX]] to * +// CHECK-512-NEXT: store [[X:%.*]], * [[CAST_TO_SCALABLE]], align 2, !tbaa !10 +// CHECK-512-NEXT: ret void +// +void write_bool(struct struct_bool *s, svbool_t x) { + s->y[0] = x; +} Index: clang/test/Sema/attr-arm-sve-vector-bits-call.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-call.c @@ -0,0 +1,105 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=256 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=1024 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=2048 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +#define CALL_FIXED_FIXED(ty) \ + fixed_##ty##_t \ + call_##ty##_ff(svbool_t pg, fixed_##ty##_t op1, fixed_##ty##_t op2) { \ + return svsel(pg, op1, op2); \ + } + +#define CALL_FIXED_SCALABLE(ty) \ + fixed_##ty##_t \ + call_##ty##_fs(svbool_t pg, fixed_##ty##_t op1, sv##ty##_t op2) { \ + return svsel(pg, op1, op2); \ + } + +#define CALL_SCALABLE_FIXED(ty) \ + fixed_##ty##_t \ + call_##ty##_sf(svbool_t pg, sv##ty##_t op1, fixed_##ty##_t op2) { \ + return svsel(pg, op1, op2); \ + } + +CALL_FIXED_FIXED(int64); +CALL_FIXED_FIXED(float64); +CALL_FIXED_FIXED(bfloat16); +CALL_FIXED_FIXED(bool); + +CALL_FIXED_SCALABLE(int64); +CALL_FIXED_SCALABLE(float64); +CALL_FIXED_SCALABLE(bfloat16); +CALL_FIXED_SCALABLE(bool); + +CALL_SCALABLE_FIXED(int64); +CALL_SCALABLE_FIXED(float64); +CALL_SCALABLE_FIXED(bfloat16); +CALL_SCALABLE_FIXED(bool); + +// CHECK-LABEL: call_int64_ff +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2i64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_float64_ff +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2f64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bfloat16_ff +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv8bf16( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bool_ff +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv16i1( %pg, %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_int64_fs +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2i64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_float64_fs +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2f64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bfloat16_fs +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv8bf16( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bool_fs +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv16i1( %pg, %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_int64_sf +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2i64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_float64_sf +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv2i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv2f64( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bfloat16_sf +// CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv8bf16( %[[PG]], %op1, %op2) +// CHECK: ret %[[INTRINSIC]] + +// CHECK-LABEL: call_bool_sf +// CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv16i1( %pg, %op1, %op2) +// CHECK: ret %[[INTRINSIC]] Index: clang/test/Sema/attr-arm-sve-vector-bits-cast.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-cast.c @@ -0,0 +1,61 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=256 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=1024 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=2048 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +#define CAST(TYPE) \ + sv##TYPE##_t to_sv##TYPE##_t(fixed_##TYPE##_t type) { \ + return type; \ + } \ + \ + fixed_##TYPE##_t from_sv##TYPE##_t(sv##TYPE##_t type) { \ + return type; \ + } + +CAST(int64) +CAST(float64) +CAST(bfloat16) +CAST(bool) + +// CHECK-LABEL: to_svint64_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: from_svint64_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: to_svfloat64_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: from_svfloat64_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: to_svbfloat16_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: from_svbfloat16_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: to_svbool_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type + +// CHECK-LABEL: from_svbool_t +// CHECK-NEXT: entry: +// CHECK-NEXT: ret %type Index: clang/test/Sema/attr-arm-sve-vector-bits-codegen.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-codegen.c @@ -0,0 +1,26 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +fixed_bool_t global_pred; +fixed_int32_t global_vec; + +// CHECK-LABEL: @foo( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = load , * bitcast ([8 x i8]* @global_pred to *), align 2, !tbaa !2 +// CHECK-NEXT: [[TMP1:%.*]] = call @llvm.aarch64.sve.and.z.nxv16i1( [[PRED:%.*]], [[TMP0]], [[TMP0]]) +// CHECK-NEXT: [[TMP2:%.*]] = load , * bitcast ([16 x i32]* @global_vec to *), align 16, !tbaa !6 +// CHECK-NEXT: [[TMP3:%.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[TMP1]]) +// CHECK-NEXT: [[TMP4:%.*]] = call @llvm.aarch64.sve.add.nxv4i32( [[TMP3]], [[TMP2]], [[VEC:%.*]]) +// CHECK-NEXT: ret [[TMP4]] +// +fixed_int32_t foo(svbool_t pred, svint32_t vec) { + svbool_t pg = svand_z(pred, global_pred, global_pred); + return svadd_m(pg, global_vec, vec); +} Index: clang/test/Sema/attr-arm-sve-vector-bits-globals.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-globals.c @@ -0,0 +1,96 @@ +// 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 +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512 + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +fixed_int64_t global_i64; +fixed_bfloat16_t global_bf16; +fixed_bool_t global_bool; + +//===----------------------------------------------------------------------===// +// WRITES +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @write_global_i64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: store [[V:%.*]], * bitcast ([2 x i64]* @global_i64 to *), align 16, !tbaa !2 +// CHECK-128-NEXT: ret void +// +// CHECK-512-LABEL: @write_global_i64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: store [[V:%.*]], * bitcast ([8 x i64]* @global_i64 to *), align 16, !tbaa !2 +// CHECK-512-NEXT: ret void +// +void write_global_i64(svint64_t v) { global_i64 = v; } + +// CHECK-128-LABEL: @write_global_bf16( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: store [[V:%.*]], * bitcast ([8 x bfloat]* @global_bf16 to *), align 16, !tbaa !6 +// CHECK-128-NEXT: ret void +// +// CHECK-512-LABEL: @write_global_bf16( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: store [[V:%.*]], * bitcast ([32 x bfloat]* @global_bf16 to *), align 16, !tbaa !6 +// CHECK-512-NEXT: ret void +// +void write_global_bf16(svbfloat16_t v) { global_bf16 = v; } + +// CHECK-128-LABEL: @write_global_bool( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: store [[V:%.*]], * bitcast ([2 x i8]* @global_bool to *), align 2, !tbaa !8 +// CHECK-128-NEXT: ret void +// +// CHECK-512-LABEL: @write_global_bool( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: store [[V:%.*]], * bitcast ([8 x i8]* @global_bool to *), align 2, !tbaa !8 +// CHECK-512-NEXT: ret void +// +void write_global_bool(svbool_t v) { global_bool = v; } + +//===----------------------------------------------------------------------===// +// READS +//===----------------------------------------------------------------------===// + +// CHECK-128-LABEL: @read_global_i64( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * bitcast ([2 x i64]* @global_i64 to *), align 16, !tbaa !2 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_global_i64( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * bitcast ([8 x i64]* @global_i64 to *), align 16, !tbaa !2 +// CHECK-512-NEXT: ret [[TMP0]] +// +svint64_t read_global_i64() { return global_i64; } + +// CHECK-128-LABEL: @read_global_bf16( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * bitcast ([8 x bfloat]* @global_bf16 to *), align 16, !tbaa !6 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_global_bf16( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * bitcast ([32 x bfloat]* @global_bf16 to *), align 16, !tbaa !6 +// CHECK-512-NEXT: ret [[TMP0]] +// +svbfloat16_t read_global_bf16() { return global_bf16; } + +// CHECK-128-LABEL: @read_global_bool( +// CHECK-128-NEXT: entry: +// CHECK-128-NEXT: [[TMP0:%.*]] = load , * bitcast ([2 x i8]* @global_bool to *), align 2, !tbaa !8 +// CHECK-128-NEXT: ret [[TMP0]] +// +// CHECK-512-LABEL: @read_global_bool( +// CHECK-512-NEXT: entry: +// CHECK-512-NEXT: [[TMP0:%.*]] = load , * bitcast ([8 x i8]* @global_bool to *), align 2, !tbaa !8 +// CHECK-512-NEXT: ret [[TMP0]] +// +svbool_t read_global_bool() { return global_bool; } Index: clang/test/Sema/attr-arm-sve-vector-bits-types.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-arm-sve-vector-bits-types.c @@ -0,0 +1,525 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=256 -fallow-half-arguments-and-returns -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-256 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=1024 -fallow-half-arguments-and-returns -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-1024 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=2048 -fallow-half-arguments-and-returns -S -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-2048 + +#include + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N))); +typedef svint16_t fixed_int16_t __attribute__((arm_sve_vector_bits(N))); +typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svuint8_t fixed_uint8_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint16_t fixed_uint16_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint32_t fixed_uint32_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint64_t fixed_uint64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svfloat16_t fixed_float16_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat32_t fixed_float32_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); + +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +//===----------------------------------------------------------------------===// +// Structs and unions +//===----------------------------------------------------------------------===// +#define DEFINE_STRUCT(ty) \ + struct struct_##ty { \ + fixed_##ty##_t x; \ + } struct_##ty; + +#define DEFINE_UNION(ty) \ + union union_##ty { \ + fixed_##ty##_t x; \ + } union_##ty; + +DEFINE_STRUCT(int8) +DEFINE_STRUCT(int16) +DEFINE_STRUCT(int32) +DEFINE_STRUCT(int64) +DEFINE_STRUCT(uint8) +DEFINE_STRUCT(uint16) +DEFINE_STRUCT(uint32) +DEFINE_STRUCT(uint64) +DEFINE_STRUCT(float16) +DEFINE_STRUCT(float32) +DEFINE_STRUCT(float64) +DEFINE_STRUCT(bfloat16) +DEFINE_STRUCT(bool) + +DEFINE_UNION(int8) +DEFINE_UNION(int16) +DEFINE_UNION(int32) +DEFINE_UNION(int64) +DEFINE_UNION(uint8) +DEFINE_UNION(uint16) +DEFINE_UNION(uint32) +DEFINE_UNION(uint64) +DEFINE_UNION(float16) +DEFINE_UNION(float32) +DEFINE_UNION(float64) +DEFINE_UNION(bfloat16) +DEFINE_UNION(bool) + +//===----------------------------------------------------------------------===// +// Global variables +//===----------------------------------------------------------------------===// +fixed_int8_t global_i8; +fixed_int16_t global_i16; +fixed_int32_t global_i32; +fixed_int64_t global_i64; + +fixed_uint8_t global_u8; +fixed_uint16_t global_u16; +fixed_uint32_t global_u32; +fixed_uint64_t global_u64; + +fixed_float16_t global_f16; +fixed_float32_t global_f32; +fixed_float64_t global_f64; + +fixed_bfloat16_t global_bf16; + +fixed_bool_t global_bool; + +//===----------------------------------------------------------------------===// +// Global arrays +//===----------------------------------------------------------------------===// +fixed_int8_t global_arr_i8[3]; +fixed_int16_t global_arr_i16[3]; +fixed_int32_t global_arr_i32[3]; +fixed_int64_t global_arr_i64[3]; + +fixed_uint8_t global_arr_u8[3]; +fixed_uint16_t global_arr_u16[3]; +fixed_uint32_t global_arr_u32[3]; +fixed_uint64_t global_arr_u64[3]; + +fixed_float16_t global_arr_f16[3]; +fixed_float32_t global_arr_f32[3]; +fixed_float64_t global_arr_f64[3]; + +fixed_bfloat16_t global_arr_bf16[3]; + +fixed_bool_t global_arr_bool[3]; + +//===----------------------------------------------------------------------===// +// Locals +//===----------------------------------------------------------------------===// +void f() { + // Variables + fixed_int8_t local_i8; + fixed_int16_t local_i16; + fixed_int32_t local_i32; + fixed_int64_t local_i64; + fixed_uint8_t local_u8; + fixed_uint16_t local_u16; + fixed_uint32_t local_u32; + fixed_uint64_t local_u64; + fixed_float16_t local_f16; + fixed_float32_t local_f32; + fixed_float64_t local_f64; + fixed_bfloat16_t local_bf16; + fixed_bool_t local_bool; + + // Arrays + fixed_int8_t local_arr_i8[3]; + fixed_int16_t local_arr_i16[3]; + fixed_int32_t local_arr_i32[3]; + fixed_int64_t local_arr_i64[3]; + fixed_uint8_t local_arr_u8[3]; + fixed_uint16_t local_arr_u16[3]; + fixed_uint32_t local_arr_u32[3]; + fixed_uint64_t local_arr_u64[3]; + fixed_float16_t local_arr_f16[3]; + fixed_float32_t local_arr_f32[3]; + fixed_float64_t local_arr_f64[3]; + fixed_bfloat16_t local_arr_bf16[3]; + fixed_bool_t local_arr_bool[3]; +} + +//===----------------------------------------------------------------------===// +// Structs and unions +//===----------------------------------------------------------------------===// +// CHECK-128: %struct.struct_int8 = type { [16 x i8] } +// CHECK-128-NEXT: %struct.struct_int16 = type { [8 x i16] } +// CHECK-128-NEXT: %struct.struct_int32 = type { [4 x i32] } +// CHECK-128-NEXT: %struct.struct_int64 = type { [2 x i64] } +// CHECK-128-NEXT: %struct.struct_uint8 = type { [16 x i8] } +// CHECK-128-NEXT: %struct.struct_uint16 = type { [8 x i16] } +// CHECK-128-NEXT: %struct.struct_uint32 = type { [4 x i32] } +// CHECK-128-NEXT: %struct.struct_uint64 = type { [2 x i64] } +// CHECK-128-NEXT: %struct.struct_float16 = type { [8 x half] } +// CHECK-128-NEXT: %struct.struct_float32 = type { [4 x float] } +// CHECK-128-NEXT: %struct.struct_float64 = type { [2 x double] } +// CHECK-128-NEXT: %struct.struct_bfloat16 = type { [8 x bfloat] } +// CHECK-128-NEXT: %struct.struct_bool = type { [2 x i8] } + +// CHECK-256: %struct.struct_int8 = type { [32 x i8] } +// CHECK-256-NEXT: %struct.struct_int16 = type { [16 x i16] } +// CHECK-256-NEXT: %struct.struct_int32 = type { [8 x i32] } +// CHECK-256-NEXT: %struct.struct_int64 = type { [4 x i64] } +// CHECK-256-NEXT: %struct.struct_uint8 = type { [32 x i8] } +// CHECK-256-NEXT: %struct.struct_uint16 = type { [16 x i16] } +// CHECK-256-NEXT: %struct.struct_uint32 = type { [8 x i32] } +// CHECK-256-NEXT: %struct.struct_uint64 = type { [4 x i64] } +// CHECK-256-NEXT: %struct.struct_float16 = type { [16 x half] } +// CHECK-256-NEXT: %struct.struct_float32 = type { [8 x float] } +// CHECK-256-NEXT: %struct.struct_float64 = type { [4 x double] } +// CHECK-256-NEXT: %struct.struct_bfloat16 = type { [16 x bfloat] } +// CHECK-256-NEXT: %struct.struct_bool = type { [4 x i8] } + +// CHECK-512: %struct.struct_int8 = type { [64 x i8] } +// CHECK-512-NEXT: %struct.struct_int16 = type { [32 x i16] } +// CHECK-512-NEXT: %struct.struct_int32 = type { [16 x i32] } +// CHECK-512-NEXT: %struct.struct_int64 = type { [8 x i64] } +// CHECK-512-NEXT: %struct.struct_uint8 = type { [64 x i8] } +// CHECK-512-NEXT: %struct.struct_uint16 = type { [32 x i16] } +// CHECK-512-NEXT: %struct.struct_uint32 = type { [16 x i32] } +// CHECK-512-NEXT: %struct.struct_uint64 = type { [8 x i64] } +// CHECK-512-NEXT: %struct.struct_float16 = type { [32 x half] } +// CHECK-512-NEXT: %struct.struct_float32 = type { [16 x float] } +// CHECK-512-NEXT: %struct.struct_float64 = type { [8 x double] } +// CHECK-512-NEXT: %struct.struct_bfloat16 = type { [32 x bfloat] } +// CHECK-512-NEXT: %struct.struct_bool = type { [8 x i8] } + +// CHECK-1024: %struct.struct_int8 = type { [128 x i8] } +// CHECK-1024-NEXT: %struct.struct_int16 = type { [64 x i16] } +// CHECK-1024-NEXT: %struct.struct_int32 = type { [32 x i32] } +// CHECK-1024-NEXT: %struct.struct_int64 = type { [16 x i64] } +// CHECK-1024-NEXT: %struct.struct_uint8 = type { [128 x i8] } +// CHECK-1024-NEXT: %struct.struct_uint16 = type { [64 x i16] } +// CHECK-1024-NEXT: %struct.struct_uint32 = type { [32 x i32] } +// CHECK-1024-NEXT: %struct.struct_uint64 = type { [16 x i64] } +// CHECK-1024-NEXT: %struct.struct_float16 = type { [64 x half] } +// CHECK-1024-NEXT: %struct.struct_float32 = type { [32 x float] } +// CHECK-1024-NEXT: %struct.struct_float64 = type { [16 x double] } +// CHECK-1024-NEXT: %struct.struct_bfloat16 = type { [64 x bfloat] } +// CHECK-1024-NEXT: %struct.struct_bool = type { [16 x i8] } + +// CHECK-2048: %struct.struct_int8 = type { [256 x i8] } +// CHECK-2048-NEXT: %struct.struct_int16 = type { [128 x i16] } +// CHECK-2048-NEXT: %struct.struct_int32 = type { [64 x i32] } +// CHECK-2048-NEXT: %struct.struct_int64 = type { [32 x i64] } +// CHECK-2048-NEXT: %struct.struct_uint8 = type { [256 x i8] } +// CHECK-2048-NEXT: %struct.struct_uint16 = type { [128 x i16] } +// CHECK-2048-NEXT: %struct.struct_uint32 = type { [64 x i32] } +// CHECK-2048-NEXT: %struct.struct_uint64 = type { [32 x i64] } +// CHECK-2048-NEXT: %struct.struct_float16 = type { [128 x half] } +// CHECK-2048-NEXT: %struct.struct_float32 = type { [64 x float] } +// CHECK-2048-NEXT: %struct.struct_float64 = type { [32 x double] } +// CHECK-2048-NEXT: %struct.struct_bfloat16 = type { [128 x bfloat] } +// CHECK-2048-NEXT: %struct.struct_bool = type { [32 x i8] } + +// CHECK-128: %union.union_int8 = type { [16 x i8] } +// CHECK-128-NEXT: %union.union_int16 = type { [8 x i16] } +// CHECK-128-NEXT: %union.union_int32 = type { [4 x i32] } +// CHECK-128-NEXT: %union.union_int64 = type { [2 x i64] } +// CHECK-128-NEXT: %union.union_uint8 = type { [16 x i8] } +// CHECK-128-NEXT: %union.union_uint16 = type { [8 x i16] } +// CHECK-128-NEXT: %union.union_uint32 = type { [4 x i32] } +// CHECK-128-NEXT: %union.union_uint64 = type { [2 x i64] } +// CHECK-128-NEXT: %union.union_float16 = type { [8 x half] } +// CHECK-128-NEXT: %union.union_float32 = type { [4 x float] } +// CHECK-128-NEXT: %union.union_float64 = type { [2 x double] } +// CHECK-128-NEXT: %union.union_bfloat16 = type { [8 x bfloat] } +// CHECK-128-NEXT: %union.union_bool = type { [2 x i8] } + +// CHECK-256: %union.union_int8 = type { [32 x i8] } +// CHECK-256-NEXT: %union.union_int16 = type { [16 x i16] } +// CHECK-256-NEXT: %union.union_int32 = type { [8 x i32] } +// CHECK-256-NEXT: %union.union_int64 = type { [4 x i64] } +// CHECK-256-NEXT: %union.union_uint8 = type { [32 x i8] } +// CHECK-256-NEXT: %union.union_uint16 = type { [16 x i16] } +// CHECK-256-NEXT: %union.union_uint32 = type { [8 x i32] } +// CHECK-256-NEXT: %union.union_uint64 = type { [4 x i64] } +// CHECK-256-NEXT: %union.union_float16 = type { [16 x half] } +// CHECK-256-NEXT: %union.union_float32 = type { [8 x float] } +// CHECK-256-NEXT: %union.union_float64 = type { [4 x double] } +// CHECK-256-NEXT: %union.union_bfloat16 = type { [16 x bfloat] } +// CHECK-256-NEXT: %union.union_bool = type { [4 x i8] } + +// CHECK-512: %union.union_int8 = type { [64 x i8] } +// CHECK-512-NEXT: %union.union_int16 = type { [32 x i16] } +// CHECK-512-NEXT: %union.union_int32 = type { [16 x i32] } +// CHECK-512-NEXT: %union.union_int64 = type { [8 x i64] } +// CHECK-512-NEXT: %union.union_uint8 = type { [64 x i8] } +// CHECK-512-NEXT: %union.union_uint16 = type { [32 x i16] } +// CHECK-512-NEXT: %union.union_uint32 = type { [16 x i32] } +// CHECK-512-NEXT: %union.union_uint64 = type { [8 x i64] } +// CHECK-512-NEXT: %union.union_float16 = type { [32 x half] } +// CHECK-512-NEXT: %union.union_float32 = type { [16 x float] } +// CHECK-512-NEXT: %union.union_float64 = type { [8 x double] } +// CHECK-512-NEXT: %union.union_bfloat16 = type { [32 x bfloat] } +// CHECK-512-NEXT: %union.union_bool = type { [8 x i8] } + +// CHECK-1024: %union.union_int8 = type { [128 x i8] } +// CHECK-1024-NEXT: %union.union_int16 = type { [64 x i16] } +// CHECK-1024-NEXT: %union.union_int32 = type { [32 x i32] } +// CHECK-1024-NEXT: %union.union_int64 = type { [16 x i64] } +// CHECK-1024-NEXT: %union.union_uint8 = type { [128 x i8] } +// CHECK-1024-NEXT: %union.union_uint16 = type { [64 x i16] } +// CHECK-1024-NEXT: %union.union_uint32 = type { [32 x i32] } +// CHECK-1024-NEXT: %union.union_uint64 = type { [16 x i64] } +// CHECK-1024-NEXT: %union.union_float16 = type { [64 x half] } +// CHECK-1024-NEXT: %union.union_float32 = type { [32 x float] } +// CHECK-1024-NEXT: %union.union_float64 = type { [16 x double] } +// CHECK-1024-NEXT: %union.union_bfloat16 = type { [64 x bfloat] } +// CHECK-1024-NEXT: %union.union_bool = type { [16 x i8] } + +// CHECK-2048: %union.union_int8 = type { [256 x i8] } +// CHECK-2048-NEXT: %union.union_int16 = type { [128 x i16] } +// CHECK-2048-NEXT: %union.union_int32 = type { [64 x i32] } +// CHECK-2048-NEXT: %union.union_int64 = type { [32 x i64] } +// CHECK-2048-NEXT: %union.union_uint8 = type { [256 x i8] } +// CHECK-2048-NEXT: %union.union_uint16 = type { [128 x i16] } +// CHECK-2048-NEXT: %union.union_uint32 = type { [64 x i32] } +// CHECK-2048-NEXT: %union.union_uint64 = type { [32 x i64] } +// CHECK-2048-NEXT: %union.union_float16 = type { [128 x half] } +// CHECK-2048-NEXT: %union.union_float32 = type { [64 x float] } +// CHECK-2048-NEXT: %union.union_float64 = type { [32 x double] } +// CHECK-2048-NEXT: %union.union_bfloat16 = type { [128 x bfloat] } +// CHECK-2048-NEXT: %union.union_bool = type { [32 x i8] } + +//===----------------------------------------------------------------------===// +// Global variables +//===----------------------------------------------------------------------===// +// CHECK-128: @global_i8 = global [16 x i8] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_i16 = global [8 x i16] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_i32 = global [4 x i32] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_i64 = global [2 x i64] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_u8 = global [16 x i8] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_u16 = global [8 x i16] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_u32 = global [4 x i32] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_u64 = global [2 x i64] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_f16 = global [8 x half] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_f32 = global [4 x float] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_f64 = global [2 x double] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_bf16 = global [8 x bfloat] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_bool = global [2 x i8] zeroinitializer, align 2 + +// CHECK-256: @global_i8 = global [32 x i8] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_i16 = global [16 x i16] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_i32 = global [8 x i32] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_i64 = global [4 x i64] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_u8 = global [32 x i8] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_u16 = global [16 x i16] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_u32 = global [8 x i32] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_u64 = global [4 x i64] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_f16 = global [16 x half] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_f32 = global [8 x float] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_f64 = global [4 x double] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_bf16 = global [16 x bfloat] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_bool = global [4 x i8] zeroinitializer, align 2 + +// CHECK-512: @global_i8 = global [64 x i8] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_i16 = global [32 x i16] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_i32 = global [16 x i32] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_i64 = global [8 x i64] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_u8 = global [64 x i8] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_u16 = global [32 x i16] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_u32 = global [16 x i32] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_u64 = global [8 x i64] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_f16 = global [32 x half] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_f32 = global [16 x float] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_f64 = global [8 x double] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_bf16 = global [32 x bfloat] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_bool = global [8 x i8] zeroinitializer, align 2 + +// CHECK-1024: @global_i8 = global [128 x i8] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_i16 = global [64 x i16] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_i32 = global [32 x i32] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_i64 = global [16 x i64] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_u8 = global [128 x i8] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_u16 = global [64 x i16] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_u32 = global [32 x i32] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_u64 = global [16 x i64] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_f16 = global [64 x half] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_f32 = global [32 x float] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_f64 = global [16 x double] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_bf16 = global [64 x bfloat] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_bool = global [16 x i8] zeroinitializer, align 2 + +// CHECK-2048: @global_i8 = global [256 x i8] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_i16 = global [128 x i16] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_i32 = global [64 x i32] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_i64 = global [32 x i64] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_u8 = global [256 x i8] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_u16 = global [128 x i16] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_u32 = global [64 x i32] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_u64 = global [32 x i64] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_f16 = global [128 x half] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_f32 = global [64 x float] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_f64 = global [32 x double] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_bf16 = global [128 x bfloat] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_bool = global [32 x i8] zeroinitializer, align 2 + +//===----------------------------------------------------------------------===// +// Global arrays +//===----------------------------------------------------------------------===// +// CHECK-128: @global_arr_i8 = global [3 x [16 x i8]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_i16 = global [3 x [8 x i16]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_i32 = global [3 x [4 x i32]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_i64 = global [3 x [2 x i64]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_u8 = global [3 x [16 x i8]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_u16 = global [3 x [8 x i16]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_u32 = global [3 x [4 x i32]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_u64 = global [3 x [2 x i64]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_f16 = global [3 x [8 x half]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_f32 = global [3 x [4 x float]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_f64 = global [3 x [2 x double]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_bf16 = global [3 x [8 x bfloat]] zeroinitializer, align 16 +// CHECK-128-NEXT: @global_arr_bool = global [3 x [2 x i8]] zeroinitializer, align 2 + +// CHECK-256: @global_arr_i8 = global [3 x [32 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_i16 = global [3 x [16 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_i32 = global [3 x [8 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_i64 = global [3 x [4 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_u8 = global [3 x [32 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_u16 = global [3 x [16 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_u32 = global [3 x [8 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_u64 = global [3 x [4 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_f16 = global [3 x [16 x half]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_f32 = global [3 x [8 x float]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_f64 = global [3 x [4 x double]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_bf16 = global [3 x [16 x bfloat]] zeroinitializer, align 16 +// CHECK-NEXT-256: @global_arr_bool = global [3 x [4 x i8]] zeroinitializer, align 2 + +// CHECK-512: @global_arr_i8 = global [3 x [64 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_i16 = global [3 x [32 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_i32 = global [3 x [16 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_i64 = global [3 x [8 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_u8 = global [3 x [64 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_u16 = global [3 x [32 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_u32 = global [3 x [16 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_u64 = global [3 x [8 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_f16 = global [3 x [32 x half]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_f32 = global [3 x [16 x float]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_f64 = global [3 x [8 x double]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_bf16 = global [3 x [32 x bfloat]] zeroinitializer, align 16 +// CHECK-NEXT-512: @global_arr_bool = global [3 x [8 x i8]] zeroinitializer, align 2 + +// CHECK-1024: @global_arr_i8 = global [3 x [128 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_i16 = global [3 x [64 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_i32 = global [3 x [32 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_i64 = global [3 x [16 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_u8 = global [3 x [128 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_u16 = global [3 x [64 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_u32 = global [3 x [32 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_u64 = global [3 x [16 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_f16 = global [3 x [64 x half]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_f32 = global [3 x [32 x float]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_f64 = global [3 x [16 x double]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_bf16 = global [3 x [64 x bfloat]] zeroinitializer, align 16 +// CHECK-NEXT-1024: @global_arr_bool = global [3 x [16 x i8]] zeroinitializer, align 2 + +// CHECK-2048: @global_arr_i8 = global [3 x [256 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_i16 = global [3 x [128 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_i32 = global [3 x [64 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_i64 = global [3 x [32 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_u8 = global [3 x [256 x i8]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_u16 = global [3 x [128 x i16]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_u32 = global [3 x [64 x i32]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_u64 = global [3 x [32 x i64]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_f16 = global [3 x [128 x half]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_f32 = global [3 x [64 x float]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_f64 = global [3 x [32 x double]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_bf16 = global [3 x [128 x bfloat]] zeroinitializer, align 16 +// CHECK-NEXT-2048: @global_arr_bool = global [3 x [32 x i8]] zeroinitializer, align 2 + +//===----------------------------------------------------------------------===// +// Local variables +//===----------------------------------------------------------------------===// +// CHECK: %local_i8 = alloca , align 16 +// CHECK-NEXT: %local_i16 = alloca , align 16 +// CHECK-NEXT: %local_i32 = alloca , align 16 +// CHECK-NEXT: %local_i64 = alloca , align 16 +// CHECK-NEXT: %local_u8 = alloca , align 16 +// CHECK-NEXT: %local_u16 = alloca , align 16 +// CHECK-NEXT: %local_u32 = alloca , align 16 +// CHECK-NEXT: %local_u64 = alloca , align 16 +// CHECK-NEXT: %local_f16 = alloca , align 16 +// CHECK-NEXT: %local_f32 = alloca , align 16 +// CHECK-NEXT: %local_f64 = alloca , align 16 +// CHECK-NEXT: %local_bf16 = alloca , align 16 +// CHECK-NEXT: %local_bool = alloca , align 2 + +//===----------------------------------------------------------------------===// +// Local arrays +//===----------------------------------------------------------------------===// +// CHECK-128: %local_arr_i8 = alloca [3 x [16 x i8]], align 16 +// CHECK-128-NEXT: %local_arr_i16 = alloca [3 x [8 x i16]], align 16 +// CHECK-128-NEXT: %local_arr_i32 = alloca [3 x [4 x i32]], align 16 +// CHECK-128-NEXT: %local_arr_i64 = alloca [3 x [2 x i64]], align 16 +// CHECK-128-NEXT: %local_arr_u8 = alloca [3 x [16 x i8]], align 16 +// CHECK-128-NEXT: %local_arr_u16 = alloca [3 x [8 x i16]], align 16 +// CHECK-128-NEXT: %local_arr_u32 = alloca [3 x [4 x i32]], align 16 +// CHECK-128-NEXT: %local_arr_u64 = alloca [3 x [2 x i64]], align 16 +// CHECK-128-NEXT: %local_arr_f16 = alloca [3 x [8 x half]], align 16 +// CHECK-128-NEXT: %local_arr_f32 = alloca [3 x [4 x float]], align 16 +// CHECK-128-NEXT: %local_arr_f64 = alloca [3 x [2 x double]], align 16 +// CHECK-128-NEXT: %local_arr_bf16 = alloca [3 x [8 x bfloat]], align 16 +// CHECK-128-NEXT: %local_arr_bool = alloca [3 x [2 x i8]], align 2 + +// CHECK-256: %local_arr_i8 = alloca [3 x [32 x i8]], align 16 +// CHECK-256-NEXT: %local_arr_i16 = alloca [3 x [16 x i16]], align 16 +// CHECK-256-NEXT: %local_arr_i32 = alloca [3 x [8 x i32]], align 16 +// CHECK-256-NEXT: %local_arr_i64 = alloca [3 x [4 x i64]], align 16 +// CHECK-256-NEXT: %local_arr_u8 = alloca [3 x [32 x i8]], align 16 +// CHECK-256-NEXT: %local_arr_u16 = alloca [3 x [16 x i16]], align 16 +// CHECK-256-NEXT: %local_arr_u32 = alloca [3 x [8 x i32]], align 16 +// CHECK-256-NEXT: %local_arr_u64 = alloca [3 x [4 x i64]], align 16 +// CHECK-256-NEXT: %local_arr_f16 = alloca [3 x [16 x half]], align 16 +// CHECK-256-NEXT: %local_arr_f32 = alloca [3 x [8 x float]], align 16 +// CHECK-256-NEXT: %local_arr_f64 = alloca [3 x [4 x double]], align 16 +// CHECK-256-NEXT: %local_arr_bf16 = alloca [3 x [16 x bfloat]], align 16 +// CHECK-256-NEXT: %local_arr_bool = alloca [3 x [4 x i8]], align 2 + +// CHECK-512: %local_arr_i8 = alloca [3 x [64 x i8]], align 16 +// CHECK-512-NEXT: %local_arr_i16 = alloca [3 x [32 x i16]], align 16 +// CHECK-512-NEXT: %local_arr_i32 = alloca [3 x [16 x i32]], align 16 +// CHECK-512-NEXT: %local_arr_i64 = alloca [3 x [8 x i64]], align 16 +// CHECK-512-NEXT: %local_arr_u8 = alloca [3 x [64 x i8]], align 16 +// CHECK-512-NEXT: %local_arr_u16 = alloca [3 x [32 x i16]], align 16 +// CHECK-512-NEXT: %local_arr_u32 = alloca [3 x [16 x i32]], align 16 +// CHECK-512-NEXT: %local_arr_u64 = alloca [3 x [8 x i64]], align 16 +// CHECK-512-NEXT: %local_arr_f16 = alloca [3 x [32 x half]], align 16 +// CHECK-512-NEXT: %local_arr_f32 = alloca [3 x [16 x float]], align 16 +// CHECK-512-NEXT: %local_arr_f64 = alloca [3 x [8 x double]], align 16 +// CHECK-512-NEXT: %local_arr_bf16 = alloca [3 x [32 x bfloat]], align 16 +// CHECK-512-NEXT: %local_arr_bool = alloca [3 x [8 x i8]], align 2 + +// CHECK-1024: %local_arr_i8 = alloca [3 x [128 x i8]], align 16 +// CHECK-1024-NEXT: %local_arr_i16 = alloca [3 x [64 x i16]], align 16 +// CHECK-1024-NEXT: %local_arr_i32 = alloca [3 x [32 x i32]], align 16 +// CHECK-1024-NEXT: %local_arr_i64 = alloca [3 x [16 x i64]], align 16 +// CHECK-1024-NEXT: %local_arr_u8 = alloca [3 x [128 x i8]], align 16 +// CHECK-1024-NEXT: %local_arr_u16 = alloca [3 x [64 x i16]], align 16 +// CHECK-1024-NEXT: %local_arr_u32 = alloca [3 x [32 x i32]], align 16 +// CHECK-1024-NEXT: %local_arr_u64 = alloca [3 x [16 x i64]], align 16 +// CHECK-1024-NEXT: %local_arr_f16 = alloca [3 x [64 x half]], align 16 +// CHECK-1024-NEXT: %local_arr_f32 = alloca [3 x [32 x float]], align 16 +// CHECK-1024-NEXT: %local_arr_f64 = alloca [3 x [16 x double]], align 16 +// CHECK-1024-NEXT: %local_arr_bf16 = alloca [3 x [64 x bfloat]], align 16 +// CHECK-1024-NEXT: %local_arr_bool = alloca [3 x [16 x i8]], align 2 + +// CHECK-2048: %local_arr_i8 = alloca [3 x [256 x i8]], align 16 +// CHECK-2048-NEXT: %local_arr_i16 = alloca [3 x [128 x i16]], align 16 +// CHECK-2048-NEXT: %local_arr_i32 = alloca [3 x [64 x i32]], align 16 +// CHECK-2048-NEXT: %local_arr_i64 = alloca [3 x [32 x i64]], align 16 +// CHECK-2048-NEXT: %local_arr_u8 = alloca [3 x [256 x i8]], align 16 +// CHECK-2048-NEXT: %local_arr_u16 = alloca [3 x [128 x i16]], align 16 +// CHECK-2048-NEXT: %local_arr_u32 = alloca [3 x [64 x i32]], align 16 +// CHECK-2048-NEXT: %local_arr_u64 = alloca [3 x [32 x i64]], align 16 +// CHECK-2048-NEXT: %local_arr_f16 = alloca [3 x [128 x half]], align 16 +// CHECK-2048-NEXT: %local_arr_f32 = alloca [3 x [64 x float]], align 16 +// CHECK-2048-NEXT: %local_arr_f64 = alloca [3 x [32 x double]], align 16 +// CHECK-2048-NEXT: %local_arr_bf16 = alloca [3 x [128 x bfloat]], align 16 +// CHECK-2048-NEXT: %local_arr_bool = alloca [3 x [32 x i8]], align 2