[Bug target/49307] [4.5/4.6/4.7 Regression] ICE in spill_failure, at reload1.c:2113

kkojima at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jun 8 00:16:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49307

Kazumoto Kojima <kkojima at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice-on-valid-code
                 CC|                            |kkojima at gcc dot gnu.org

--- Comment #2 from Kazumoto Kojima <kkojima at gcc dot gnu.org> 2011-06-08 00:16:35 UTC ---
I think this is similar to PR target/32163.  The testcase in
that PR fails by a very similar way for 4.5/4.6/4.7.  It seems that
now the IRA pass combines

  reg = __stack_chk_guard@GOT
  A = reg + r12
  B = mem[A]

to

  reg = __stack_chk_guard@GOT
  B = mem[reg + r12]

and the blockage insn we used in the fix of PR32163 is no use
for the transformation IRA does.  I'm testing the patch below
which uses a unspec and a define_insn_and_split to hide reg + r12
from the early passes.

--- ORIG/trunk/gcc/config/sh/sh.md    2010-08-28 13:32:01.000000000 +0900
+++ trunk/gcc/config/sh/sh.md    2011-06-08 07:52:26.000000000 +0900
@@ -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,11 @@ 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]);



More information about the Gcc-bugs mailing list