Commit 888c7050 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 6d3daa1a
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
......
...@@ -895,12 +895,16 @@ emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg) ...@@ -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) ...@@ -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) ...@@ -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
......
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.
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment