@@ -25173,6 +25173,10 @@ aarch64_comp_type_attributes (const_tree type1, const_tree type2)
return 0;
if (!check_attr ("Advanced SIMD type"))
return 0;
+ if (!check_attr ("SVE type"))
+ return 0;
+ if (!check_attr ("SVE sizeless type"))
+ return 0;
return 1;
}
new file mode 100644
@@ -0,0 +1,103 @@
+/* { dg-options "-msve-vector-bits=256" } */
+
+#include <arm_sve.h>
+
+typedef svint32_t vls_svint32_t __attribute__((arm_sve_vector_bits(256)));
+typedef svuint32_t vls_svuint32_t __attribute__((arm_sve_vector_bits(256)));
+
+typedef int32_t gnu_svint32_t __attribute__((vector_size(32)));
+typedef uint32_t gnu_svuint32_t __attribute__((vector_size(32)));
+
+#define X_gnu_svint32_t 1
+#define X_gnu_svuint32_t 2
+#define X_vls_svint32_t 3
+#define X_vls_svuint32_t 4
+
+#define CHECK(T) T: X_##T
+
+#define CHECK_TYPE(EXPR, TYPE) \
+ do { \
+ int x[_Generic (EXPR, \
+ CHECK (gnu_svint32_t), \
+ CHECK (gnu_svuint32_t), \
+ CHECK (vls_svint32_t), \
+ CHECK (vls_svuint32_t), \
+ default : 0) == X_##TYPE ? 1 : -1]; \
+ } while (0)
+
+void
+f (gnu_svint32_t sg, gnu_svuint32_t ug, vls_svint32_t sn, vls_svuint32_t un, int c)
+{
+ CHECK_TYPE (sg, gnu_svint32_t);
+ CHECK_TYPE (ug, gnu_svuint32_t);
+ CHECK_TYPE (sn, vls_svint32_t);
+ CHECK_TYPE (un, vls_svuint32_t);
+
+ CHECK_TYPE (sg + 1, gnu_svint32_t);
+ CHECK_TYPE (ug + 1, gnu_svuint32_t);
+ CHECK_TYPE (sn + 1, vls_svint32_t);
+ CHECK_TYPE (un + 1, vls_svuint32_t);
+
+ CHECK_TYPE (1 + sg, gnu_svint32_t);
+ CHECK_TYPE (1 + ug, gnu_svuint32_t);
+ CHECK_TYPE (1 + sn, vls_svint32_t);
+ CHECK_TYPE (1 + un, vls_svuint32_t);
+
+ CHECK_TYPE (sg + sg, gnu_svint32_t);
+ CHECK_TYPE (ug + ug, gnu_svuint32_t);
+ CHECK_TYPE (sn + sn, vls_svint32_t);
+ CHECK_TYPE (un + un, vls_svuint32_t);
+
+ /* Traditional behavior for mixed signs is to pick the signedness of the
+ first operand. We don't have any Arm-specific reason for preferring that
+ behavior. */
+ CHECK_TYPE (sg + ug, gnu_svint32_t);
+ CHECK_TYPE (ug + sg, gnu_svuint32_t);
+ CHECK_TYPE (sn + un, vls_svint32_t);
+ CHECK_TYPE (un + sn, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg + sg : sg, gnu_svint32_t);
+ CHECK_TYPE (c ? ug + ug : ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn + sn : sn, vls_svint32_t);
+ CHECK_TYPE (c ? un + un : un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg + 1 : sg, gnu_svint32_t);
+ CHECK_TYPE (c ? ug + 1 : ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn + 1 : sn, vls_svint32_t);
+ CHECK_TYPE (c ? un + 1 : un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg, gnu_svint32_t);
+ CHECK_TYPE (c ? 1 + ug : ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? 1 + sn : sn, vls_svint32_t);
+ CHECK_TYPE (c ? 1 + un : un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg : sg + sg, gnu_svint32_t);
+ CHECK_TYPE (c ? ug : ug + ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn : sn + sn, vls_svint32_t);
+ CHECK_TYPE (c ? un : un + un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg : sg + 1, gnu_svint32_t);
+ CHECK_TYPE (c ? ug : ug + 1, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn : sn + 1, vls_svint32_t);
+ CHECK_TYPE (c ? un : un + 1, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg : 1 + sg, gnu_svint32_t);
+ CHECK_TYPE (c ? ug : 1 + ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn : 1 + sn, vls_svint32_t);
+ CHECK_TYPE (c ? un : 1 + un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + sg, gnu_svint32_t);
+ CHECK_TYPE (c ? ug + ug : ug + ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn + sn : sn + sn, vls_svint32_t);
+ CHECK_TYPE (c ? un + un : un + un, vls_svuint32_t);
+
+ CHECK_TYPE (c ? sg + sg : sg + 1, gnu_svint32_t);
+ CHECK_TYPE (c ? ug + ug : ug + 1, gnu_svuint32_t);
+ CHECK_TYPE (c ? sn + sn : sn + 1, vls_svint32_t);
+ CHECK_TYPE (c ? un + un : un + 1, vls_svuint32_t);
+
+ CHECK_TYPE (c ? 1 + sg : sg + sg, gnu_svint32_t);
+ CHECK_TYPE (c ? 1 + ug : ug + ug, gnu_svuint32_t);
+ CHECK_TYPE (c ? 1 + sn : sn + sn, vls_svint32_t);
+ CHECK_TYPE (c ? 1 + un : un + un, vls_svuint32_t);
+}
@@ -106,8 +106,8 @@ statements (int n)
/* Pointer assignment. */
- gnu_sc_ptr = sve_sc_ptr;
- sve_sc_ptr = gnu_sc_ptr;
+ gnu_sc_ptr = sve_sc_ptr; /* { dg-warning {incompatible pointer type} } */
+ sve_sc_ptr = gnu_sc_ptr; /* { dg-warning {incompatible pointer type} } */
/* Pointer arithmetic. */
@@ -120,8 +120,8 @@ statements (int n)
sve_sc_ptr -= 0; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
sve_sc_ptr -= 1; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
sve_sc_ptr - sve_sc_ptr; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
- gnu_sc_ptr - sve_sc_ptr; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
- sve_sc_ptr - gnu_sc_ptr; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
+ gnu_sc_ptr - sve_sc_ptr; /* { dg-error {invalid operands to binary -} } */
+ sve_sc_ptr - gnu_sc_ptr; /* { dg-error {invalid operands to binary -} } */
sve_sc1 = sve_sc_ptr[0]; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
sve_sc1 = sve_sc_ptr[1]; /* { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } */
@@ -133,18 +133,18 @@ statements (int n)
sve_sc_ptr <= &sve_sc1;
sve_sc_ptr > &sve_sc1;
sve_sc_ptr >= &sve_sc1;
- gnu_sc_ptr == sve_sc_ptr;
- gnu_sc_ptr != sve_sc_ptr;
- gnu_sc_ptr < sve_sc_ptr;
- gnu_sc_ptr <= sve_sc_ptr;
- gnu_sc_ptr > sve_sc_ptr;
- gnu_sc_ptr >= sve_sc_ptr;
- sve_sc_ptr == gnu_sc_ptr;
- sve_sc_ptr != gnu_sc_ptr;
- sve_sc_ptr < gnu_sc_ptr;
- sve_sc_ptr <= gnu_sc_ptr;
- sve_sc_ptr > gnu_sc_ptr;
- sve_sc_ptr >= gnu_sc_ptr;
+ gnu_sc_ptr == sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ gnu_sc_ptr != sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ gnu_sc_ptr < sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ gnu_sc_ptr <= sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ gnu_sc_ptr > sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ gnu_sc_ptr >= sve_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr == gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr != gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr < gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr <= gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr > gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
+ sve_sc_ptr >= gnu_sc_ptr; /* { dg-warning {comparison of distinct pointer types} } */
/* Conditional expressions. */
@@ -154,8 +154,8 @@ statements (int n)
0 ? 0 : sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
0 ?: sve_sc1; /* { dg-error {type mismatch in conditional expression} } */
0 ? sve_sc_ptr : sve_sc_ptr;
- 0 ? sve_sc_ptr : gnu_sc_ptr;
- 0 ? gnu_sc_ptr : sve_sc_ptr;
+ 0 ? sve_sc_ptr : gnu_sc_ptr; /* { dg-warning {pointer type mismatch} } */
+ 0 ? gnu_sc_ptr : sve_sc_ptr; /* { dg-warning {pointer type mismatch} } */
/* Generic associations. */
@@ -85,19 +85,19 @@ f (int c)
(void) (c ? fs8 : ss8); // { dg-error {type mismatch|different types} }
(void) (c ? fs8 : fs8);
- (void) (c ? fs8 : gs8); // { dg-error {type mismatch|different types} "" { xfail c++ } }
+ (void) (c ? fs8 : gs8); // { dg-error {type mismatch|different types} }
(void) (c ? gs8 : ss8); // { dg-error {type mismatch|different types} }
- (void) (c ? gs8 : fs8); // { dg-error {type mismatch|different types} "" { xfail c++ } }
+ (void) (c ? gs8 : fs8); // { dg-error {type mismatch|different types} }
(void) (c ? gs8 : gs8);
sb = fb;
fb = sb;
(void) (c ? sb : sb);
- (void) (c ? sb : fb); // { dg-error {type mismatch|different types} "" { xfail *-*-* } }
+ (void) (c ? sb : fb); // { dg-error {type mismatch|different types} "" { xfail c } }
- (void) (c ? fb : sb); // { dg-error {type mismatch|different types} "" { xfail *-*-* } }
+ (void) (c ? fb : sb); // { dg-error {type mismatch|different types} "" { xfail c } }
(void) (c ? fb : fb);
}
@@ -123,24 +123,22 @@ g (int c)
void *select __attribute__((unused));
diff = ss8 - ss8; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} }
- diff = ss8 - fs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" { xfail c } }
- // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} "bogus" { target c } .-1 }
- diff = ss8 - gs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" { xfail c } }
- // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} "bogus" { target c } .-1 }
+ diff = ss8 - fs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
+ diff = ss8 - gs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
- diff = fs8 - ss8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" { xfail c } }
- // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} "bogus" { target c } .-1 }
+ diff = fs8 - ss8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
diff = fs8 - fs8;
- diff = fs8 - gs8;
+ diff = fs8 - gs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
- diff = gs8 - ss8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" { xfail c } }
- // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} "bogus" { target c } .-1 }
- diff = gs8 - fs8;
+ diff = gs8 - ss8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
+ diff = gs8 - fs8; // { dg-error {invalid operands [^\n]* binary[^\n]*\-} "" }
diff = gs8 - gs8;
- fs8 = ss8; // { dg-error {invalid conversion} "" { xfail c } }
+ fs8 = ss8; // { dg-error {invalid conversion} "" { target c++ } }
+ // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
fs8 = fs8;
- fs8 = gs8;
+ fs8 = gs8; // { dg-error {invalid conversion} "" { target c++ } }
+ // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
fs8 = su8; // { dg-error {cannot convert} "c++" { target c++ } }
// { dg-warning {incompatible pointer type} "c" { target c } .-1 }
@@ -150,36 +148,48 @@ g (int c)
// { dg-warning {incompatible pointer type} "c" { target c } .-1 }
fs8 = ss16; // { dg-error {cannot convert} "c++" { target c++ } }
- // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+ // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
fs8 = fs16; // { dg-error {cannot convert} "c++" { target c++ } }
- // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+ // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
fs8 = gs16; // { dg-error {cannot convert} "c++" { target c++ } }
- // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
+ // { dg-warning {incompatible pointer type} "c" { target c } .-1 }
select = c ? ss8 : ss8;
- select = c ? ss8 : fs8; // { dg-error {distinct pointer types} "" { xfail c } }
- select = c ? ss8 : gs8; // { dg-error {distinct pointer types} "" { xfail c } }
+ select = c ? ss8 : fs8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+ select = c ? ss8 : gs8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
- select = c ? fs8 : ss8; // { dg-error {distinct pointer types} "" { xfail c } }
+ select = c ? fs8 : ss8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
select = c ? fs8 : fs8;
- select = c ? fs8 : gs8; // { dg-error {distinct pointer types} "" { xfail *-*-* } }
+ select = c ? fs8 : gs8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
- select = c ? gs8 : ss8; // { dg-error {distinct pointer types} "" { xfail c } }
- select = c ? gs8 : fs8; // { dg-error {distinct pointer types} "" { xfail *-*-* } }
+ select = c ? gs8 : ss8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
+ select = c ? gs8 : fs8; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c } .-1 }
select = c ? gs8 : gs8;
diff = sb - sb; // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} }
- diff = sb - fb; // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} }
+ diff = sb - fb; // { dg-error {invalid operands} "" { target c++ } }
+ // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} "c" { target c } .-1 }
- diff = fb - sb; // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} }
+ diff = fb - sb; // { dg-error {invalid operands} "" { target c++ } }
+ // { dg-error {arithmetic on pointer to SVE type 'svbool_t'} "c" { target c } .-1 }
diff = fb - fb;
- sb = fb;
- fb = sb;
+ sb = fb; // { dg-error {invalid conversion} "" { target c++ } }
+ // { dg-warning {incompatible pointer type} "c" { target c xfail c } .-1 }
+ fb = sb; // { dg-error {invalid conversion} "" { target c++ } }
+ // { dg-warning {incompatible pointer type} "c" { target c xfail c } .-1 }
select = c ? sb : sb;
- select = c ? sb : fb; // { dg-error {type mismatch|different types} "" { xfail *-*-* } }
+ select = c ? sb : fb; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c xfail c } .-1 }
- select = c ? fb : sb; // { dg-error {type mismatch|different types} "" { xfail *-*-* } }
+ select = c ? fb : sb; // { dg-error {distinct pointer types} "" { target c++ } }
+ // { dg-warning {pointer type mismatch} "c" { target c xfail c } .-1 }
select = c ? fb : fb;
}