diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 64f6e15a8b9b..285d56af2802 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 941c0c224b88..63ca2d12be81 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 1bb565a3cfe0..dedb2e3c1933 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 7b0e74ab6929..9855db5fb8ff 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 000000000000..e676c96eb8e6 --- /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; +}