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. --- 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 00000000000..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; +} -- 2.29.2