re PR target/70465 (Poor code for x87 asm)

PR target/70465
	* reg-stack.c (emit_swap_insn): Treat (float_extend:?F (mem:?F))
	and (const_double:?F) like (mem:?F) for the purpose of fxch %st(1)
	elimination by swapping fld*.

	* gcc.target/i386/pr70465-2.c: New test.

From-SVN: r245654
This commit is contained in:
Jakub Jelinek 2017-02-22 18:17:17 +01:00 committed by Jakub Jelinek
parent 6d3daa1afb
commit 888c705092
4 changed files with 49 additions and 5 deletions

View File

@ -1,3 +1,10 @@
2017-02-22 Jakub Jelinek <jakub@redhat.com>
PR target/70465
* reg-stack.c (emit_swap_insn): Treat (float_extend:?F (mem:?F))
and (const_double:?F) like (mem:?F) for the purpose of fxch %st(1)
elimination by swapping fld*.
2017-02-22 Richard Biener <rguenther@suse.de> 2017-02-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/79673 PR tree-optimization/79673

View File

@ -895,12 +895,16 @@ emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
just use just use
fld b fld b
fld a fld a
if possible. */ if possible. Similarly for fld1, fldz, fldpi etc. instead of any
of the loads or for float extension from memory. */
i1src = SET_SRC (i1set);
if (GET_CODE (i1src) == FLOAT_EXTEND)
i1src = XEXP (i1src, 0);
if (REG_P (i1dest) if (REG_P (i1dest)
&& REGNO (i1dest) == FIRST_STACK_REG && REGNO (i1dest) == FIRST_STACK_REG
&& MEM_P (SET_SRC (i1set)) && (MEM_P (i1src) || GET_CODE (i1src) == CONST_DOUBLE)
&& !side_effects_p (SET_SRC (i1set)) && !side_effects_p (i1src)
&& hard_regno == FIRST_STACK_REG + 1 && hard_regno == FIRST_STACK_REG + 1
&& i1 != BB_HEAD (current_block)) && i1 != BB_HEAD (current_block))
{ {
@ -930,6 +934,9 @@ emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
&& (i2set = single_set (i2)) != NULL_RTX) && (i2set = single_set (i2)) != NULL_RTX)
{ {
rtx i2dest = *get_true_reg (&SET_DEST (i2set)); rtx i2dest = *get_true_reg (&SET_DEST (i2set));
rtx i2src = SET_SRC (i2set);
if (GET_CODE (i2src) == FLOAT_EXTEND)
i2src = XEXP (i2src, 0);
/* If the last two insns before insn that involve /* If the last two insns before insn that involve
stack regs are loads, where the latter (i1) stack regs are loads, where the latter (i1)
pushes onto the register stack and thus pushes onto the register stack and thus
@ -937,9 +944,9 @@ emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
%st to %st(1), consider swapping them. */ %st to %st(1), consider swapping them. */
if (REG_P (i2dest) if (REG_P (i2dest)
&& REGNO (i2dest) == FIRST_STACK_REG && REGNO (i2dest) == FIRST_STACK_REG
&& MEM_P (SET_SRC (i2set)) && (MEM_P (i2src) || GET_CODE (i2src) == CONST_DOUBLE)
/* Ensure i2 doesn't have other side-effects. */ /* Ensure i2 doesn't have other side-effects. */
&& !side_effects_p (SET_SRC (i2set)) && !side_effects_p (i2src)
/* And that the two instructions can actually be /* And that the two instructions can actually be
swapped, i.e. there shouldn't be any stores swapped, i.e. there shouldn't be any stores
in between i2 and i1 that might alias with in between i2 and i1 that might alias with

View File

@ -1,3 +1,8 @@
2017-02-22 Jakub Jelinek <jakub@redhat.com>
PR target/70465
* gcc.target/i386/pr70465-2.c: New test.
2017-02-21 Uros Bizjak <ubizjak@gmail.com> 2017-02-21 Uros Bizjak <ubizjak@gmail.com>
* gcc.dg/pr61441.c: Use dg-add-options ieee. * gcc.dg/pr61441.c: Use dg-add-options ieee.

View File

@ -0,0 +1,25 @@
/* PR target/70465 */
/* { dg-do compile } */
/* { dg-options "-Ofast -mfpmath=387 -fomit-frame-pointer" } */
/* { dg-final { scan-assembler-not "fxch\t%st.1" } } */
extern float d[1024];
static inline long double
foo (long double a, long double b)
{
return a < b ? a : b;
}
static inline long double
bar (long double a, long double b)
{
return a > b ? a : b;
}
float
baz (void)
{
long double c = d[0];
return foo (bar (c, 0.0l), 1.0l);
}