On 2020/3/28 00:04, Segher Boessenkool wrote:
Hi!
On Fri, Mar 27, 2020 at 09:34:00AM +0800, luoxhu wrote:
On 2020/3/27 07:59, Segher Boessenkool wrote:
On Wed, Mar 25, 2020 at 11:15:22PM -0500, luo...@linux.ibm.com wrote:
frame_pointer_needed is set to true in reload pass
setup_can_eliminate,
but regs_ever_live[31] is false, so pro_and_epilogue doesn't
save/restore
r31 even it is used actually, causing CPU2006 465.tonto segment
fault of
loading from invalid addresses.
If df_regs_ever_live_p(31) is false there is no hard frame pointer
anywhere in the program. How can it be used then?
There is a piece of code emit move instruction to r31 even
df_regs_ever_live_p(31) is false
in pro_and_epilogue.
Can you point out where (in rs6000-logue.c ot similar)? We should fix
*that*.
As frame_point_needed is true and frame_pointer_needed is widely
used in this function, so I propose to save r31 in save_reg_p
instead of check
(frame_pointer_needed && df_regs_ever_live_p(31), I haven't verify
whether this works yet).
Is this reasonable? Thanks.
frame_pointer_needed is often true when the backend can figure out we do
not actually need it.
rs6000-logue.c
void
rs6000_emit_prologue (void)
{
...
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 +0000 26840) /*
Set frame pointer, if needed. */
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 +0000 26841) if
(frame_pointer_needed)
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 +0000 26842) {
0d6c02bf24e4 (jakub 2005-06-30 14:26:32 +0000 26843)
insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 +0000
26844) sp_reg_rtx);
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 +0000 26845)
RTX_FRAME_RELATED_P (insn) = 1;
6b02f2a5c61e (meissner 1995-11-30 20:02:16 +0000 26846) }
d1bd513ed578 (kenner 1992-02-09 19:26:21 +0000 26847)
...
}
Ah, so this you mean. I see. It looks like if you change this to
if (frame_pointer_needed && df_regs_ever_live_p
(HARD_FRAME_POINTER_REGNUM))
{
insn = emit_move_insn (gen_rtx_REG (Pmode,
HARD_FRAME_POINTER_REGNUM),
sp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
(so just that "if" clause changes), it'll all be fine. Could you test
that please?
Tried with below patch, it still fails at same place, I guess this is
not enough.
The instruction in 100dc034 change r31 from 0x105fdd70 to
0x7fffffffbbf0 and didn't
restore it before return.
00000000100dc020 <__atomvec_module_MOD_atom_index_from_pos>:
100dc020: 51 10 40 3c lis r2,4177
100dc024: 00 7f 42 38 addi r2,r2,32512
100dc028: 28 00 e3 e8 ld r7,40(r3)
100dc02c: e1 ff 21 f8 stdu r1,-32(r1)
100dc030: 00 00 27 2c cmpdi r7,0
100dc034: 78 0b 3f 7c mr r31,r1
100dc038: 08 00 82 40 bne 100dc040
<__atomvec_module_MOD_atom_index_from_pos+0x20>
100dc03c: 01 00 e0 38 li r7,1
100dc040: 38 00 43 e9 ld r10,56(r3)
100dc044: 30 00 23 e9 ld r9,48(r3)
100dc048: 00 00 03 e9 ld r8,0(r3)
Diff:
diff --git a/gcc/config/rs6000/rs6000-logue.c
b/gcc/config/rs6000/rs6000-logue.c
index 4cbf228eb79..28fda1866d8 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -3658,7 +3658,7 @@ rs6000_emit_prologue (void)
}
/* Set frame pointer, if needed. */
- if (frame_pointer_needed)
+ if (frame_pointer_needed && df_regs_ever_live_p
(HARD_FRAME_POINTER_REGNUM))
{
insn = emit_move_insn (gen_rtx_REG (Pmode,
HARD_FRAME_POINTER_REGNUM),
sp_reg_rtx);
@@ -4534,7 +4534,8 @@ 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
+ && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM))
{
frame_reg_rtx = sp_reg_rtx;
if (DEFAULT_ABI == ABI_V4)
@@ -4873,7 +4874,8 @@ rs6000_emit_epilogue (enum epilogue_type
epilogue_type)
a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
discarded by dwarf2cfi.c/dwarf2out.c, and in any case would
be harmless if emitted. */
- if (frame_pointer_needed)
+ if (frame_pointer_needed
+ && df_regs_ever_live_p (HARD_FRAME_POINTER_REGNUM))
{
insn = get_last_insn ();
add_reg_note (insn, REG_CFA_DEF_CFA,
Program received signal SIGSEGV: Segmentation fault - invalid memory
reference.
Backtrace for this error:
#0 0x2000000a2243 in ???
#1 0x2000000a0abb in ???
#2 0x2000000604d7 in ???
#3 0x1027418c in __mol_module_MOD_make_image_of_shell
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:9376
#4 0x10281adf in __mol_module_MOD_symmetrise_r
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:9276
#5 0x10322d3b in __mol_module_MOD_symmetrise.constprop.0
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:9239
#6 0x1023d1ff in __mol_module_MOD_make_atom_density
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:12477
#7 0x1023d9a3 in __mol_module_MOD_get_atom_density
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:12434
#8 0x1023e87b in __mol_module_MOD_make_atom_guess
at
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none.0000/mol.fppized.f90:12406
#9 0x1023e87b in __mol_module_MOD_get_initial_density
Thanks,
Xionghu