]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Check for matching CONST_VECTOR encodings [PR99929]
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 26 Apr 2021 08:36:48 +0000 (09:36 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 26 Apr 2021 08:36:48 +0000 (09:36 +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.

(cherry picked from commit a87d3f964df31d4fbceb822c6d293e85c117d992)

gcc/cse.c
gcc/cselib.c
gcc/jump.c
gcc/lra-constraints.c
gcc/reload.c
gcc/rtl.c
gcc/rtl.h

index a73a771041a71460cb1728c2b7037cff606e3d01..2382b24d81616cc29945a28309e36ef8e972983e 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2627,6 +2627,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 5a978c1f4b8a8a86a2bd9dbbd5628cd5c5f86b3d..de5d9d4e2badae0850d3d1c4ee8a5ff738e2ceb6 100644 (file)
@@ -938,6 +938,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 f379048f636856dc43c03128912e36eea23bebd1..112317cd7e1e467d4fd2885bf986a66f6aa399ef 100644 (file)
@@ -1767,6 +1767,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 1e98df481322ec5ce5cf624e6ecea6440999eccc..805024419450de9ae9328fbe060e011b4e03f3f6 100644 (file)
@@ -759,6 +759,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 88299a8a9058196e6a0f88600348fc208cc8c314..0e4f72065a2a97eb884bb3694a9b3724427ea469 100644 (file)
@@ -2291,6 +2291,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 dc03e1e5426d124e0d55592b64512fdf1ffb9aad..61cd447458655642bb32708815c4eca8fadae0f4 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -460,6 +460,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);
@@ -602,6 +607,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 31567126c83bfcfa522a7aebe42c476fb2b660a7..fb2e088f7d1b30cdf95d14d652167c19198d0ce5 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3035,6 +3035,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