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:
parent
6d3daa1afb
commit
888c705092
|
@ -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>
|
||||
|
||||
PR tree-optimization/79673
|
||||
|
|
|
@ -895,12 +895,16 @@ emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
|
|||
just use
|
||||
fld b
|
||||
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)
|
||||
&& REGNO (i1dest) == FIRST_STACK_REG
|
||||
&& MEM_P (SET_SRC (i1set))
|
||||
&& !side_effects_p (SET_SRC (i1set))
|
||||
&& (MEM_P (i1src) || GET_CODE (i1src) == CONST_DOUBLE)
|
||||
&& !side_effects_p (i1src)
|
||||
&& hard_regno == FIRST_STACK_REG + 1
|
||||
&& 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)
|
||||
{
|
||||
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
|
||||
stack regs are loads, where the latter (i1)
|
||||
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. */
|
||||
if (REG_P (i2dest)
|
||||
&& 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. */
|
||||
&& !side_effects_p (SET_SRC (i2set))
|
||||
&& !side_effects_p (i2src)
|
||||
/* And that the two instructions can actually be
|
||||
swapped, i.e. there shouldn't be any stores
|
||||
in between i2 and i1 that might alias with
|
||||
|
|
|
@ -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>
|
||||
|
||||
* gcc.dg/pr61441.c: Use dg-add-options ieee.
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue