From 120ef1d50ab7fe53a67fb2026374b2bdd67838bd Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Fri, 9 Jun 2017 05:46:08 +0200 Subject: [PATCH] rs6000: Don't add an immediate to r0 (PR80966) If there is a large stack frame the rs6000 -fstack-limit code would calculate the new stack pointer value using two insns (an addis and an addi), with r0 as temporary. Such instructions do not exist. This patch changes add3 to expand using a different strategy in such cases; to FAIL if there is no way to do it (namely, if the source is r0 and there is no way to get a temporary reg); and it changes rs6000_emit_allocate_stack to assert gen_add3_insn did in fact emit instructions. PR target/80966 * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that gen_add3_insn did not fail. * config/rs6000/rs6000.md (add3): If asked to add a constant to r0, construct that number in a temporary reg and add that reg to r0. If asked to put the result in r0 as well, fail. gcc/testsuite/ * gcc.target/powerpc/stack-limit.c: New testcase. From-SVN: r249046 --- gcc/ChangeLog | 9 +++++++++ gcc/config/rs6000/rs6000.c | 8 +++++--- gcc/config/rs6000/rs6000.md | 11 +++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/powerpc/stack-limit.c | 10 ++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/stack-limit.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 64f6e15a8b9..285d56af280 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-06-09 Segher Boessenkool + + PR target/80966 + * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that + gen_add3_insn did not fail. + * config/rs6000/rs6000.md (add3): If asked to add a constant to + r0, construct that number in a temporary reg and add that reg to r0. + If asked to put the result in r0 as well, fail. + 2017-06-08 Will Schmidt * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add handling diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 941c0c224b8..63ca2d12be8 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -27005,9 +27005,11 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) && REGNO (stack_limit_rtx) > 1 && REGNO (stack_limit_rtx) <= 31) { - emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size))); - emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, - const0_rtx)); + rtx_insn *insn + = gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)); + gcc_assert (insn); + emit_insn (insn); + emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, const0_rtx)); } else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF && TARGET_32BIT diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 1bb565a3cfe..dedb2e3c193 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1629,6 +1629,17 @@ || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (mode)); + /* Adding a constant to r0 is not a valid insn, so use a different + strategy in that case. */ + if (REGNO (operands[1]) == 0 || REGNO (tmp) == 0) + { + if (operands[0] == operands[1]) + FAIL; + rs6000_emit_move (operands[0], operands[2], mode); + emit_insn (gen_add3 (operands[0], operands[1], operands[0])); + DONE; + } + HOST_WIDE_INT val = INTVAL (operands[2]); HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, mode); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b0e74ab692..9855db5fb8f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-06-09 Segher Boessenkool + + PR target/80966 + * gcc.target/powerpc/stack-limit.c: New testcase. + 2017-06-08 Will Schmidt * testsuite/gcc.target/powerpc/fold-vec-logical-eqv-char.c: New. diff --git a/gcc/testsuite/gcc.target/powerpc/stack-limit.c b/gcc/testsuite/gcc.target/powerpc/stack-limit.c new file mode 100644 index 00000000000..e676c96eb8e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/stack-limit.c @@ -0,0 +1,10 @@ +/* { dg-options "-O0 -fstack-limit-register=r14" } */ + +// PR80966 + +int foo (int i) +{ + char arr[135000]; + + arr[i] = 0; +} -- 2.30.2