diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -377,8 +377,10 @@ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); - if (Opts.ArmSveVectorBits) + if (Opts.ArmSveVectorBits) { Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.ArmSveVectorBits)); + Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS"); + } } ArrayRef AArch64TargetInfo::getTargetBuiltins() const { diff --git a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature \ +// RUN: +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall \ +// RUN: -emit-llvm -o - %s -msve-vector-bits=256 | FileCheck %s +// REQUIRES: aarch64-registered-target + +// Examples taken from section 3.7.3.3 of the SVE ACLE (Version +// 00bet6) that can be found at +// https://developer.arm.com/documentation/100987/latest + +#include + +// Page 27, item 1 +#if __ARM_FEATURE_SVE_BITS == 256 && __ARM_FEATURE_SVE_VECTOR_OPERATORS +// CHECK-LABEL: @x = local_unnamed_addr global <4 x i64> , align 16 +typedef svint64_t vec256 __attribute__((arm_sve_vector_bits(256))); +vec256 x = {0, 1, 2, 3}; +#endif + +// Page 27, item 2. We can not change the ABI of existing vector +// types, including vec_int8. That's why in the SVE ACLE, VLST is +// distinct from, but mostly interchangeable with, the corresponding +// GNUT. VLST is treated for ABI purposes like an SVE type but GNUT +// continues to be a normal GNU vector type, with base Armv8-A PCS +// rules. +typedef int8_t vec_int8 __attribute__((vector_size(32))); +#if __ARM_FEATURE_SVE_BITS == 256 && __ARM_FEATURE_SVE_VECTOR_OPERATORS +// CHECK-LABEL: define void @f2(<32 x i8>* noalias nocapture sret(<32 x i8>) align 16 %agg.result, <32 x i8>* nocapture readonly %0) +// CHECK-NEXT: entry: +// CHECK-NEXT: %x.addr = alloca <32 x i8>, align 16 +// CHECK-NEXT: %saved-call-rvalue = alloca , align 16 +// CHECK-NEXT: %x = load <32 x i8>, <32 x i8>* %0, align 16 +// CHECK-NEXT: store <32 x i8> %x, <32 x i8>* %x.addr, align 16 +// CHECK-NEXT: %1 = call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) +// CHECK-NEXT: %2 = bitcast <32 x i8>* %x.addr to * +// CHECK-NEXT: %3 = load , * %2, align 16 +// CHECK-NEXT: %4 = call @llvm.aarch64.sve.asrd.nxv16i8( %1, %3, i32 1) +// CHECK-NEXT: store %4, * %saved-call-rvalue, align 16 +// CHECK-NEXT: %castFixedSve = bitcast * %saved-call-rvalue to <32 x i8>* +// CHECK-NEXT: %5 = load <32 x i8>, <32 x i8>* %castFixedSve, align 16 +// CHECK-NEXT: store <32 x i8> %5, <32 x i8>* %agg.result, align 16 +// CHECK-NEXT: ret void + +vec_int8 f2(vec_int8 x) { return svasrd_x(svptrue_b8(), x, 1); } +#endif + +// Page 27, item 3. +typedef int8_t vec1 __attribute__((vector_size(32))); +void f3(vec1); +#if __ARM_FEATURE_SVE_BITS == 256 && __ARM_FEATURE_SVE_VECTOR_OPERATORS +typedef svint8_t vec2 __attribute__((arm_sve_vector_bits(256))); +// CHECK-LABEL: define void @g( %x.coerce) +// CHECK-NEXT: entry: +// CHECK-NEXT: %x = alloca <32 x i8>, align 16 +// CHECK-NEXT: %indirect-arg-temp = alloca <32 x i8>, align 16 +// CHECK-NEXT: %0 = bitcast <32 x i8>* %x to * +// CHECK-NEXT: store %x.coerce, * %0 +// CHECK-NEXT: %x1 = load <32 x i8>, <32 x i8>* %x, align 16 +// CHECK-NEXT: store <32 x i8> %x1, <32 x i8>* %indirect-arg-temp +// CHECK-NEXT: call void @f3(<32 x i8>* nonnull %indirect-arg-temp) +// CHECK-NEXT: ret void + +// CHECK-LABEL: declare void @f3(<32 x i8>*) +void g(vec2 x) { f3(x); } // OK +#endif diff --git a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature \ +// RUN: +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall \ +// RUN: -emit-llvm -o - %s -msve-vector-bits=256 | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature \ +// RUN: +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall \ +// RUN: -emit-llvm -o - %s -msve-vector-bits=512 | FileCheck %s --check-prefix=CHECK512 +// REQUIRES: aarch64-registered-target + +// Examples taken from section 3.7.3.3 of the SVE ACLE (Version +// 00bet6) that can be found at +// https://developer.arm.com/documentation/100987/latest + +#include + +// Page 27, item 1. +#if __ARM_FEATURE_SVE_BITS == 512 && __ARM_FEATURE_SVE_VECTOR_OPERATORS +// CHECK512-LABEL: define @_Z1f9__SVE_VLSIu11__SVInt32_tLj512EES_( %x.coerce, %y.coerce) +// CHECK512-NEXT: entry: +// CHECK512-NEXT: %x = alloca <16 x i32>, align 16 +// CHECK512-NEXT: %y = alloca <16 x i32>, align 16 +// CHECK512-NEXT: %retval.coerce = alloca , align 16 +// CHECK512-NEXT: %0 = bitcast <16 x i32>* %x to * +// CHECK512-NEXT: store %x.coerce, * %0, align 16 +// CHECK512-NEXT: %x1 = load <16 x i32>, <16 x i32>* %x, align 16 +// CHECK512-NEXT: %1 = bitcast <16 x i32>* %y to * +// CHECK512-NEXT: store %y.coerce, * %1, align 16 +// CHECK512-NEXT: %y2 = load <16 x i32>, <16 x i32>* %y, align 16 +// CHECK512-NEXT: %add = add <16 x i32> %y2, %x1 +// CHECK512-NEXT: %retval.0..sroa_cast = bitcast * %retval.coerce to <16 x i32>* +// CHECK512-NEXT: store <16 x i32> %add, <16 x i32>* %retval.0..sroa_cast, align 16 +// CHECK512-NEXT: %2 = load , * %retval.coerce, align 16 +// CHECK512-NEXT: ret %2 +typedef svint32_t vec __attribute__((arm_sve_vector_bits(512))); +auto f(vec x, vec y) { return x + y; } // Returns a vec. +#endif + +// Page 27, item 3. +typedef int8_t vec1 __attribute__((vector_size(32))); +void f(vec1); +#if __ARM_FEATURE_SVE_BITS == 256 && __ARM_FEATURE_SVE_VECTOR_OPERATORS +typedef svint8_t vec2 __attribute__((arm_sve_vector_bits(256))); +// CHECK-LABEL: define void @_Z1g9__SVE_VLSIu10__SVInt8_tLj256EE( %x.coerce) +// CHECK-NEXT: entry: +// CHECK-NEXT: %x = alloca <32 x i8>, align 16 +// CHECK-NEXT: %indirect-arg-temp = alloca <32 x i8>, align 16 +// CHECK-NEXT: %0 = bitcast <32 x i8>* %x to * +// CHECK-NEXT: store %x.coerce, * %0, align 16 +// CHECK-NEXT: %x1 = load <32 x i8>, <32 x i8>* %x, align 16 +// CHECK-NEXT: store <32 x i8> %x1, <32 x i8>* %indirect-arg-temp, align 16 +// CHECK-NEXT: call void @_Z1fDv32_a(<32 x i8>* nonnull %indirect-arg-temp) +// CHECK-NEXT: ret void +void g(vec2 x) { f(x); } // OK +#endif diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -440,14 +440,10 @@ // CHECK-BFLOAT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1 // ================== Check sve-vector-bits flag. -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=128 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-128 %s -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=256 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-256 %s -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=512 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-512 %s -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=1024 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-1024 %s -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s -// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s -// CHECK-SVE-VECTOR-BITS-128: __ARM_FEATURE_SVE_BITS 128 -// CHECK-SVE-VECTOR-BITS-256: __ARM_FEATURE_SVE_BITS 256 -// CHECK-SVE-VECTOR-BITS-512: __ARM_FEATURE_SVE_BITS 512 -// CHECK-SVE-VECTOR-BITS-1024: __ARM_FEATURE_SVE_BITS 1024 -// CHECK-SVE-VECTOR-BITS-2048: __ARM_FEATURE_SVE_BITS 2048 +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=128 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS -D#VBITS=128 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=256 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS -D#VBITS=256 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=512 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS -D#VBITS=512 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=1024 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS -D#VBITS=1024 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS -D#VBITS=2048 %s +// CHECK-SVE-VECTOR-BITS: __ARM_FEATURE_SVE_BITS [[#VBITS:]] +// CHECK-SVE-VECTOR-BITS: __ARM_FEATURE_SVE_VECTOR_OPERATORS 1