summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-02-09 08:50:58 +1030
committerAlan Modra <amodra@gcc.gnu.org>2019-02-09 08:50:58 +1030
commit9b747072b98c6f8a0ffb058e89b45d36b47152cc (patch)
tree3e40cee7cbfd77fe6d27b5071742fb2117a8fa73 /gcc/config/rs6000
parentddf321918d35a4f737dda35867c550ab7daf8dfc (diff)
downloadgcc-9b747072b98c6f8a0ffb058e89b45d36b47152cc.tar.gz
[RS6000] Correct save_reg_p
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
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/rs6000.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 711278c7422..b4ff18d414c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
}