On 3/16/21 1:16 AM, Ilya Leoshkevich wrote:
> Bootstrapped and regtested on s390x-redhat-linux. Ok for master?
>
>
>
> When a long double is passed to an asm statement with a "+fvm"
> constraint, a LRA loop occurs. This happens, because LRA chooses the
> widest register class in this case (VEC_REGS), but the code generated
> by s390_md_asm_adjust() always wants FP_REGS. Mismatching register
> classes cause infinite reloading.
>
> Fix by treating "fv" constraints as "v" in s390_md_asm_adjust().
>
> gcc/ChangeLog:
>
> * config/s390/s390.c (f_constraint_p): Treat "fv" constraints
> as "v".
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/s390/vector/long-double-asm-fprvrmem.c: New test.
Ok. Thanks!
Andreas
> ---
> gcc/config/s390/s390.c | 12 ++--
> .../s390/vector/long-double-asm-fprvrmem.c | 11 +++
> 2 files changed, 21 insertions(+), 2 deletions(-)
> create mode 100644
> gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
>
> diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
> index 151136bedbc..f7b1c03561e 100644
> --- a/gcc/config/s390/s390.c
> +++ b/gcc/config/s390/s390.c
> @@ -16714,13 +16714,21 @@ s390_shift_truncation_mask (machine_mode mode)
> static bool
> f_constraint_p (const char *constraint)
> {
> + bool seen_f_p = false;
> + bool seen_v_p = false;
> +
>for (size_t i = 0, c_len = strlen (constraint); i < c_len;
> i += CONSTRAINT_LEN (constraint[i], constraint + i))
> {
>if (constraint[i] == 'f')
> - return true;
> + seen_f_p = true;
> + if (constraint[i] == 'v')
> + seen_v_p = true;
> }
> - return false;
> +
> + /* Treat "fv" constraints as "v", because LRA will choose the widest
> register
> + * class. */
> + return seen_f_p && !seen_v_p;
> }
>
> /* Implement TARGET_MD_ASM_ADJUST hook in order to fix up "f"
> diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
> b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
> new file mode 100644
> index 000..f95656c5723
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-fprvrmem.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -march=z14 -mzarch" } */
> +
> +long double
> +foo (long double x)
> +{
> + x = x * x;
> + asm("# %0" : "+fvm"(x));
> + x = x + x;
> + return x;
> +}
>