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