diff options
author | Xionghu Luo <luoxhu@linux.ibm.com> | 2020-04-26 20:37:27 -0500 |
---|---|---|
committer | Xionghu Luo <luoxhu@linux.ibm.com> | 2020-04-26 20:41:38 -0500 |
commit | f6955089db6c3aa63c276704159ffad1ef15d256 (patch) | |
tree | 0433341f8d43b3c95276846b1130cb88eb5e535b | |
parent | bfdea9ae81f924ecdcc6be9bd64b6c9084881088 (diff) | |
download | gcc-f6955089db6c3aa63c276704159ffad1ef15d256.zip gcc-f6955089db6c3aa63c276704159ffad1ef15d256.tar.gz gcc-f6955089db6c3aa63c276704159ffad1ef15d256.tar.bz2 |
rs6000: Don't use HARD_FRAME_POINTER_REGNUM if it's not live in pro_and_epilogue (PR91518)
This bug is exposed by FRE refactor of r263875. Comparing the fre
dump file shows no obvious change of the segment fault function proves
it to be a target issue.
frame_pointer_needed is set to true in reload pass setup_can_eliminate,
but regs_ever_live[31] is false, pro_and_epilogue uses it without live
check causing CPU2006 465.tonto segment fault of loading from invalid
addresses due to r31 not saved/restored. Thus, add HARD_FRAME_POINTER_REGNUM
live check with frame_pointer_needed_indeed when generating pro_and_epilogue
instructions.
gcc/ChangeLog
2020-04-27 Xiong Hu Luo <luoxhu@linux.ibm.com>
PR target/91518
* config/rs6000/rs6000-logue.c (frame_pointer_needed_indeed):
New variable.
(rs6000_emit_prologue_components):
Check with frame_pointer_needed_indeed.
(rs6000_emit_epilogue_components): Likewise.
(rs6000_emit_prologue): Likewise.
(rs6000_emit_epilogue): Set frame_pointer_needed_indeed.
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-logue.c | 23 |
2 files changed, 25 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38dd583..36b5720 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2020-04-27 Xiong Hu Luo <luoxhu@linux.ibm.com> + + PR target/91518 + * config/rs6000/rs6000-logue.c (frame_pointer_needed_indeed): + New variable. + (rs6000_emit_prologue_components): + Check with frame_pointer_needed_indeed. + (rs6000_emit_epilogue_components): Likewise. + (rs6000_emit_prologue): Likewise. + (rs6000_emit_epilogue): Set frame_pointer_needed_indeed. + 2020-04-25 David Edelsohn <dje.gcc@gmail.com> * config/rs6000/rs6000-logue.c (rs6000_stack_info): Don't push a diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index 7226319..6aad1ff 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -58,6 +58,8 @@ static bool rs6000_save_toc_in_prologue_p (void); static rs6000_stack_t stack_info; +/* Set if HARD_FRAM_POINTER_REGNUM is really needed. */ +static bool frame_pointer_needed_indeed = false; /* Label number of label created for -mrelocatable, to call to so we can get the address of the GOT section */ @@ -2735,9 +2737,9 @@ void rs6000_emit_prologue_components (sbitmap components) { rs6000_stack_t *info = rs6000_stack_info (); - rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed - ? HARD_FRAME_POINTER_REGNUM - : STACK_POINTER_REGNUM); + rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed_indeed + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); machine_mode reg_mode = Pmode; int reg_size = TARGET_32BIT ? 4 : 8; @@ -2815,9 +2817,9 @@ void rs6000_emit_epilogue_components (sbitmap components) { rs6000_stack_t *info = rs6000_stack_info (); - rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed - ? HARD_FRAME_POINTER_REGNUM - : STACK_POINTER_REGNUM); + rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed_indeed + ? HARD_FRAME_POINTER_REGNUM + : STACK_POINTER_REGNUM); machine_mode reg_mode = Pmode; int reg_size = TARGET_32BIT ? 4 : 8; @@ -2996,7 +2998,10 @@ rs6000_emit_prologue (void) && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl)) == NULL)); - + + frame_pointer_needed_indeed + = frame_pointer_needed && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM); + /* Offset to top of frame for frame_reg and sp respectively. */ HOST_WIDE_INT frame_off = 0; HOST_WIDE_INT sp_off = 0; @@ -3658,7 +3663,7 @@ rs6000_emit_prologue (void) } /* Set frame pointer, if needed. */ - if (frame_pointer_needed) + if (frame_pointer_needed_indeed) { insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), sp_reg_rtx); @@ -4534,7 +4539,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) } /* If we have a frame pointer, we can restore the old stack pointer from it. */ - else if (frame_pointer_needed) + else if (frame_pointer_needed_indeed) { frame_reg_rtx = sp_reg_rtx; if (DEFAULT_ABI == ABI_V4) |