[RS6000] Correct save_reg_p
authorAlan Modra <amodra@gmail.com>
Fri, 8 Feb 2019 22:20:58 +0000 (08:50 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Fri, 8 Feb 2019 22:20:58 +0000 (08:50 +1030)
Fixes lack of r30 save/restore on

// -m32 -fpic -ftls-model=initial-exec
__thread char* p;
char** f1 (void) { return &p; }

and

// -m32 -fpic -msecure-plt
extern int foo (int);
int f1 (int x) { return foo (x); }

These are both caused by save_reg_p returning false when the pic
offset table reg (r30 for ABI_V4) was used, due to the logic not
exactly matching that in rs6000_emit_prologue to set up r30.

I also noticed that save_reg_p isn't following the comment regarding
calls_eh_return (since svn 267049, git 0edf78b1b2a0), and the comment
needs tweaking too.  For why the revised comment is correct, grep for
saves_all_registers in lra.c, and yes, we do want to save the pic
offset table reg for eh_return.

PR target/88343
* config/rs6000/rs6000.c (save_reg_p): Correct calls_eh_return
case.  Match logic in rs6000_emit_prologue emitting pic_offset_table
setup.

From-SVN: r268708

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

index 9e5a140b0e12e0b26ca535eac48eaa85323df4cc..0079a6948e84299c666f8d4a3db342a947bdeed8 100644 (file)
@@ -1,3 +1,10 @@
+2019-02-09  Alan Modra  <amodra@gmail.com>
+
+       PR target/88343
+       * config/rs6000/rs6000.c (save_reg_p): Correct calls_eh_return
+       case.  Match logic in rs6000_emit_prologue emitting pic_offset_table
+       setup.
+
 2019-02-08  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR middle-end/88560
index 711278c742257ba9f7817e9fbee5c3da0366e2ca..b4ff18d414c34501b0c1435782bd1c7e4a31b813 100644 (file)
@@ -24008,21 +24008,30 @@ rs6000_split_multireg_move (rtx dst, rtx src)
 static bool
 save_reg_p (int reg)
 {
-  /* We need to mark the PIC offset register live for the same conditions
-     as it is set up, or otherwise it won't be saved before we clobber it.  */
-
   if (reg == RS6000_PIC_OFFSET_TABLE_REGNUM && !TARGET_SINGLE_PIC_BASE)
     {
       /* When calling eh_return, we must return true for all the cases
         where conditional_register_usage marks the PIC offset reg
-        call used.  */
+        call used or fixed.  */
+      if (crtl->calls_eh_return
+         && ((DEFAULT_ABI == ABI_V4 && flag_pic)
+             || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
+             || (TARGET_TOC && TARGET_MINIMAL_TOC)))
+       return true;
+
+      /* We need to mark the PIC offset register live for the same
+        conditions as it is set up in rs6000_emit_prologue, or
+        otherwise it won't be saved before we clobber it.  */
       if (TARGET_TOC && TARGET_MINIMAL_TOC
-         && (crtl->calls_eh_return
-             || df_regs_ever_live_p (reg)
-             || !constant_pool_empty_p ()))
+         && !constant_pool_empty_p ())
+       return true;
+
+      if (DEFAULT_ABI == ABI_V4
+         && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
+         && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
        return true;
 
-      if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN)
+      if (DEFAULT_ABI == ABI_DARWIN
          && flag_pic && crtl->uses_pic_offset_table)
        return true;
     }