On Wed, Jan 22, 2020 at 03:24:54PM +0100, Jakub Jelinek wrote:
> > It looks like your patch will pessimise code in some cases as well, btw?
> 
> No, it will solely turn previous wrong-codes into something that works
> (== cases where gen_addr3_insn would previously fail).
> The 1)+2) variant could even improve code, as gen_addr3_insn could succeed
> even if we currently don't call it (perhaps generate more than one insn,
> but it still might be better than forcing the constant into register and
> then performing add that way).

Here is what I meant as the alternative, i.e. don't check any predicates,
just gen_add3_insn, if that fails, force rs into register and retry.
And, add REG_FRAME_RELATED_EXPR note always when we haven't emitted a single
insn that has rtl exactly matching what we'd add the REG_FRAME_RELATED_EXPR
with (in that case, dwarf2cfi.c is able to figure it out by itself, no need
to waste compile time memory).

Ok for trunk if it passes bootstrap/regtest?

2020-01-30  Jakub Jelinek  <ja...@redhat.com>

        PR target/93122
        * config/rs6000/rs6000-logue.c
        (rs6000_emit_probe_stack_range_stack_clash): Always use gen_add3_insn,
        if it fails, move rs into end_addr and retry.  Add
        REG_FRAME_RELATED_EXPR note whenever it returns more than one insn or
        the insn pattern doesn't describe well what exactly happens to
        dwarf2cfi.c.

        * gcc.target/powerpc/pr93122.c: New test.

--- gcc/config/rs6000/rs6000-logue.c.jj 2020-01-12 11:54:36.395413680 +0100
+++ gcc/config/rs6000/rs6000-logue.c    2020-01-30 16:54:28.646943559 +0100
@@ -1604,20 +1604,32 @@ rs6000_emit_probe_stack_range_stack_clas
       rtx end_addr
        = copy_reg ? gen_rtx_REG (Pmode, 0) : gen_rtx_REG (Pmode, 12);
       rtx rs = GEN_INT (-rounded_size);
-      rtx_insn *insn;
-      if (add_operand (rs, Pmode))
-       insn = emit_insn (gen_add3_insn (end_addr, stack_pointer_rtx, rs));
-      else
+      rtx_insn *insn = gen_add3_insn (end_addr, stack_pointer_rtx, rs);
+      if (insn == NULL)
+       {
+         emit_move_insn (end_addr, rs);
+         insn = gen_add3_insn (end_addr, end_addr, stack_pointer_rtx);
+         gcc_assert (insn);
+       }
+      rtx set;
+      if (!NONJUMP_INSN_P (insn)
+         || NEXT_INSN (insn)
+         || (set = single_set (insn)) == NULL_RTX
+         || SET_DEST (set) != end_addr
+         || GET_CODE (SET_SRC (set)) != PLUS
+         || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
+         || XEXP (SET_SRC (set), 1) != rs)
        {
-         emit_move_insn (end_addr, GEN_INT (-rounded_size));
-         insn = emit_insn (gen_add3_insn (end_addr, end_addr,
-                                          stack_pointer_rtx));
-         /* Describe the effect of INSN to the CFI engine.  */
+         insn = emit_insn (insn);
+         /* Describe the effect of INSN to the CFI engine, unless it
+            is a single insn that describes it itself.  */
          add_reg_note (insn, REG_FRAME_RELATED_EXPR,
                        gen_rtx_SET (end_addr,
                                     gen_rtx_PLUS (Pmode, stack_pointer_rtx,
                                                   rs)));
        }
+      else
+       insn = emit_insn (insn);
       RTX_FRAME_RELATED_P (insn) = 1;
 
       /* Emit the loop.  */
--- gcc/testsuite/gcc.target/powerpc/pr93122.c.jj       2020-01-30 
16:42:14.255927311 +0100
+++ gcc/testsuite/gcc.target/powerpc/pr93122.c  2020-01-30 16:42:14.255927311 
+0100
@@ -0,0 +1,12 @@
+/* PR target/93122 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-fstack-clash-protection -mprefixed-addr -mfuture" } */
+
+void bar (char *);
+
+void
+foo (void)
+{
+  char s[4294967296];
+  bar (s);
+}


        Jakub

Reply via email to