"Roger Sayle" <[email protected]> writes:
> diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
> index 92a2a6e954a..32267ac061b 100644
> --- a/gcc/simplify-rtx.cc
> +++ b/gcc/simplify-rtx.cc
> @@ -5586,17 +5586,30 @@ simplify_ashift:
>           return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
>                                       gen_rtx_PARALLEL (VOIDmode, vec));
>         }
> -     /* (vec_concat:
> -          (subreg_lowpart:N OP)
> -          (vec_select:N OP P))  -->  OP when P selects the high half
> -         of the OP.  */
> -     if (GET_CODE (trueop0) == SUBREG
> -         && subreg_lowpart_p (trueop0)
> -         && GET_CODE (trueop1) == VEC_SELECT
> -         && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
> -         && !side_effects_p (XEXP (trueop1, 0))
> -         && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
> -       return XEXP (trueop1, 0);
> +     /* (vec_concat:N
> +          (subreg:N/2 OP 0)
> +          (subreg:N/2 OP N/2)) --> OP
> +        i.e. where concatenating the first and second halves of the
> +        same object OP.  */
> +     if (known_eq (GET_MODE_SIZE (op0_mode),
> +                   GET_MODE_SIZE (op1_mode)))

I thought this was required for all VEC_CONCATs.  Even if it isn't,
I think the GET_MODE_SIZE tests below are enough to ensure that
every byte of base0 is used exactly once.

So my preference would be to drop this check.

> +       {
> +         poly_uint64 offset = 0u;
> +         rtx base0 = get_ref_base_and_offset (trueop0, &offset);
> +         if (base0
> +             && known_eq (offset, 0u)
> +             && known_eq (GET_MODE_SIZE (GET_MODE (base0)),
> +                          GET_MODE_SIZE (mode)))
> +           {
> +             rtx base1 = get_ref_base_and_offset (trueop1, &offset);
> +             if (base1

The null tests for base0 and base1 don't seem necessary.  IMO it would
be a misfeature for get_ref_base_and_offset to return null.  In the
worst case it can just return the parameter and set the offset to 0.

LGTM otherwise, but I think someone else should give the final ok.

Thanks for doing this.

Richard

> +                 && rtx_equal_p (base0, base1)
> +                 && known_eq (offset, GET_MODE_SIZE (op0_mode))
> +                 && !side_effects_p (trueop0)
> +                 && !side_effects_p (trueop1))
> +               return gen_lowpart (mode, base0);
> +           }
> +       }
>        }
>        return 0;
>  
> diff --git a/gcc/testsuite/gcc.target/i386/pr48609.c 
> b/gcc/testsuite/gcc.target/i386/pr48609.c
> new file mode 100644
> index 00000000000..8af9d883761
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr48609.c
> @@ -0,0 +1,13 @@
> +/* PR target/48609 */
> +/* { dg-do compile { target { ! ia32 } } } */
> +/* { dg-options "-O2 -msse2" } */
> +typedef _Complex float SCtype;
> +extern SCtype bar;
> +void foo (SCtype x)
> +{
> +  bar = x;
> +}
> +
> +/* { dg-final { scan-assembler-not "movdqa" } } */
> +/* { dg-final { scan-assembler-not "shufps" } } */
> +/* { dg-final { scan-assembler-not "unpcklps" } } */

Reply via email to