Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-04-07 Thread Segher Boessenkool
Hi!

On Mon, Mar 30, 2020 at 12:18:59PM +0800, luoxhu wrote:
> >>>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*.

> >frame_pointer_needed is often true when the backend can figure out we do
> >not actually need it.

> >(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 0x7fffbbf0 
> and didn't
> restore it before return. 

So where was *that* insn generated, then?


Segher


Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-29 Thread Nicholas Krause via Gcc-patches




On 3/30/20 12:18 AM, luoxhu via Gcc-patches wrote:



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 + 26840)   /* 
Set frame pointer, if needed.  */
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26841)   if 
(frame_pointer_needed)

bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26842) {
0d6c02bf24e4 (jakub  2005-06-30 14:26:32 + 26843)   
insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 
26844)    sp_reg_rtx);
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26845)   
RTX_FRAME_RELATED_P (insn) = 1;

6b02f2a5c61e (meissner   1995-11-30 20:02:16 + 26846) }
d1bd513ed578 (kenner 1992-02-09 19:26:21 + 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 
0x7fffbbf0 and didn't

restore it before return.
100dc020 <__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  0x200a2243 in ???
#1  0x200a0abb in ???
#2  0x200604d7 in ???
#3  0x1027418c in __mol_module_MOD_make_image_of_shell
   at 
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none./mol.fppized.f90:9376


Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-29 Thread luoxhu via Gcc-patches



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 + 26840)   /* Set frame 
pointer, if needed.  */
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26841)   if 
(frame_pointer_needed)
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26842) {
0d6c02bf24e4 (jakub  2005-06-30 14:26:32 + 26843)   insn = 
emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26844)   
 sp_reg_rtx);
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26845)   
RTX_FRAME_RELATED_P (insn) = 1;
6b02f2a5c61e (meissner   1995-11-30 20:02:16 + 26846) }
d1bd513ed578 (kenner 1992-02-09 19:26:21 + 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 0x7fffbbf0 and 
didn't
restore it before return. 


100dc020 <__atomvec_module_MOD_atom_index_from_pos>:
   100dc020:   51 10 40 3c lis r2,4177
   100dc024:   00 7f 42 38 addir2,r2,32512
   100dc028:   28 00 e3 e8 ld  r7,40(r3)
   100dc02c:   e1 ff 21 f8 stdur1,-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  0x200a2243 in ???
#1  0x200a0abb in ???
#2  0x200604d7 in ???
#3  0x1027418c in __mol_module_MOD_make_image_of_shell
   at 
/home/luoxhu/workspace/cpu2006/benchspec/CPU2006/465.tonto/build/build_peak_none./mol.fppized.f90:9376
#4  0x10281adf in __mol_module_MOD_symmetrise_r
   at 

Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-27 Thread Segher Boessenkool
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 + 26840)   /* Set frame 
> pointer, if needed.  */
> bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26841)   if 
> (frame_pointer_needed)
> bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26842) {
> 0d6c02bf24e4 (jakub  2005-06-30 14:26:32 + 26843)   insn = 
> emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
> bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26844) 
>sp_reg_rtx);
> bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26845)   
> RTX_FRAME_RELATED_P (insn) = 1;
> 6b02f2a5c61e (meissner   1995-11-30 20:02:16 + 26846) }
> d1bd513ed578 (kenner 1992-02-09 19:26:21 + 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?

Thanks,


Segher


Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-26 Thread luoxhu via Gcc-patches



On 2020/3/27 07:59, Segher Boessenkool wrote:
> Hi!
> 
> 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.  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.
 
rs6000-logue.c
void
rs6000_emit_prologue (void)
{
...
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26840)   /* Set frame 
pointer, if needed.  */
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26841)   if 
(frame_pointer_needed)
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26842) {
0d6c02bf24e4 (jakub  2005-06-30 14:26:32 + 26843)   insn = 
emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26844)   
 sp_reg_rtx);
bbd21807fdf6 (geoffk 2000-03-16 03:16:41 + 26845)   
RTX_FRAME_RELATED_P (insn) = 1;
6b02f2a5c61e (meissner   1995-11-30 20:02:16 + 26846) }
d1bd513ed578 (kenner 1992-02-09 19:26:21 + 26847)
...
}

Xionghu

> 
> 
> Segher
> 



Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-26 Thread Segher Boessenkool
Hi!

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?


Segher


Re: [PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-26 Thread will schmidt via Gcc-patches
On Wed, 2020-03-25 at 23:15 -0500, luoxhu--- via Gcc-patches wrote:
> From: Xionghu Luo 
> 

Hi,
No real issues noted in my review. Patch is straighforward, just a
couple cosmetic comments inline below.


> This P1 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, 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.

Could also use a statement here that also reflects what the patch does.

"Thus, mark the register as in-use if frame_pointer_needed is true and
reg is HARD_FRAME_POINTER_REGNUM."


> Bootstrap and regression tested pass on Power8-LE.  Backport to gcc-9
> required once approved.
> 
> gcc/ChangeLog
> 
> 2020-03-26  Xiong Hu Luo  
> 
>   PR target/91518
>   * config/rs6000/rs6000-logue.c (save_reg_p): Save r31 if
>   frame_pointer_needed.


We don't actually reference 'r31' in the code change.  Maybe preferred
to refer to it as HARD_FRAME_POINTER_REGNUM instead?


> ---
>  gcc/config/rs6000/rs6000-logue.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/gcc/config/rs6000/rs6000-logue.c
> b/gcc/config/rs6000/rs6000-logue.c
> index 4cbf228eb79..7b62ff03afd 100644
> --- a/gcc/config/rs6000/rs6000-logue.c
> +++ b/gcc/config/rs6000/rs6000-logue.c
> @@ -116,6 +116,9 @@ save_reg_p (int reg)
>   return true;
>  }
> 
> +  if (reg == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
> +return true;
> +

Ok.  

>return !call_used_or_fixed_reg_p (reg) && df_regs_ever_live_p
> (reg);
>  }

Thanks
-Will




[PATCH] rs6000: Save/restore r31 if frame_pointer_needed is true

2020-03-25 Thread luoxhu--- via Gcc-patches
From: Xionghu Luo 

This P1 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, 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.

Bootstrap and regression tested pass on Power8-LE.  Backport to gcc-9
required once approved.

gcc/ChangeLog

2020-03-26  Xiong Hu Luo  

PR target/91518
* config/rs6000/rs6000-logue.c (save_reg_p): Save r31 if
frame_pointer_needed.
---
 gcc/config/rs6000/rs6000-logue.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index 4cbf228eb79..7b62ff03afd 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -116,6 +116,9 @@ save_reg_p (int reg)
return true;
 }
 
+  if (reg == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
+return true;
+
   return !call_used_or_fixed_reg_p (reg) && df_regs_ever_live_p (reg);
 }
 
-- 
2.21.0.777.g83232e3864