This testcase triggered an ICE in rtx_vector_builder::step because
we were trying to use a stepped representation for floating-point
constants.  The underlying problem was that the arguments to
rtx_vector_builder were the wrong way around, meaning that some
variations were likely to be incorrectly encoded for integers
(but probably as a silent failure).

Also, aarch64_sve_expand_vector_init_handle_trailing_constants
tries to extend the trailing constant elements to a full vector
by following the "natural" pattern of the original vector, which
should generally lead to nicer constants.  However, for the testcase,
we'd then end up picking a variable for some elements.  Fixed by
stubbing out all variable elements with zeros.

That fix involved testing valid_for_const_vector_p.  For consistency,
the patch uses the same test when finding trailing constants, instead
of the previous aarch64_legitimate_constant_p.

Tested on aarch64-linux-gnu, pushed.

Richard


2020-04-20  Richard Sandiford  <richard.sandif...@arm.com>

gcc/
        PR target/94668
        * config/aarch64/aarch64.c (aarch64_sve_expand_vector_init): Fix
        order of arguments to rtx_vector_builder.
        (aarch64_sve_expand_vector_init_handle_trailing_constants): Likewise.
        When extending the trailing constants to a full vector, replace any
        variables with zeros.

gcc/testsuite/
        PR target/94668
        * gcc.target/aarch64/sve/pr94668.c: New test.
---
 gcc/ChangeLog                                 |  9 +++++++
 gcc/config/aarch64/aarch64.c                  | 26 ++++++++++++++-----
 gcc/testsuite/ChangeLog                       |  5 ++++
 .../gcc.target/aarch64/sve/pr94668.c          |  8 ++++++
 4 files changed, 41 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr94668.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc6c6389b90..4c9de79c1fd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-20  Richard Sandiford  <richard.sandif...@arm.com>
+
+       PR target/94668
+       * config/aarch64/aarch64.c (aarch64_sve_expand_vector_init): Fix
+       order of arguments to rtx_vector_builder.
+       (aarch64_sve_expand_vector_init_handle_trailing_constants): Likewise.
+       When extending the trailing constants to a full vector, replace any
+       variables with zeros.
+
 2020-04-20  Jan Hubicka  <hubi...@ucw.cz>
 
        PR ipa/94582
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 24c055df0dc..ee6a2de77a5 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -18382,15 +18382,27 @@ 
aarch64_sve_expand_vector_init_handle_trailing_constants
   int n_trailing_constants = 0;
 
   for (int i = nelts_reqd - 1;
-       i >= 0 && aarch64_legitimate_constant_p (elem_mode, builder.elt (i));
+       i >= 0 && valid_for_const_vector_p (elem_mode, builder.elt (i));
        i--)
     n_trailing_constants++;
 
   if (n_trailing_constants >= nelts_reqd / 2)
     {
-      rtx_vector_builder v (mode, 1, nelts);
+      /* Try to use the natural pattern of BUILDER to extend the trailing
+        constant elements to a full vector.  Replace any variables in the
+        extra elements with zeros.
+
+        ??? It would be better if the builders supported "don't care"
+            elements, with the builder filling in whichever elements
+            give the most compact encoding.  */
+      rtx_vector_builder v (mode, nelts, 1);
       for (int i = 0; i < nelts; i++)
-       v.quick_push (builder.elt (i + nelts_reqd - n_trailing_constants));
+       {
+         rtx x = builder.elt (i + nelts_reqd - n_trailing_constants);
+         if (!valid_for_const_vector_p (elem_mode, x))
+           x = const0_rtx;
+         v.quick_push (x);
+       }
       rtx const_vec = v.build ();
       emit_move_insn (target, const_vec);
 
@@ -18508,7 +18520,7 @@ aarch64_sve_expand_vector_init (rtx target, const 
rtx_vector_builder &builder,
 
   /* Case 2: Vector contains leading constants.  */
 
-  rtx_vector_builder rev_builder (mode, 1, nelts_reqd);
+  rtx_vector_builder rev_builder (mode, nelts_reqd, 1);
   for (int i = 0; i < nelts_reqd; i++)
     rev_builder.quick_push (builder.elt (nelts_reqd - i - 1));
   rev_builder.finalize ();
@@ -18541,8 +18553,8 @@ aarch64_sve_expand_vector_init (rtx target, const 
rtx_vector_builder &builder,
   if (nelts_reqd <= 4)
     return false;
 
-  rtx_vector_builder v_even (mode, 1, nelts);
-  rtx_vector_builder v_odd (mode, 1, nelts);
+  rtx_vector_builder v_even (mode, nelts, 1);
+  rtx_vector_builder v_odd (mode, nelts, 1);
 
   for (int i = 0; i < nelts * 2; i += 2)
     {
@@ -18586,7 +18598,7 @@ aarch64_sve_expand_vector_init (rtx target, rtx vals)
   machine_mode mode = GET_MODE (target);
   int nelts = XVECLEN (vals, 0);
 
-  rtx_vector_builder v (mode, 1, nelts);
+  rtx_vector_builder v (mode, nelts, 1);
   for (int i = 0; i < nelts; i++)
     v.quick_push (XVECEXP (vals, 0, i));
   v.finalize ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ba21a0b7f8..9bf3581b770 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-20  Richard Sandiford  <richard.sandif...@arm.com>
+
+       PR target/94668
+       * gcc.target/aarch64/sve/pr94668.c: New test.
+
 2020-04-20  Jan Hubicka  <hubi...@ucw.cz>
 
        PR ipa/94582
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr94668.c 
b/gcc/testsuite/gcc.target/aarch64/sve/pr94668.c
new file mode 100644
index 00000000000..9ff01e825c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr94668.c
@@ -0,0 +1,8 @@
+/* { dg-options "-O -msve-vector-bits=512" } */
+
+typedef float v16sf __attribute__ ((vector_size(64)));
+v16sf
+foo (float a)
+{
+  return (v16sf) { 0, 0, 0, a, 0, 0, 0, 0, 0, a, 0, 0, 0, 0, 0, 0 };
+}

Reply via email to