+2020-05-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/95105
+ * config/aarch64/aarch64-sve-builtins.cc
+ (handle_arm_sve_vector_bits_attribute): Create a copy of the
+ original type's TYPE_MAIN_VARIANT, then reapply all the differences
+ between the original type and its main variant.
+
2020-05-14 Richard Biener <rguenther@suse.de>
PR middle-end/95118
svbool_t and its fixed-length variants. Using a type variant
avoids that but means that we treat some ambiguous combinations
as valid. */
+ tree new_type;
+ tree base_type = TYPE_MAIN_VARIANT (type);
if (lang_GNU_C () && VECTOR_BOOLEAN_TYPE_P (type))
- type = build_variant_type_copy (type);
+ new_type = build_variant_type_copy (base_type);
else
- type = build_distinct_type_copy (type);
+ new_type = build_distinct_type_copy (base_type);
+
+ /* Allow the GNU vector extensions to be applied to vectors.
+ The extensions aren't yet defined for packed predicates,
+ so continue to treat them as abstract entities for now. */
+ if (!VECTOR_BOOLEAN_TYPE_P (new_type))
+ TYPE_INDIVISIBLE_P (new_type) = 0;
/* The new type is a normal sized type; it doesn't have the same
restrictions as sizeless types. */
- TYPE_ATTRIBUTES (type)
+ TYPE_ATTRIBUTES (new_type)
= remove_attribute ("SVE sizeless type",
- copy_list (TYPE_ATTRIBUTES (type)));
+ copy_list (TYPE_ATTRIBUTES (new_type)));
- /* Allow the GNU vector extensions to be applied to vectors.
- The extensions aren't yet defined for packed predicates,
- so continue to treat them as abstract entities for now. */
- if (!VECTOR_BOOLEAN_TYPE_P (type))
- TYPE_INDIVISIBLE_P (type) = 0;
+ /* Apply the relevant attributes, qualifiers and alignment of TYPE,
+ if they differ from the original (sizeless) BASE_TYPE. */
+ if (TYPE_ATTRIBUTES (base_type) != TYPE_ATTRIBUTES (type)
+ || TYPE_QUALS (base_type) != TYPE_QUALS (type))
+ {
+ tree attrs = remove_attribute ("SVE sizeless type",
+ copy_list (TYPE_ATTRIBUTES (type)));
+ new_type = build_type_attribute_qual_variant (new_type, attrs,
+ TYPE_QUALS (type));
+ }
+ if (TYPE_ALIGN (base_type) != TYPE_ALIGN (type))
+ new_type = build_aligned_type (new_type, TYPE_ALIGN (type));
- *node = type;
+ *node = new_type;
return NULL_TREE;
}
+2020-05-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/95105
+ * gcc.target/aarch64/sve/acle/general/attributes_8.c: New test.
+ * g++.target/aarch64/sve/acle/general-c++/attributes_1.C: Likewise.
+
2020-05-14 Richard Biener <rguenther@suse.de>
PR testsuite/94703
--- /dev/null
+/* { dg-options "-msve-vector-bits=256 -W -Wall" } */
+
+#include <arm_sve.h>
+
+#define N __ARM_FEATURE_SVE_BITS
+#define FIXED_ATTR __attribute__ ((arm_sve_vector_bits (N)))
+
+template<typename T> struct foo { T var; };
+
+typedef svint8_t var1;
+typedef __SVInt8_t var2;
+
+typedef const var1 const_var1;
+typedef const var2 const_var2;
+
+typedef svint8_t fixed1 FIXED_ATTR;
+typedef svint8_t fixed1_alias FIXED_ATTR;
+typedef __SVInt8_t fixed2 FIXED_ATTR;
+
+typedef const_var1 const_fixed1 FIXED_ATTR;
+typedef const var1 const_fixed1_alias FIXED_ATTR;
+typedef const_var2 const_fixed2 FIXED_ATTR;
+
+extern fixed1 extern1;
+extern fixed1_alias extern1_alias;
+extern fixed2 extern2;
+
+extern foo<fixed1> extern1_foo;
+extern foo<fixed1_alias> extern1_alias_foo;
+extern foo<fixed2> extern2_foo;
+
+extern const_fixed1 const_extern1;
+extern const_fixed1_alias const_extern1_alias;
+extern const_fixed2 const_extern2;
+
+extern foo<const_fixed1> const_extern1_foo;
+extern foo<const_fixed1_alias> const_extern1_alias_foo;
+extern foo<const_fixed2> const_extern2_foo;
+
+fixed1 &ref1a = extern1;
+fixed1_alias &ref1b = extern1;
+fixed2 &ref1c = extern1;
+
+fixed1 &ref2a = extern1_alias;
+fixed1_alias &ref2b = extern1_alias;
+fixed2 &ref2c = extern1_alias;
+
+fixed1 &ref3a = extern2;
+fixed1_alias &ref3b = extern2;
+fixed2 &ref3c = extern2;
+
+fixed1 &ref1a_foo = extern1_foo.var;
+fixed1_alias &ref1b_foo = extern1_foo.var;
+fixed2 &ref1c_foo = extern1_foo.var;
+
+fixed1 &ref2a_foo = extern1_alias_foo.var;
+fixed1_alias &ref2b_foo = extern1_alias_foo.var;
+fixed2 &ref2c_foo = extern1_alias_foo.var;
+
+fixed1 &ref3a_foo = extern2_foo.var;
+fixed1_alias &ref3b_foo = extern2_foo.var;
+fixed2 &ref3c_foo = extern2_foo.var;
+
+fixed1 &ref4a = const_extern1; // { dg-error {discards qualifiers} }
+fixed1_alias &ref4b = const_extern1; // { dg-error {discards qualifiers} }
+fixed2 &ref4c = const_extern1; // { dg-error {discards qualifiers} }
+
+fixed1 &ref4a_foo = const_extern1_foo.var; // { dg-error {discards qualifiers} }
+fixed1_alias &ref4b_foo = const_extern1_foo.var; // { dg-error {discards qualifiers} }
+fixed2 &ref4c_foo = const_extern1_foo.var; // { dg-error {discards qualifiers} }
+
+const fixed1 &ref5a = const_extern2;
+const fixed1_alias &ref5b = const_extern2;
+const fixed2 &ref5c = const_extern2;
+
+const_fixed1 &const_ref1a = extern1;
+const_fixed1_alias &const_ref1b = extern1;
+const_fixed2 &const_ref1c = extern1;
+
+const_fixed1 &const_ref2a = extern1_alias;
+const_fixed1_alias &const_ref2b = extern1_alias;
+const_fixed2 &const_ref2c = extern1_alias;
+
+const_fixed1 &const_ref3a = extern2;
+const_fixed1_alias &const_ref3b = extern2;
+const_fixed2 &const_ref3c = extern2;
+
+const_fixed1 &const_ref1a_foo = extern1_foo.var;
+const_fixed1_alias &const_ref1b_foo = extern1_foo.var;
+const_fixed2 &const_ref1c_foo = extern1_foo.var;
+
+const_fixed1 &const_ref2a_foo = extern1_alias_foo.var;
+const_fixed1_alias &const_ref2b_foo = extern1_alias_foo.var;
+const_fixed2 &const_ref2c_foo = extern1_alias_foo.var;
+
+const_fixed1 &const_ref3a_foo = extern2_foo.var;
+const_fixed1_alias &const_ref3b_foo = extern2_foo.var;
+const_fixed2 &const_ref3c_foo = extern2_foo.var;
+
+const_fixed1 &const_ref4a = const_extern1;
+const_fixed1_alias &const_ref4b = const_extern1;
+const_fixed2 &const_ref4c = const_extern1;
+
+const_fixed1 &const_ref5a = const_extern1_alias;
+const_fixed1_alias &const_ref5b = const_extern1_alias;
+const_fixed2 &const_ref5c = const_extern1_alias;
+
+const_fixed1 &const_ref6a = const_extern2;
+const_fixed1_alias &const_ref6b = const_extern2;
+const_fixed2 &const_ref6c = const_extern2;
+
+const_fixed1 &const_ref4a_foo = const_extern1_foo.var;
+const_fixed1_alias &const_ref4b_foo = const_extern1_foo.var;
+const_fixed2 &const_ref4c_foo = const_extern1_foo.var;
+
+const_fixed1 &const_ref5a_foo = const_extern1_alias_foo.var;
+const_fixed1_alias &const_ref5b_foo = const_extern1_alias_foo.var;
+const_fixed2 &const_ref5c_foo = const_extern1_alias_foo.var;
+
+const_fixed1 &const_ref6a_foo = const_extern2_foo.var;
+const_fixed1_alias &const_ref6b_foo = const_extern2_foo.var;
+const_fixed2 &const_ref6c_foo = const_extern2_foo.var;
--- /dev/null
+/* { dg-options "-msve-vector-bits=256 -W -Wall" } */
+
+#include <arm_sve.h>
+
+#define N __ARM_FEATURE_SVE_BITS
+#define FIXED_ATTR __attribute__ ((arm_sve_vector_bits (N)))
+#define ALIGNED_ATTR __attribute__((aligned(N / 8)))
+
+typedef svint8_t var1;
+typedef __SVInt8_t var2;
+
+typedef const var1 const_var1;
+typedef const var2 const_var2;
+
+typedef var1 aligned_var1 ALIGNED_ATTR;
+typedef var2 aligned_var2 ALIGNED_ATTR;
+
+typedef var1 fixed1 FIXED_ATTR;
+typedef var1 fixed1_alias FIXED_ATTR;
+typedef var2 fixed2 FIXED_ATTR;
+
+typedef const_var1 const_fixed1 FIXED_ATTR;
+typedef const var1 const_fixed1_alias FIXED_ATTR;
+typedef const_var2 const_fixed2 FIXED_ATTR;
+
+typedef aligned_var1 aligned_fixed1 FIXED_ATTR;
+typedef var1 aligned_fixed1_alias FIXED_ATTR ALIGNED_ATTR;
+typedef aligned_var2 aligned_fixed2 FIXED_ATTR;
+
+extern fixed1 extern1;
+extern fixed1_alias extern1_alias;
+extern fixed2 extern2;
+
+extern const_fixed1 const_extern1;
+extern const_fixed1_alias const_extern1_alias;
+extern const_fixed2 const_extern2;
+
+fixed1 *ptr1a = &extern1;
+fixed1_alias *ptr1b = &extern1;
+fixed2 *ptr1c = &extern1;
+
+fixed1 *ptr2a = &extern1_alias;
+fixed1_alias *ptr2b = &extern1_alias;
+fixed2 *ptr2c = &extern1_alias;
+
+fixed1 *ptr3a = &extern2;
+fixed1_alias *ptr3b = &extern2;
+fixed2 *ptr3c = &extern2;
+
+fixed1 *ptr4a = &const_extern1; // { dg-error {invalid conversion} "c++" { target c++ } }
+ // { dg-warning {discards 'const' qualifier} "c" { target c } .-1 }
+fixed1_alias *ptr4b = &const_extern1; // { dg-error {invalid conversion} "c++" { target c++ } }
+ // { dg-warning {discards 'const' qualifier} "c" { target c } .-1 }
+fixed2 *ptr4c = &const_extern1; // { dg-error {invalid conversion} "c++" { target c++ } }
+ // { dg-warning {discards 'const' qualifier} "c" { target c } .-1 }
+
+const fixed1 *ptr5a = &const_extern2;
+const fixed1_alias *ptr5b = &const_extern2;
+const fixed2 *ptr5c = &const_extern2;
+
+const_fixed1 *const_ptr1a = &extern1;
+const_fixed1_alias *const_ptr1b = &extern1;
+const_fixed2 *const_ptr1c = &extern1;
+
+const_fixed1 *const_ptr2a = &extern1_alias;
+const_fixed1_alias *const_ptr2b = &extern1_alias;
+const_fixed2 *const_ptr2c = &extern1_alias;
+
+const_fixed1 *const_ptr3a = &extern2;
+const_fixed1_alias *const_ptr3b = &extern2;
+const_fixed2 *const_ptr3c = &extern2;
+
+const_fixed1 *const_ptr4a = &const_extern1;
+const_fixed1_alias *const_ptr4b = &const_extern1;
+const_fixed2 *const_ptr4c = &const_extern1;
+
+const_fixed1 *const_ptr5a = &const_extern1_alias;
+const_fixed1_alias *const_ptr5b = &const_extern1_alias;
+const_fixed2 *const_ptr5c = &const_extern1_alias;
+
+const_fixed1 *const_ptr6a = &const_extern2;
+const_fixed1_alias *const_ptr6b = &const_extern2;
+const_fixed2 *const_ptr6c = &const_extern2;
+
+struct normal1 { int x; fixed1 y; };
+struct normal1_alias { int x; fixed1_alias y; };
+struct normal2 { int x; fixed2 y; };
+
+struct aligned1 { int x; aligned_fixed1 y; };
+struct aligned1_alias { int x; aligned_fixed1_alias y; };
+struct aligned2 { int x; aligned_fixed2 y; };
+
+#define ASSERT(NAME, TEST) typedef int NAME[(TEST) ? 1 : -1]
+
+ASSERT (check_normal1, sizeof (struct normal1) == N / 8 + 16);
+ASSERT (check_normal1_alias, sizeof (struct normal1_alias) == N / 8 + 16);
+ASSERT (check_normal2, sizeof (struct normal2) == N / 8 + 16);
+
+ASSERT (check_aligned1, sizeof (struct aligned1) == N / 4);
+ASSERT (check_aligned1_alias, sizeof (struct aligned1_alias) == N / 4);
+ASSERT (check_aligned2, sizeof (struct aligned2) == N / 4);