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 }; +}