[clang] 3c696a2 - [AArch64][SVE] Allow lax conversion between VLATs and GNU vectors
Joe Ellis via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 23 02:47:38 PST 2020
Author: Joe Ellis
Date: 2020-11-23T10:47:17Z
New Revision: 3c696a212ba4328e4f8f92136bc4d728a6490ef7
URL: https://github.com/llvm/llvm-project/commit/3c696a212ba4328e4f8f92136bc4d728a6490ef7
DIFF: https://github.com/llvm/llvm-project/commit/3c696a212ba4328e4f8f92136bc4d728a6490ef7.diff
LOG: [AArch64][SVE] Allow lax conversion between VLATs and GNU vectors
Previously, lax conversions were only allowed between SVE vector-length
agnostic types and vector-length specific types. This meant that code
such as the following:
#include <arm_sve.h>
#define N __ARM_FEATURE_SVE_BITS
#define FIXED_ATTR __attribute__ ((vector_size (N/8)))
typedef float fixed_float32_t FIXED_ATTR;
void foo() {
fixed_float32_t fs32;
svfloat64_t s64;
fs32 = s64;
}
was not allowed.
This patch makes a minor change to areLaxCompatibleSveTypes to allow for
lax conversions to be performed between SVE vector-length agnostic types
and GNU vectors.
Differential Revision: https://reviews.llvm.org/D91696
Added:
Modified:
clang/lib/AST/ASTContext.cpp
clang/test/Sema/aarch64-sve-lax-vector-conversions.c
clang/test/Sema/attr-arm-sve-vector-bits.c
clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f54916babed7..67ee8c0956d6 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8586,10 +8586,20 @@ bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType,
const auto *VecTy = SecondType->getAs<VectorType>();
if (VecTy &&
- VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector) {
+ (VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector ||
+ VecTy->getVectorKind() == VectorType::GenericVector)) {
const LangOptions::LaxVectorConversionKind LVCKind =
getLangOpts().getLaxVectorConversions();
+ // If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion.
+ // "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly
+ // converts to VLAT and VLAT implicitly converts to GNUT."
+ // ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and
+ // predicates.
+ if (VecTy->getVectorKind() == VectorType::GenericVector &&
+ getTypeSize(SecondType) != getLangOpts().ArmSveVectorBits)
+ return false;
+
// If -flax-vector-conversions=all is specified, the types are
// certainly compatible.
if (LVCKind == LangOptions::LaxVectorConversionKind::All)
diff --git a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
index e2fe87f7dd20..1a1addcf1c1b 100644
--- a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
+++ b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
@@ -7,32 +7,61 @@
#include <arm_sve.h>
#define N __ARM_FEATURE_SVE_BITS
-#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+#define SVE_FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+#define GNU_FIXED_ATTR __attribute__((vector_size(N / 8)))
-typedef svfloat32_t fixed_float32_t FIXED_ATTR;
-typedef svint32_t fixed_int32_t FIXED_ATTR;
+typedef svfloat32_t sve_fixed_float32_t SVE_FIXED_ATTR;
+typedef svint32_t sve_fixed_int32_t SVE_FIXED_ATTR;
+typedef float gnu_fixed_float32_t GNU_FIXED_ATTR;
+typedef int gnu_fixed_int32_t GNU_FIXED_ATTR;
-void allowed_with_integer_lax_conversions() {
- fixed_int32_t fi32;
+void sve_allowed_with_integer_lax_conversions() {
+ sve_fixed_int32_t fi32;
svint64_t si64;
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
// -flax-vector-conversions={integer,all}.
fi32 = si64;
- // lax-vector-none-error at -1 {{assigning to 'fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
+ // lax-vector-none-error at -1 {{assigning to 'sve_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
si64 = fi32;
// lax-vector-none-error at -1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
}
-void allowed_with_all_lax_conversions() {
- fixed_float32_t ff32;
+void sve_allowed_with_all_lax_conversions() {
+ sve_fixed_float32_t ff32;
svfloat64_t sf64;
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
// -flax-vector-conversions=all.
ff32 = sf64;
- // lax-vector-none-error at -1 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
- // lax-vector-integer-error at -2 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-none-error at -1 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ sf64 = ff32;
+ // lax-vector-none-error at -1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
+}
+
+void gnu_allowed_with_integer_lax_conversions() {
+ gnu_fixed_int32_t fi32;
+ svint64_t si64;
+
+ // The implicit cast here should fail if -flax-vector-conversions=none, but pass if
+ // -flax-vector-conversions={integer,all}.
+ fi32 = si64;
+ // lax-vector-none-error at -1 {{assigning to 'gnu_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
+ si64 = fi32;
+ // lax-vector-none-error at -1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
+}
+
+void gnu_allowed_with_all_lax_conversions() {
+ gnu_fixed_float32_t ff32;
+ svfloat64_t sf64;
+
+ // The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
+ // -flax-vector-conversions=all.
+ ff32 = sf64;
+ // lax-vector-none-error at -1 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
sf64 = ff32;
// lax-vector-none-error at -1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
// lax-vector-integer-error at -2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
diff --git a/clang/test/Sema/attr-arm-sve-vector-bits.c b/clang/test/Sema/attr-arm-sve-vector-bits.c
index 667a49b0d76b..60f9e57357b9 100644
--- a/clang/test/Sema/attr-arm-sve-vector-bits.c
+++ b/clang/test/Sema/attr-arm-sve-vector-bits.c
@@ -272,9 +272,6 @@ TEST_CAST_COMMON(bool)
// Test the implicit conversion only applies to valid types
fixed_bool_t to_fixed_bool_t__from_svint32_t(svint32_t x) { return x; } // expected-error-re {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'fixed_bool_t' (vector of {{[0-9]+}} 'unsigned char' values)}}
-svint64_t to_svint64_t__from_gnu_int32_t(gnu_int32_t x) { return x; } // expected-error-re {{returning 'gnu_int32_t' (vector of {{[0-9]+}} 'int32_t' values) from a function with incompatible result type 'svint64_t' (aka '__SVInt64_t')}}
-gnu_int32_t from_svint64_t__to_gnu_int32_t(svint64_t x) { return x; } // expected-error-re {{returning 'svint64_t' (aka '__SVInt64_t') from a function with incompatible result type 'gnu_int32_t' (vector of {{[0-9]+}} 'int32_t' values)}}
-
// Test implicit conversion between SVE and GNU vector is invalid when
// __ARM_FEATURE_SVE_BITS != N
#if defined(__ARM_FEATURE_SVE_BITS) && __ARM_FEATURE_SVE_BITS == 512
diff --git a/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp b/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp
index e2fe87f7dd20..1a1addcf1c1b 100644
--- a/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp
+++ b/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp
@@ -7,32 +7,61 @@
#include <arm_sve.h>
#define N __ARM_FEATURE_SVE_BITS
-#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+#define SVE_FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+#define GNU_FIXED_ATTR __attribute__((vector_size(N / 8)))
-typedef svfloat32_t fixed_float32_t FIXED_ATTR;
-typedef svint32_t fixed_int32_t FIXED_ATTR;
+typedef svfloat32_t sve_fixed_float32_t SVE_FIXED_ATTR;
+typedef svint32_t sve_fixed_int32_t SVE_FIXED_ATTR;
+typedef float gnu_fixed_float32_t GNU_FIXED_ATTR;
+typedef int gnu_fixed_int32_t GNU_FIXED_ATTR;
-void allowed_with_integer_lax_conversions() {
- fixed_int32_t fi32;
+void sve_allowed_with_integer_lax_conversions() {
+ sve_fixed_int32_t fi32;
svint64_t si64;
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
// -flax-vector-conversions={integer,all}.
fi32 = si64;
- // lax-vector-none-error at -1 {{assigning to 'fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
+ // lax-vector-none-error at -1 {{assigning to 'sve_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
si64 = fi32;
// lax-vector-none-error at -1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
}
-void allowed_with_all_lax_conversions() {
- fixed_float32_t ff32;
+void sve_allowed_with_all_lax_conversions() {
+ sve_fixed_float32_t ff32;
svfloat64_t sf64;
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
// -flax-vector-conversions=all.
ff32 = sf64;
- // lax-vector-none-error at -1 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
- // lax-vector-integer-error at -2 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-none-error at -1 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ sf64 = ff32;
+ // lax-vector-none-error at -1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
+}
+
+void gnu_allowed_with_integer_lax_conversions() {
+ gnu_fixed_int32_t fi32;
+ svint64_t si64;
+
+ // The implicit cast here should fail if -flax-vector-conversions=none, but pass if
+ // -flax-vector-conversions={integer,all}.
+ fi32 = si64;
+ // lax-vector-none-error at -1 {{assigning to 'gnu_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
+ si64 = fi32;
+ // lax-vector-none-error at -1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
+}
+
+void gnu_allowed_with_all_lax_conversions() {
+ gnu_fixed_float32_t ff32;
+ svfloat64_t sf64;
+
+ // The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
+ // -flax-vector-conversions=all.
+ ff32 = sf64;
+ // lax-vector-none-error at -1 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
+ // lax-vector-integer-error at -2 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
sf64 = ff32;
// lax-vector-none-error at -1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
// lax-vector-integer-error at -2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
More information about the cfe-commits
mailing list