mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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:
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user