IBM Z: Fix "+fvm" constraint with long doubles

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.
This commit is contained in:
Ilya Leoshkevich
2020-12-10 15:43:59 +01:00
parent 995a740cb0
commit 4073a09e23
2 changed files with 21 additions and 2 deletions

View File

@@ -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"

View File

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