Richard Biener <[email protected]> writes:
> The following adds simplification of a scalar mode vec_select wrapping
> a vec_concat. combine sees
>
> (insn 7 4 8 2 (set (reg:V2DF 106)
> (vec_concat:V2DF (plus:DF (vec_select:DF (reg/v:V2DF 101 [ p ])
> (parallel [
> (const_int 0 [0])
> ]))
> (vec_select:DF (reg/v:V2DF 101 [ p ])
> (parallel [
> (const_int 1 [0x1])
> ])))
> (plus:DF (vec_select:DF (reg/v:V2DF 101 [ p ])
> (parallel [
> (const_int 0 [0])
> ]))
> (vec_select:DF (reg/v:V2DF 101 [ p ])
> (parallel [
> (const_int 1 [0x1])
> ]))))) "t.c":5:11 3234 {*sse3_haddv2df3}
> (expr_list:REG_DEAD (reg/v:V2DF 101 [ p ])
> (nil)))
> (insn 8 7 9 2 (set (reg:DF 105)
> (vec_select:DF (reg:V2DF 106)
> (parallel [
> (const_int 0 [0])
> ]))) "t.c":5:11 7297 {sse2_storelpd}
> (expr_list:REG_DEAD (reg:V2DF 106)
> (nil)))
>
> and this should simplify and combine to
>
> (set (reg:DF 105)
> (plus:DF (vec_select:DF (reg:V2DF 109 [ p ])
> (parallel [
> (const_int 0 [0])
> ]))
> (vec_select:DF (reg:V2DF 109 [ p ])
> (parallel [
> (const_int 1 [0x1])
> ]))))
>
> which x86 can recognize (but rejects due to consting, see PR126328).
> There'll be test coverage in gcc.target/i386/pr54400.c
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> OK?
LGTM FWIW.
> Thanks,
> Richard.
>
> * simplify-rtx.cc (simplify_context::simplify_binary_operation_1):
> Simplify scalar vec_select of vec_concat.
> ---
> gcc/simplify-rtx.cc | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
> index 882a11c5760..6f8ee53f209 100644
> --- a/gcc/simplify-rtx.cc
> +++ b/gcc/simplify-rtx.cc
> @@ -5210,6 +5210,20 @@ simplify_ashift:
> tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
> return tmp;
> }
> + /* If we select one half of a vec_concat, return that. */
> + else if (GET_CODE (trueop0) == VEC_CONCAT)
> + {
> + rtx subop0 = XEXP (trueop0, 0);
> + rtx subop1 = XEXP (trueop0, 1);
> + machine_mode mode0 = GET_MODE (subop0);
> + machine_mode mode1 = GET_MODE (subop1);
> + int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
> + if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
> + return subop0;
> + if (known_eq (i0, GET_MODE_NUNITS (mode0))
> + && mode == mode1 && !side_effects_p (subop0))
> + return subop1;
> + }
> }
> else
> {