diff options
author | Kaz Kojima <kkojima@gcc.gnu.org> | 2011-06-09 22:19:20 +0000 |
---|---|---|
committer | Kaz Kojima <kkojima@gcc.gnu.org> | 2011-06-09 22:19:20 +0000 |
commit | af178dafbc61519926b7c088300075daae0118cd (patch) | |
tree | e7be741c2a5488c3f87639712e372da005bda062 | |
parent | bf806a90c9e000332733ad76e92b1554f740829f (diff) | |
download | gcc-af178dafbc61519926b7c088300075daae0118cd.zip gcc-af178dafbc61519926b7c088300075daae0118cd.tar.gz gcc-af178dafbc61519926b7c088300075daae0118cd.tar.bz2 |
re PR target/49307 (ICE in spill_failure, at reload1.c:2113)
PR target/49307
* config/sh/sh.md (UNSPEC_CHKADD): New.
(chk_guard_add): New define_insn_and_split.
(symGOT_load): Use chk_guard_add instead of blockage.
* gcc.dg/pr49307.c: New.
From-SVN: r174861
-rw-r--r-- | gcc/config/sh/sh.md | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr49307.c | 21 |
3 files changed, 49 insertions, 7 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index dd63f63..e261d33 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -150,6 +150,7 @@ (UNSPEC_DIV_INV_TABLE 37) (UNSPEC_ASHIFTRT 35) (UNSPEC_THUNK 36) + (UNSPEC_CHKADD 38) (UNSPEC_SP_SET 40) (UNSPEC_SP_TEST 41) (UNSPEC_MOVUA 42) @@ -8454,6 +8455,22 @@ label: i++; }") +;; op0 = op1 + r12 but hide it before reload completed. See the comment +;; in symGOT_load expand. + +(define_insn_and_split "chk_guard_add" + [(set (match_operand:SI 0 "register_operand" "=&r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r") + (reg:SI PIC_REG)] + UNSPEC_CHKADD))] + "TARGET_SH1" + "#" + "TARGET_SH1 && reload_completed" + [(set (match_dup 0) (reg:SI PIC_REG)) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] + "" + [(set_attr "type" "arith")]) + (define_expand "sym_label2reg" [(set (match_operand:SI 0 "" "") (const:SI (unspec:SI [(match_operand:SI 1 "" "") @@ -8496,13 +8513,9 @@ label: else emit_move_insn (operands[2], operands[1]); - emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, - operands[2], - gen_rtx_REG (Pmode, PIC_REG))); - /* When stack protector inserts codes after the result is set to - R0, @(rX, r12) will cause a spill failure for R0. Don't schedule - insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A)) + R0, @(rX, r12) will cause a spill failure for R0. Use a unspec + insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A)) when rX is a GOT address for the guard symbol. Ugly but doesn't matter because this is a rare situation. */ if (!TARGET_SHMEDIA @@ -8512,7 +8525,10 @@ label: && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0), \"__stack_chk_guard\") == 0) - emit_insn (gen_blockage ()); + emit_insn (gen_chk_guard_add (operands[3], operands[2])); + else + emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2], + gen_rtx_REG (Pmode, PIC_REG))); /* N.B. This is not constant for a GOTPLT relocation. */ mem = gen_rtx_MEM (Pmode, operands[3]); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f84baa1..fa1fec8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-06-09 Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/49307 + * gcc.dg/pr49307.c: New. + 2011-06-09 Wei Guozhi <carrot@google.com> PR target/46975 diff --git a/gcc/testsuite/gcc.dg/pr49307.c b/gcc/testsuite/gcc.dg/pr49307.c new file mode 100644 index 0000000..e05659a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr49307.c @@ -0,0 +1,21 @@ +/* PR target/49307 */ +/* { dg-do compile } */ +/* { dg-options "-O -fpic -fstack-protector" } */ +/* { dg-require-effective-target fpic } */ +/* { dg-require-effective-target fstack_protector } */ + +extern void bar (char **pp, void *vp); +extern void free (void *p); + +int +foo (void) +{ + char *p; + char fext[128]; + + p = fext; + bar (&p, (void *)0); + if (p) + free (p); + return 0; +} |