diff mbox series

[committed] aarch64: Handle SVE attributes in comp_type_attributes [PR100270]

Message ID mptbla0ht32.fsf@arm.com
State New
Headers show
Series [committed] aarch64: Handle SVE attributes in comp_type_attributes [PR100270] | expand

Commit Message

Richard Sandiford April 27, 2021, 11:20 a.m. UTC
Even though "SVE type" and "SVE sizeless type" are marked as
affecting type identity, the middle end doesn't truly believe
it unless we also handle them in comp_type_attributes.

Tested on aarch64-linux-gnu.  Pushed to trunk so far, but I'll backport
to GCC 11 too.  The GCC 10 version will look different.

Richard


gcc/
	PR target/100270
	* config/aarch64/aarch64.c (aarch64_comp_type_attributes): Handle
	SVE attributes.

gcc/testsuite/
	PR target/100270
	* gcc.target/aarch64/sve/acle/general-c/pr100270_1.c: New test.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Change
	expected error message when subtracting pointers to different
	vector types.  Expect warnings when mixing them elsewhere.
	* gcc.target/aarch64/sve/acle/general/attributes_7.c: Remove
	XFAILs.  Tweak error messages for some cases.
---
 gcc/config/aarch64/aarch64.c                  |   4 +
 .../aarch64/sve/acle/general-c/pr100270_1.c   | 103 ++++++++++++++++++
 .../aarch64/sve/acle/general-c/sizeless-2.c   |  36 +++---
 .../aarch64/sve/acle/general/attributes_7.c   |  72 ++++++------
 4 files changed, 166 insertions(+), 49 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/pr100270_1.c
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 12625a4bee3..dbaf6fbe4c8 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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;
 }
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/pr100270_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/pr100270_1.c
new file mode 100644
index 00000000000..05232d79325
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/pr100270_1.c
@@ -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);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
index 3af36de9994..c575492c1f8 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
@@ -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.  */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
index e2e74700a01..621666ce6c9 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/attributes_7.c
@@ -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;
 }