diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2219,6 +2219,13 @@ bool destIsVector = DestType->isVectorType(); bool srcIsVector = SrcType->isVectorType(); if (srcIsVector || destIsVector) { + // Allow bitcasting if either the source or destination is a scalable + // vector. + if (SrcType->isSizelessBuiltinType() || DestType->isSizelessBuiltinType()) { + Kind = CK_BitCast; + return TC_Success; + } + // The non-vector type, if any, must have integral type. This is // the same rule that C vector casts use; note, however, that enum // types are not integral in C++. diff --git a/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp b/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s + +// expected-no-diagnostics + +#include + +#define N __ARM_FEATURE_SVE_BITS +#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N))) + +typedef svfloat32_t fixed_float32_t FIXED_ATTR; +typedef svfloat64_t fixed_float64_t FIXED_ATTR; +typedef svint32_t fixed_int32_t FIXED_ATTR; +typedef svint64_t fixed_int64_t FIXED_ATTR; + +// Fixed-size SVE types can be cast to scalable SVE types (regardless of lane size). +// NOTE: the list below is not exhaustive for all SVE types. + +void svint32_to_fixed_int32_t() { + svint32_t si32; + fixed_int32_t fi32; + + fi32 = (fixed_int32_t)si32; +} + +void fixed_int32_t_to_svint32() { + svint32_t si32; + fixed_int32_t fi32; + + si32 = (svint32_t)fi32; +} + +void svint64_to_fixed_int32_t() { + svint64_t si64; + fixed_int32_t fi32; + + fi32 = (fixed_int32_t)si64; +} + +void fixed_int32_t_to_svint64() { + svint64_t si64; + fixed_int32_t fi32; + + si64 = (svint64_t)fi32; +} + +void svint32_to_fixed_int64_t() { + svint32_t si32; + fixed_int64_t fi32; + + fi32 = (fixed_int64_t)si32; +} + +void fixed_int64_t_to_svint32() { + svint32_t si32; + fixed_int64_t fi32; + + si32 = (svint32_t)fi32; +} + +void svint64_to_fixed_int64_t() { + svint64_t si64; + fixed_int64_t fi32; + + fi32 = (fixed_int64_t)si64; +} + +void fixed_int64_t_to_svint64() { + svint64_t si64; + fixed_int64_t fi32; + + si64 = (svint64_t)fi32; +} diff --git a/clang/test/Sema/aarch64-sve-explicit-casts.cpp b/clang/test/Sema/aarch64-sve-explicit-casts.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Sema/aarch64-sve-explicit-casts.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s + +#include + +// SVE types cannot be C-style casted to one another. +// "To avoid any ambiguity [between the two operations], the ACLE does not allow C-style casting from one +// vector type to another." ~ACLE Section 3.4 (Vector Types) +// The functions below check that C-style casting between scalable types correctly raises an error. + +void svint32_to_svint64() { + svint32_t si32; + svint64_t si64; + + si64 = (svint64_t) si32; // expected-error-re {{C-style cast from 'svint32_t' {{.*}} is not allowed}} +} + +void svint64_to_svint32() { + svint32_t si32; + svint64_t si64; + + si32 = (svint32_t) si64; // expected-error-re {{C-style cast from 'svint64_t' {{.*}} is not allowed}} +} + +void svfloat32_to_svfloat64() { + svfloat32_t sf32; + svfloat64_t sf64; + + sf64 = (svfloat64_t) sf32; // expected-error-re {{C-style cast from 'svfloat32_t' {{.*}} is not allowed}} +} + +void svfloat64_to_svfloat32() { + svfloat32_t sf32; + svfloat64_t sf64; + + sf32 = (svfloat32_t) sf64; // expected-error-re {{C-style cast from 'svfloat64_t' {{.*}} is not allowed}} +}