Skip to content

Commit 3c696a2

Browse files
author
Joe Ellis
committed
[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
1 parent cf39bdb commit 3c696a2

File tree

4 files changed

+89
-24
lines changed

4 files changed

+89
-24
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8586,10 +8586,20 @@ bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType,
85868586

85878587
const auto *VecTy = SecondType->getAs<VectorType>();
85888588
if (VecTy &&
8589-
VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector) {
8589+
(VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector ||
8590+
VecTy->getVectorKind() == VectorType::GenericVector)) {
85908591
const LangOptions::LaxVectorConversionKind LVCKind =
85918592
getLangOpts().getLaxVectorConversions();
85928593

8594+
// If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion.
8595+
// "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly
8596+
// converts to VLAT and VLAT implicitly converts to GNUT."
8597+
// ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and
8598+
// predicates.
8599+
if (VecTy->getVectorKind() == VectorType::GenericVector &&
8600+
getTypeSize(SecondType) != getLangOpts().ArmSveVectorBits)
8601+
return false;
8602+
85938603
// If -flax-vector-conversions=all is specified, the types are
85948604
// certainly compatible.
85958605
if (LVCKind == LangOptions::LaxVectorConversionKind::All)

clang/test/Sema/aarch64-sve-lax-vector-conversions.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,61 @@
77
#include <arm_sve.h>
88

99
#define N __ARM_FEATURE_SVE_BITS
10-
#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
10+
#define SVE_FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
11+
#define GNU_FIXED_ATTR __attribute__((vector_size(N / 8)))
1112

12-
typedef svfloat32_t fixed_float32_t FIXED_ATTR;
13-
typedef svint32_t fixed_int32_t FIXED_ATTR;
13+
typedef svfloat32_t sve_fixed_float32_t SVE_FIXED_ATTR;
14+
typedef svint32_t sve_fixed_int32_t SVE_FIXED_ATTR;
15+
typedef float gnu_fixed_float32_t GNU_FIXED_ATTR;
16+
typedef int gnu_fixed_int32_t GNU_FIXED_ATTR;
1417

15-
void allowed_with_integer_lax_conversions() {
16-
fixed_int32_t fi32;
18+
void sve_allowed_with_integer_lax_conversions() {
19+
sve_fixed_int32_t fi32;
1720
svint64_t si64;
1821

1922
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
2023
// -flax-vector-conversions={integer,all}.
2124
fi32 = si64;
22-
// lax-vector-none-error@-1 {{assigning to 'fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
25+
// lax-vector-none-error@-1 {{assigning to 'sve_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
2326
si64 = fi32;
2427
// lax-vector-none-error@-1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
2528
}
2629

27-
void allowed_with_all_lax_conversions() {
28-
fixed_float32_t ff32;
30+
void sve_allowed_with_all_lax_conversions() {
31+
sve_fixed_float32_t ff32;
2932
svfloat64_t sf64;
3033

3134
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
3235
// -flax-vector-conversions=all.
3336
ff32 = sf64;
34-
// lax-vector-none-error@-1 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
35-
// lax-vector-integer-error@-2 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
37+
// lax-vector-none-error@-1 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
38+
// lax-vector-integer-error@-2 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
39+
sf64 = ff32;
40+
// lax-vector-none-error@-1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
41+
// lax-vector-integer-error@-2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
42+
}
43+
44+
void gnu_allowed_with_integer_lax_conversions() {
45+
gnu_fixed_int32_t fi32;
46+
svint64_t si64;
47+
48+
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
49+
// -flax-vector-conversions={integer,all}.
50+
fi32 = si64;
51+
// lax-vector-none-error@-1 {{assigning to 'gnu_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
52+
si64 = fi32;
53+
// lax-vector-none-error@-1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
54+
}
55+
56+
void gnu_allowed_with_all_lax_conversions() {
57+
gnu_fixed_float32_t ff32;
58+
svfloat64_t sf64;
59+
60+
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
61+
// -flax-vector-conversions=all.
62+
ff32 = sf64;
63+
// lax-vector-none-error@-1 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
64+
// lax-vector-integer-error@-2 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
3665
sf64 = ff32;
3766
// lax-vector-none-error@-1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
3867
// lax-vector-integer-error@-2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}

clang/test/Sema/attr-arm-sve-vector-bits.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,6 @@ TEST_CAST_COMMON(bool)
272272
// Test the implicit conversion only applies to valid types
273273
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)}}
274274

275-
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')}}
276-
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)}}
277-
278275
// Test implicit conversion between SVE and GNU vector is invalid when
279276
// __ARM_FEATURE_SVE_BITS != N
280277
#if defined(__ARM_FEATURE_SVE_BITS) && __ARM_FEATURE_SVE_BITS == 512

clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,61 @@
77
#include <arm_sve.h>
88

99
#define N __ARM_FEATURE_SVE_BITS
10-
#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
10+
#define SVE_FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
11+
#define GNU_FIXED_ATTR __attribute__((vector_size(N / 8)))
1112

12-
typedef svfloat32_t fixed_float32_t FIXED_ATTR;
13-
typedef svint32_t fixed_int32_t FIXED_ATTR;
13+
typedef svfloat32_t sve_fixed_float32_t SVE_FIXED_ATTR;
14+
typedef svint32_t sve_fixed_int32_t SVE_FIXED_ATTR;
15+
typedef float gnu_fixed_float32_t GNU_FIXED_ATTR;
16+
typedef int gnu_fixed_int32_t GNU_FIXED_ATTR;
1417

15-
void allowed_with_integer_lax_conversions() {
16-
fixed_int32_t fi32;
18+
void sve_allowed_with_integer_lax_conversions() {
19+
sve_fixed_int32_t fi32;
1720
svint64_t si64;
1821

1922
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
2023
// -flax-vector-conversions={integer,all}.
2124
fi32 = si64;
22-
// lax-vector-none-error@-1 {{assigning to 'fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
25+
// lax-vector-none-error@-1 {{assigning to 'sve_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
2326
si64 = fi32;
2427
// lax-vector-none-error@-1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
2528
}
2629

27-
void allowed_with_all_lax_conversions() {
28-
fixed_float32_t ff32;
30+
void sve_allowed_with_all_lax_conversions() {
31+
sve_fixed_float32_t ff32;
2932
svfloat64_t sf64;
3033

3134
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
3235
// -flax-vector-conversions=all.
3336
ff32 = sf64;
34-
// lax-vector-none-error@-1 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
35-
// lax-vector-integer-error@-2 {{assigning to 'fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
37+
// lax-vector-none-error@-1 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
38+
// lax-vector-integer-error@-2 {{assigning to 'sve_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
39+
sf64 = ff32;
40+
// lax-vector-none-error@-1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
41+
// lax-vector-integer-error@-2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
42+
}
43+
44+
void gnu_allowed_with_integer_lax_conversions() {
45+
gnu_fixed_int32_t fi32;
46+
svint64_t si64;
47+
48+
// The implicit cast here should fail if -flax-vector-conversions=none, but pass if
49+
// -flax-vector-conversions={integer,all}.
50+
fi32 = si64;
51+
// lax-vector-none-error@-1 {{assigning to 'gnu_fixed_int32_t' (vector of 16 'int' values) from incompatible type}}
52+
si64 = fi32;
53+
// lax-vector-none-error@-1 {{assigning to 'svint64_t' (aka '__SVInt64_t') from incompatible type}}
54+
}
55+
56+
void gnu_allowed_with_all_lax_conversions() {
57+
gnu_fixed_float32_t ff32;
58+
svfloat64_t sf64;
59+
60+
// The implicit cast here should fail if -flax-vector-conversions={none,integer}, but pass if
61+
// -flax-vector-conversions=all.
62+
ff32 = sf64;
63+
// lax-vector-none-error@-1 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
64+
// lax-vector-integer-error@-2 {{assigning to 'gnu_fixed_float32_t' (vector of 16 'float' values) from incompatible type}}
3665
sf64 = ff32;
3766
// lax-vector-none-error@-1 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}
3867
// lax-vector-integer-error@-2 {{assigning to 'svfloat64_t' (aka '__SVFloat64_t') from incompatible type}}

0 commit comments

Comments
 (0)