From: Michael Matz Date: Sat, 2 Feb 2008 15:00:57 +0000 (+0000) Subject: re PR target/35045 (gcc-4.3 generates wrong code on i386 with -O3) X-Git-Tag: releases/gcc-4.3.0~293 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6994f254d5a429d1eecfb998f859e34582e2885a;p=thirdparty%2Fgcc.git re PR target/35045 (gcc-4.3 generates wrong code on i386 with -O3) PR target/35045 * postreload-gcse.c (record_last_reg_set_info_regno): Renamed from record_last_reg_set_info. (record_last_reg_set_info): Take an RTX argument, iterate over all constituent hardregs. (record_last_set_info, record_opr_changes): Change calls to new signature or to record_last_reg_set_info_regno. * gcc.dg/pr35045.c: New test. From-SVN: r132071 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40afac69f316..c17605d39313 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-02-02 Michael Matz + + PR target/35045 + * postreload-gcse.c (record_last_reg_set_info_regno): Renamed + from record_last_reg_set_info. + (record_last_reg_set_info): Take an RTX argument, iterate over all + constituent hardregs. + (record_last_set_info, record_opr_changes): Change calls to + new signature or to record_last_reg_set_info_regno. + 2008-02-02 Gerald Pfeifer * doc/extend.texi (X86 Built-in Functions): Fix grammar. diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index 5f3192f083d0..805608dc5fab 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -175,7 +175,8 @@ static void free_mem (void); /* Support for hash table construction and transformations. */ static bool oprs_unchanged_p (rtx, rtx, bool); -static void record_last_reg_set_info (rtx, int); +static void record_last_reg_set_info (rtx, rtx); +static void record_last_reg_set_info_regno (rtx, int); static void record_last_mem_set_info (rtx); static void record_last_set_info (rtx, const_rtx, void *); static void record_opr_changes (rtx); @@ -645,7 +646,19 @@ load_killed_in_block_p (int uid_limit, rtx x, bool after_insn) /* Record register first/last/block set information for REGNO in INSN. */ static inline void -record_last_reg_set_info (rtx insn, int regno) +record_last_reg_set_info (rtx insn, rtx reg) +{ + unsigned int regno, end_regno; + + regno = REGNO (reg); + end_regno = END_HARD_REGNO (reg); + do + reg_avail_info[regno] = INSN_CUID (insn); + while (++regno < end_regno); +} + +static inline void +record_last_reg_set_info_regno (rtx insn, int regno) { reg_avail_info[regno] = INSN_CUID (insn); } @@ -680,7 +693,7 @@ record_last_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data) dest = SUBREG_REG (dest); if (REG_P (dest)) - record_last_reg_set_info (last_set_insn, REGNO (dest)); + record_last_reg_set_info (last_set_insn, dest); else if (MEM_P (dest)) { /* Ignore pushes, they don't clobber memory. They may still @@ -691,7 +704,7 @@ record_last_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data) if (! push_operand (dest, GET_MODE (dest))) record_last_mem_set_info (last_set_insn); else - record_last_reg_set_info (last_set_insn, STACK_POINTER_REGNUM); + record_last_reg_set_info_regno (last_set_insn, STACK_POINTER_REGNUM); } } @@ -722,17 +735,17 @@ record_opr_changes (rtx insn) /* Also record autoincremented REGs for this insn as changed. */ for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) if (REG_NOTE_KIND (note) == REG_INC) - record_last_reg_set_info (insn, REGNO (XEXP (note, 0))); + record_last_reg_set_info (insn, XEXP (note, 0)); /* Finally, if this is a call, record all call clobbers. */ if (CALL_P (insn)) { - unsigned int regno, end_regno; + unsigned int regno; rtx link, x; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) - record_last_reg_set_info (insn, regno); + record_last_reg_set_info_regno (insn, regno); for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) if (GET_CODE (XEXP (link, 0)) == CLOBBER) @@ -741,11 +754,7 @@ record_opr_changes (rtx insn) if (REG_P (x)) { gcc_assert (HARD_REGISTER_P (x)); - regno = REGNO (x); - end_regno = END_HARD_REGNO (x); - do - record_last_reg_set_info (insn, regno); - while (++regno < end_regno); + record_last_reg_set_info (insn, x); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 06cd1b139ede..9a2f57050ce3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-02-02 Michael Matz + + PR target/35045 + * gcc.dg/pr35045.c: New test. + 2008-02-02 Thomas Koenig PR libfortran/35001 diff --git a/gcc/testsuite/gcc.dg/pr35045.c b/gcc/testsuite/gcc.dg/pr35045.c new file mode 100644 index 000000000000..16f8799c52d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr35045.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fgcse-after-reload" } */ + +extern void abort (void); + +__attribute__((noinline)) __complex__ float +give_neg1 (void) +{ + __complex__ float res; + __real__ res = -1.0; + __imag__ res = 1.0; + return res; +} + +__attribute__((noinline)) __complex__ float +mycacoshf (__complex__ float x) +{ + __complex__ float res; + res = give_neg1 (); + + /* We have to use the positive branch. */ + if (__real__ res < 0.0) + { + unsigned a,b,c,d,e,f; + res = -res; + asm __volatile__ ("" : "=r" (a), "=r" (b), "=r" (c), "=r" (d), "=r" (e), "=r" (f)); + } + return res; +} + +int main() +{ + __complex__ float res = mycacoshf(1.0); + if (__imag__ res >= 0.0) + abort(); + return 0; +}