rs6000: Don't add an immediate to r0 (PR80966)
authorSegher Boessenkool <segher@kernel.crashing.org>
Fri, 9 Jun 2017 03:46:08 +0000 (05:46 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Fri, 9 Jun 2017 03:46:08 +0000 (05:46 +0200)
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 add<mode>3 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 (add<mode>3): 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
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/stack-limit.c [new file with mode: 0644]

index 64f6e15a8b9b60de0f7c81e0d4bfd699a07f0702..285d56af2802dccd0feadac6d39b3a565a8df4ec 100644 (file)
@@ -1,3 +1,12 @@
+2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/80966
+       * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that
+       gen_add3_insn did not fail.
+       * config/rs6000/rs6000.md (add<mode>3): 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  <will_schmidt@vnet.ibm.com>
 
        * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add handling
index 941c0c224b884ef9198127a2bd99c097c1810263..63ca2d12be814760f4a730054b1547faccd7a3c2 100644 (file)
@@ -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
index 1bb565a3cfe024db20e685473944426534701822..dedb2e3c193310551ea5773506fdb3e7d16d4a19 100644 (file)
                  || rtx_equal_p (operands[0], operands[1]))
                 ? operands[0] : gen_reg_rtx (<MODE>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>mode);
+         emit_insn (gen_add<mode>3 (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>mode);
index 7b0e74ab6929f922546b692612804b439f682f58..9855db5fb8ffc86e476454372a5223de215154c4 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR target/80966
+       * gcc.target/powerpc/stack-limit.c: New testcase.
+
 2017-06-08  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * 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 (file)
index 0000000..e676c96
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-options "-O0 -fstack-limit-register=r14" } */
+
+// PR80966
+
+int foo (int i)
+{
+  char arr[135000];
+
+  arr[i] = 0;
+}