]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/44075 (__builtin_eh_return miscompiled)
authorAlan Modra <amodra@gmail.com>
Fri, 4 Jun 2010 04:58:05 +0000 (14:28 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Fri, 4 Jun 2010 04:58:05 +0000 (14:28 +0930)
PR target/44075
* gcc/config/rs6000/rs6000.c (struct machine_function): Reorder
fields for better packing.  Add lr_save_state.
(rs6000_ra_ever_killed): Return lr_save_state if set.
(rs6000_emit_eh_reg_restore): Set lr_save_state.

From-SVN: r160248

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index d062536754f16fadf817a625a8340c537baa4643..c979c9917a02590d91cfca54c77391c66a38efb7 100644 (file)
@@ -1,3 +1,11 @@
+2010-06-04  Alan Modra  <amodra@gmail.com>
+
+       PR target/44075
+       * gcc/config/rs6000/rs6000.c (struct machine_function): Reorder
+       fields for better packing.  Add lr_save_state.
+       (rs6000_ra_ever_killed): Return lr_save_state if set.
+       (rs6000_emit_eh_reg_restore): Set lr_save_state.
+
 2010-05-24  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline:
index b39c456720d2ca87a48ef5c85fb9fef479a775c7..228477fce80b973994e3e00296749f0f2ac5ff18 100644 (file)
@@ -115,14 +115,16 @@ typedef struct rs6000_stack {
    This is added to the cfun structure.  */
 typedef struct machine_function GTY(())
 {
-  /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
-  int ra_needs_full_frame;
   /* Some local-dynamic symbol.  */
   const char *some_ld_name;
   /* Whether the instruction chain has been scanned already.  */
   int insn_chain_scanned_p;
+  /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
+  int ra_needs_full_frame;
   /* Flags if __builtin_return_address (0) was used.  */
   int ra_need_lr;
+  /* Cache lr_save_p after expansion of builtin_eh_return.  */
+  int lr_save_state;
   /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
      varargs save area.  */
   HOST_WIDE_INT varargs_save_offset;
@@ -14914,6 +14916,9 @@ rs6000_ra_ever_killed (void)
   if (current_function_is_thunk)
     return 0;
 
+  if (cfun->machine->lr_save_state)
+    return cfun->machine->lr_save_state - 1;
+
   /* regs_ever_live has LR marked as used if any sibcalls are present,
      but this should not force saving and restoring in the
      pro/epilogue.  Likewise, reg_set_between_p thinks a sibcall
@@ -15083,6 +15088,12 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
     }
   else
     emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
+
+  /* Freeze lr_save_p.  We've just emitted rtl that depends on the
+     state of lr_save_p so any change from here on would be a bug.  In
+     particular, stop rs6000_ra_ever_killed from considering the SET
+     of lr we may have added just above.  */ 
+  cfun->machine->lr_save_state = info->lr_save_p + 1;
 }
 
 static GTY(()) alias_set_type set = -1;