re PR target/67260 ([sh] Register spill bug for sibcall+complex+softfloat)
authorOleg Endo <olegendo@gcc.gnu.org>
Sat, 13 Feb 2016 08:03:44 +0000 (08:03 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Sat, 13 Feb 2016 08:03:44 +0000 (08:03 +0000)
gcc/
PR target/67260
* config/sh/sh.md (sibcall_value_pcrel): Replace =&k scratch reg with
fixed R1_REG scratch reg.
(sibcall_value_pcrel_fdpic): Likewise.

gcc/testsuite/
PR target/67260
* gcc.target/sh/torture/pr67260.c: New.

From-SVN: r233399

gcc/ChangeLog
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/torture/pr67260.c [new file with mode: 0644]

index de5a749dc76a0e5d2e67b53f4d784efe057ec029..0fce0c3bfe00577462f0dcddb52a5a8c8b7bb69d 100644 (file)
@@ -1,3 +1,10 @@
+2016-02-13  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/67260
+       * config/sh/sh.md (sibcall_value_pcrel): Replace =&k scratch reg with
+       fixed R1_REG scratch reg.
+       (sibcall_value_pcrel_fdpic): Likewise.
+
 2016-02-13  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/67636
index b5b0f9573b7165303fb17a9c58e956922ceadffa..9fa835b1a29d73625d54ea77d831e07eaf790767 100644 (file)
@@ -10476,12 +10476,16 @@ label:
                      (const_string "single") (const_string "double")))
    (set_attr "type" "jump_ind")])
 
+;; sibcall_value_pcrel used to have a =&k clobber for the scratch register
+;; that it needs for the branch address.  This causes troubles when there
+;; is a big overlap of argument and return value registers.  Hence, use a
+;; fixed call clobbered register for the address.  See also PR 67260.
 (define_insn_and_split "sibcall_value_pcrel"
   [(set (match_operand 0 "" "=rf")
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
              (match_operand 2 "" "")))
    (use (reg:SI FPSCR_MODES_REG))
-   (clobber (match_scratch:SI 3 "=&k"))
+   (clobber (reg:SI R1_REG))
    (return)]
   "TARGET_SH2 && !TARGET_FDPIC"
   "#"
@@ -10491,6 +10495,8 @@ label:
   rtx lab = PATTERN (gen_call_site ());
   rtx call_insn;
 
+  operands[3] =  gen_rtx_REG (SImode, R1_REG);
+
   sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
                                                        operands[3],
@@ -10505,13 +10511,15 @@ label:
                      (const_string "single") (const_string "double")))
    (set_attr "type" "jump_ind")])
 
+;; Like for sibcall_value_pcrel, use a fixed call clobbered register for
+;; the branch address.
 (define_insn_and_split "sibcall_value_pcrel_fdpic"
   [(set (match_operand 0 "" "=rf")
        (call (mem:SI (match_operand:SI 1 "symbol_ref_operand"))
              (match_operand 2)))
    (use (reg:SI FPSCR_MODES_REG))
    (use (reg:SI PIC_REG))
-   (clobber (match_scratch:SI 3 "=k"))
+   (clobber (reg:SI R1_REG))
    (return)]
   "TARGET_SH2 && TARGET_FDPIC"
   "#"
@@ -10520,6 +10528,8 @@ label:
 {
   rtx lab = PATTERN (gen_call_site ());
 
+  operands[3] =  gen_rtx_REG (SImode, R1_REG);
+
   sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
   rtx i = emit_call_insn (gen_sibcall_valuei_pcrel_fdpic (operands[0],
                                                          operands[3],
index a949c955e29f5dc072d58f80b782ff5fbca10144..0acf5311f2f5b255de5a8fa9a31a8ccd77ee05bd 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-13  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/67260
+       * gcc.target/sh/torture/pr67260.c: New.
+
 2016-02-12  John David Anglin  <danglin@gcc.gnu.org>
 
        * gcc.dg/pr67964.c: Add dg-require-alias.
diff --git a/gcc/testsuite/gcc.target/sh/torture/pr67260.c b/gcc/testsuite/gcc.target/sh/torture/pr67260.c
new file mode 100644 (file)
index 0000000..7bd176e
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-additional-options "-std=gnu99" }  */
+/* { dg-do compile }  */
+
+#pragma GCC visibility push(hidden)
+
+double _Complex foo (double _Complex arg);
+
+double _Complex
+bar (double _Complex arg)
+{
+  return foo (arg);
+}