[AArch64][SVE] Allow C-style casts between fixed-size and scalable vectors
This patch allows C-style casting between fixed-size and scalable vectors. This kind of cast was previously blocked by the compiler, but it should be allowed. Differential Revision: https://reviews.llvm.org/D91262
This commit is contained in:
parent
a1de391dae
commit
1e2da3839c
|
@ -11501,6 +11501,8 @@ public:
|
|||
QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
SourceLocation Loc, bool IsCompAssign);
|
||||
|
||||
bool isValidSveBitcast(QualType srcType, QualType destType);
|
||||
|
||||
bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType);
|
||||
bool isLaxVectorConversion(QualType srcType, QualType destType);
|
||||
|
||||
|
|
|
@ -2219,6 +2219,12 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
|
|||
bool destIsVector = DestType->isVectorType();
|
||||
bool srcIsVector = SrcType->isVectorType();
|
||||
if (srcIsVector || destIsVector) {
|
||||
// Allow bitcasting between SVE VLATs and VLSTs, and vice-versa.
|
||||
if (Self.isValidSveBitcast(SrcType, DestType)) {
|
||||
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++.
|
||||
|
@ -2752,6 +2758,13 @@ void CastOperation::CheckCStyleCast() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Allow bitcasting between compatible SVE vector types.
|
||||
if ((SrcType->isVectorType() || DestType->isVectorType()) &&
|
||||
Self.isValidSveBitcast(SrcType, DestType)) {
|
||||
Kind = CK_BitCast;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DestType->isScalarType() && !DestType->isVectorType()) {
|
||||
const RecordType *DestRecordTy = DestType->getAs<RecordType>();
|
||||
|
||||
|
|
|
@ -7197,6 +7197,28 @@ static bool breakDownVectorType(QualType type, uint64_t &len,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Are the two types SVE-bitcast-compatible types? I.e. is bitcasting from the
|
||||
/// first SVE type (e.g. an SVE VLAT) to the second type (e.g. an SVE VLST)
|
||||
/// allowed?
|
||||
///
|
||||
/// This will also return false if the two given types do not make sense from
|
||||
/// the perspective of SVE bitcasts.
|
||||
bool Sema::isValidSveBitcast(QualType srcTy, QualType destTy) {
|
||||
assert(srcTy->isVectorType() || destTy->isVectorType());
|
||||
|
||||
auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) {
|
||||
if (!FirstType->isSizelessBuiltinType())
|
||||
return false;
|
||||
|
||||
const auto *VecTy = SecondType->getAs<VectorType>();
|
||||
return VecTy &&
|
||||
VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector;
|
||||
};
|
||||
|
||||
return ValidScalableConversion(srcTy, destTy) ||
|
||||
ValidScalableConversion(destTy, srcTy);
|
||||
}
|
||||
|
||||
/// Are the two types lax-compatible vector types? That is, given
|
||||
/// that one of them is a vector, do they have equal storage sizes,
|
||||
/// where the storage size is the number of elements times the element
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// 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
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=1024 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=2048 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
#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;
|
||||
|
||||
// SVE VLSTs can be cast to SVE VLATs, regardless of lane size.
|
||||
// NOTE: the list below is NOT exhaustive for all SVE types.
|
||||
|
||||
#define CAST(from, to) \
|
||||
void from##_to_##to(from a, to b) { \
|
||||
b = (to) a; \
|
||||
}
|
||||
|
||||
#define TESTCASE(ty1, ty2) \
|
||||
CAST(ty1, ty2) \
|
||||
CAST(ty2, ty1)
|
||||
|
||||
TESTCASE(fixed_float32_t, svfloat32_t)
|
||||
TESTCASE(fixed_float32_t, svfloat64_t)
|
||||
TESTCASE(fixed_float32_t, svint32_t)
|
||||
TESTCASE(fixed_float32_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_float64_t, svfloat32_t)
|
||||
TESTCASE(fixed_float64_t, svfloat64_t)
|
||||
TESTCASE(fixed_float64_t, svint32_t)
|
||||
TESTCASE(fixed_float64_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_int32_t, svfloat32_t)
|
||||
TESTCASE(fixed_int32_t, svfloat64_t)
|
||||
TESTCASE(fixed_int32_t, svint32_t)
|
||||
TESTCASE(fixed_int32_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_int64_t, svfloat32_t)
|
||||
TESTCASE(fixed_int64_t, svfloat64_t)
|
||||
TESTCASE(fixed_int64_t, svint32_t)
|
||||
TESTCASE(fixed_int64_t, svint64_t)
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// 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
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=1024 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=2048 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
#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;
|
||||
|
||||
// SVE VLSTs can be cast to SVE VLATs, regardless of lane size.
|
||||
// NOTE: the list below is NOT exhaustive for all SVE types.
|
||||
|
||||
#define CAST(from, to) \
|
||||
void from##_to_##to(from a, to b) { \
|
||||
b = (to) a; \
|
||||
}
|
||||
|
||||
#define TESTCASE(ty1, ty2) \
|
||||
CAST(ty1, ty2) \
|
||||
CAST(ty2, ty1)
|
||||
|
||||
TESTCASE(fixed_float32_t, svfloat32_t)
|
||||
TESTCASE(fixed_float32_t, svfloat64_t)
|
||||
TESTCASE(fixed_float32_t, svint32_t)
|
||||
TESTCASE(fixed_float32_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_float64_t, svfloat32_t)
|
||||
TESTCASE(fixed_float64_t, svfloat64_t)
|
||||
TESTCASE(fixed_float64_t, svint32_t)
|
||||
TESTCASE(fixed_float64_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_int32_t, svfloat32_t)
|
||||
TESTCASE(fixed_int32_t, svfloat64_t)
|
||||
TESTCASE(fixed_int32_t, svint32_t)
|
||||
TESTCASE(fixed_int32_t, svint64_t)
|
||||
|
||||
TESTCASE(fixed_int64_t, svfloat32_t)
|
||||
TESTCASE(fixed_int64_t, svfloat64_t)
|
||||
TESTCASE(fixed_int64_t, svint32_t)
|
||||
TESTCASE(fixed_int64_t, svint64_t)
|
Loading…
Reference in New Issue