From c006911de91ca9e23d7d2df069499c768d215eac Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 7 Feb 2020 11:09:03 +0100 Subject: [PATCH] powerpc: Fix -fstack-clash-protection -mprefixed-addr ICE [PR93122] 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 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 | 8 +++++ gcc/config/rs6000/rs6000-logue.c | 36 +++++++++++++++------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/powerpc/pr93122.c | 12 ++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr93122.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e56eaba7327..a7babd25be4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2020-02-07 Jakub Jelinek + 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_1): Remove. diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index 0db53d8375a..fecc3e6f780 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bec80b2a94f..0c21d75dc16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-07 Jakub Jelinek + + PR target/93122 + * gcc.target/powerpc/pr93122.c: New test. + 2020-02-07 Paolo Carlini 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 index 00000000000..158e6788edb --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr93122.c @@ -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); +} -- 2.30.2