powerpc: Fix -fstack-clash-protection -mprefixed-addr ICE [PR93122]
authorJakub Jelinek <jakub@redhat.com>
Fri, 7 Feb 2020 10:09:03 +0000 (11:09 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 7 Feb 2020 10:12:22 +0000 (11:12 +0100)
As mentioned in the PR, the following testcase ICEs because rs, while valid
add_operand is not valid add_cint_operand and so gen_add3_insn fails,
because it doesn't meet the expander predicates.

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).

2020-02-07  Jakub Jelinek  <jakub@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/ChangeLog
gcc/config/rs6000/rs6000-logue.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr93122.c [new file with mode: 0644]

index e56eaba..a7babd2 100644 (file)
@@ -1,5 +1,13 @@
 2020-02-07  Jakub Jelinek  <jakub@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.
+
        PR target/93594
        * config/i386/predicates.md (avx_identity_operand): Remove.
        * config/i386/sse.md (*avx_vec_concat<mode>_1): Remove.
index 0db53d8..fecc3e6 100644 (file)
@@ -1604,20 +1604,34 @@ rs6000_emit_probe_stack_range_stack_clash (HOST_WIDE_INT orig_size,
       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));
+      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);
+       }
+      bool add_note = false;
+      if (!NONJUMP_INSN_P (insn) || NEXT_INSN (insn))
+       add_note = true;
       else
        {
-         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.  */
-         add_reg_note (insn, REG_FRAME_RELATED_EXPR,
-                       gen_rtx_SET (end_addr,
-                                    gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-                                                  rs)));
+         rtx set = single_set (insn);
+         if (set == 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)
+           add_note = true;
        }
+      insn = emit_insn (insn);
+      /* Describe the effect of INSN to the CFI engine, unless it
+        is a single insn that describes it itself.  */
+      if (add_note)
+       add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+                     gen_rtx_SET (end_addr,
+                                  gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+                                                rs)));
       RTX_FRAME_RELATED_P (insn) = 1;
 
       /* Emit the loop.  */
index bec80b2..0c21d75 100644 (file)
@@ -1,3 +1,8 @@
+2020-02-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/93122
+       * gcc.target/powerpc/pr93122.c: New test.
+
 2020-02-07  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/89404
diff --git a/gcc/testsuite/gcc.target/powerpc/pr93122.c b/gcc/testsuite/gcc.target/powerpc/pr93122.c
new file mode 100644 (file)
index 0000000..158e678
--- /dev/null
@@ -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);
+}