On Tue, Jan 02, 2018 at 01:02:26PM -0700, Jeff Law wrote:
> It's fairly obvious that the probe of *sp isn't actually necessary here
> because the register saves in the prologue act as probe points for *sp.
> 
> In fact, the only way this can ever cause problems is if %esi is used in
> the body in which case it would have been callee saved in the prologue.
> So if we detect that %esi is already callee saved in the prologue then
> we could eliminate the explicit probe of *sp.
> 
> But we can do even better.  If any register is saved in the prologue,
> then that callee register save functions as an implicit probe of *sp and
> we do not need to explicitly probe *sp.
> 
> While this was reported with -m32, I'm pretty sure we can trigger a
> similar issue on x86_64.
> 
> Bootstrapped and regression tested on x86_64.  Also verified the
> testcase behavior on -m32.  The test uses flags to hopefully ensure
> expected behavior on x86/Solaris, but I did not explicitly test that
> configuration.
> 
> OK for the trunk?
> 
> Jeff
> 

Missing
        PR target/83641
here.

>       * config/i386/i386.c (ix86_adjut_stack_and_probe_stack_clash): Do not

adjust as Florian reported.

>       explicitly probe *sp in a noreturn function if there were any callee
>       register saves.

" or frame pointer is needed" ?

> 
>       * gcc.target/i386/stack-check-17.c: New test

Missing full stop after New test

This is a nice optimization, ok for trunk.

I think we do not want to put anything into the CFI even if the condition
you've added doesn't trigger, that is a pure space and runtime cycle waste,
except for noting the sp change if it is the current CFA.  Even after the
push the register value still holds the caller's value, and after the pop
too.  ix86_emit_restore_reg_using_pop does a lot of stuff we IMNSHO don't
want to do, if dummy_reg happened to be a drap reg, we'd emit really weird
stuff, the cfa restore, etc.  There are many other spots that gen_pop
themselves and do the appropriate thing at that spot, instead of
all using ix86_emit_restore_reg_using_pop.

Ok for trunk if it passes bootstrap/regtest on x86_64 and i686-linux?

2018-01-03  Jakub Jelinek  <ja...@redhat.com>

        PR target/83641
        * config/i386/i386.c (ix86_adjust_stack_and_probe_stack_clash): For
        noreturn probe, use gen_pop instead of ix86_emit_restore_reg_using_pop,
        only set RTX_FRAME_RELATED_P on both the push and pop if cfa_reg is sp
        and add REG_CFA_ADJUST_CFA notes in that case to both insns.

--- gcc/config/i386/i386.c.jj   2018-01-03 10:20:06.495535771 +0100
+++ gcc/config/i386/i386.c      2018-01-03 12:32:01.747649506 +0100
@@ -12229,9 +12229,21 @@ ix86_adjust_stack_and_probe_stack_clash
         argument passing registers so as not to introduce dependencies in
         the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
       rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
-      rtx_insn *insn = emit_insn (gen_push (dummy_reg));
-      RTX_FRAME_RELATED_P (insn) = 1;
-      ix86_emit_restore_reg_using_pop (dummy_reg);
+      rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
+      rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
+      m->fs.sp_offset -= UNITS_PER_WORD;
+      if (m->fs.cfa_reg == stack_pointer_rtx)
+       {
+         m->fs.cfa_offset -= UNITS_PER_WORD;
+         rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
+         x = gen_rtx_SET (stack_pointer_rtx, x);
+         add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
+         RTX_FRAME_RELATED_P (insn_push) = 1;
+         x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
+         x = gen_rtx_SET (stack_pointer_rtx, x);
+         add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
+         RTX_FRAME_RELATED_P (insn_pop) = 1;
+       }
       emit_insn (gen_blockage ());
     }
 


        Jakub

Reply via email to