diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2016-02-13 08:03:44 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2016-02-13 08:03:44 +0000 |
commit | 6cda3ab6615347beffbeef3d296d9b49d530e50d (patch) | |
tree | b1b5cf03c5d5f6988deec65ac51e4787d536938c | |
parent | 6786e598faebc3585c3ecec1ec4408946e897dfa (diff) | |
download | gcc-6cda3ab6615347beffbeef3d296d9b49d530e50d.zip gcc-6cda3ab6615347beffbeef3d296d9b49d530e50d.tar.gz gcc-6cda3ab6615347beffbeef3d296d9b49d530e50d.tar.bz2 |
re PR target/67260 ([sh] Register spill bug for sibcall+complex+softfloat)
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/sh/torture/pr67260.c | 12 |
4 files changed, 36 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de5a749..0fce0c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 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 PR target/64345 * config/sh/sh.md (*zero_extract_3): New insn_and_split pattern. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index b5b0f95..9fa835b 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -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], diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a949c95..0acf531 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..7bd176e --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/torture/pr67260.c @@ -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); +} |