OSDN Git Service

PR target/49307
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Jun 2011 22:19:20 +0000 (22:19 +0000)
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Jun 2011 22:19:20 +0000 (22:19 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@174861 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr49307.c [new file with mode: 0644]

index dd63f63..e261d33 100644 (file)
   (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]);
index f84baa1..fa1fec8 100644 (file)
@@ -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 (file)
index 0000000..e05659a
--- /dev/null
@@ -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;
+}