]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Check for matching CONST_VECTOR encodings [PR99929]
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 14 Apr 2021 19:06:45 +0000 (20:06 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 14 Apr 2021 19:06:45 +0000 (20:06 +0100)
PR99929 is one of those “how did we get away with this for so long”
bugs: the equality routines weren't checking whether two variable-length
CONST_VECTORs had the same encoding.  This meant that:

   { 1, 0, 0, 0, 0, 0, ... }

would appear to be equal to:

   { 1, 0, 1, 0, 1, 0, ... }

since both are represented using the elements { 1, 0 }.

gcc/
PR rtl-optimization/99929
* rtl.h (same_vector_encodings_p): New function.
* cse.c (exp_equiv_p): Check that CONST_VECTORs have the same encoding.
* cselib.c (rtx_equal_for_cselib_1): Likewise.
* jump.c (rtx_renumbered_equal_p): Likewise.
* lra-constraints.c (operands_match_p): Likewise.
* reload.c (operands_match_p): Likewise.
* rtl.c (rtx_equal_p_cb, rtx_equal_p): Likewise.

gcc/testsuite/
* gcc.target/aarch64/sve/pr99929_1.c: New file.
* gcc.target/aarch64/sve/pr99929_2.c: Likewise.

gcc/cse.c
gcc/cselib.c
gcc/jump.c
gcc/lra-constraints.c
gcc/reload.c
gcc/rtl.c
gcc/rtl.h
gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c [new file with mode: 0644]

index 37c6959abea73c3f02c644327626d8790d64116d..df191d5aa3ff7aa27f8fd8a380f1d91a66811ecd 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2637,6 +2637,11 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse)
     CASE_CONST_UNIQUE:
       return x == y;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case LABEL_REF:
       return label_ref_label (x) == label_ref_label (y);
 
index 2d34a914c6bc2ff677c08d9f66562a0dbf605ac8..779874eeb2db81dd18abf41e049a77f16eec73af 100644 (file)
@@ -1048,6 +1048,11 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth)
     case DEBUG_EXPR:
       return 0;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case DEBUG_IMPLICIT_PTR:
       return DEBUG_IMPLICIT_PTR_DECL (x)
             == DEBUG_IMPLICIT_PTR_DECL (y);
index 561dbb70d15833cb53183b9ba8ce976c4bfd59a7..67b5c3374a6501b861dc5e6507b596c39bcd2d19 100644 (file)
@@ -1777,6 +1777,11 @@ rtx_renumbered_equal_p (const_rtx x, const_rtx y)
     CASE_CONST_UNIQUE:
       return 0;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case LABEL_REF:
       /* We can't assume nonlocal labels have their following insns yet.  */
       if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
index 9425f2d7e73920c9543f28c19bf0e680ea742497..5c2a2d7ce9c2121fd8ad84ed7442bb2b7e690cca 100644 (file)
@@ -834,6 +834,11 @@ operands_match_p (rtx x, rtx y, int y_hard_regno)
     CASE_CONST_UNIQUE:
       return false;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case LABEL_REF:
       return label_ref_label (x) == label_ref_label (y);
     case SYMBOL_REF:
index 461fd0272eb5af4222f5c90a63fb32f0f3616ebb..e18e27c2405d10a7d4f20ddb3ae4ae17dbeb362c 100644 (file)
@@ -2310,6 +2310,11 @@ operands_match_p (rtx x, rtx y)
     CASE_CONST_UNIQUE:
       return 0;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case LABEL_REF:
       return label_ref_label (x) == label_ref_label (y);
     case SYMBOL_REF:
index 1aa794c82ca348d8e5843d42706ea7966e7319d8..e4ae1683069b49966edf0b5d270f1fa64206cf1a 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -466,6 +466,11 @@ rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
     CASE_CONST_UNIQUE:
       return 0;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case DEBUG_IMPLICIT_PTR:
       return DEBUG_IMPLICIT_PTR_DECL (x)
             == DEBUG_IMPLICIT_PTR_DECL (y);
@@ -608,6 +613,11 @@ rtx_equal_p (const_rtx x, const_rtx y)
     CASE_CONST_UNIQUE:
       return 0;
 
+    case CONST_VECTOR:
+      if (!same_vector_encodings_p (x, y))
+       return false;
+      break;
+
     case DEBUG_IMPLICIT_PTR:
       return DEBUG_IMPLICIT_PTR_DECL (x)
             == DEBUG_IMPLICIT_PTR_DECL (y);
index a392721c8d0f345bf9684785d6955eb2bb1575b6..398d745aff50361cd1fc212c75d8fce76a7ba161 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3087,6 +3087,23 @@ vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
   return const_vec_series_p (x, base_out, step_out);
 }
 
+/* Return true if CONST_VECTORs X and Y, which are known to have the same mode,
+   also have the same encoding.  This means that they are equal whenever their
+   operands are equal.  */
+
+inline bool
+same_vector_encodings_p (const_rtx x, const_rtx y)
+{
+  /* Don't be fussy about the encoding of constant-length vectors,
+     since XVECEXP (X, 0) and XVECEXP (Y, 0) list all the elements anyway.  */
+  if (poly_uint64 (CONST_VECTOR_NUNITS (x)).is_constant ())
+    return true;
+
+  return (CONST_VECTOR_NPATTERNS (x) == CONST_VECTOR_NPATTERNS (y)
+         && (CONST_VECTOR_NELTS_PER_PATTERN (x)
+             == CONST_VECTOR_NELTS_PER_PATTERN (y)));
+}
+
 /* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X.  */
 
 inline scalar_int_mode
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_1.c
new file mode 100644 (file)
index 0000000..1fe1813
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <arm_sve.h>
+
+static void e(short *g, short p2) { *g ^= p2; }
+static short m[23];
+int main() {
+  for (unsigned i = 0; i < 23; ++i)
+    m[i] = 4;
+  if (svaddv(svptrue_pat_b32(SV_VL1), svdup_u32(1)) != 1)
+    __builtin_abort();
+  for (unsigned i = 0; i < 3; ++i)
+    e(m, m[i]);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c b/gcc/testsuite/gcc.target/aarch64/sve/pr99929_2.c
new file mode 100644 (file)
index 0000000..50d432d
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "pr99929_1.c"
+
+/* { dg-final { scan-assembler {\tptrue\tp[0-7].[bhsd], vl1\n} } } */