[Bug target/22553] [4.6/4.7/4.8 regression] ICE building libstdc++

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Nov 9 21:44:00 GMT 2012


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

--- Comment #26 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-11-09 21:44:16 UTC ---
I've tried enabling sched1 on rev 193341 and ran the test suite with
make -k -j4 check
RUNTESTFLAGS="--target_board=sh-sim\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"

I got one failure for -m2a, -m4 -m4a (both, -ml and -mb):

FAIL: gcc.dg/pr42475.c (internal compiler error)

The error is:
sh_tmp.cpp: In function 'baz':
sh_tmp.cpp:25:1: error: unable to find a register to spill in class 'R0_REGS'
 }
 ^
sh_tmp.cpp:25:1: error: this is the insn:
(insn 18 31 42 2 (parallel [
            (set (subreg:SF (reg:SI 1 r1 [orig:174 D.1383+4 ] [174]) 0)
                (mult:SF (reg:SF 171)
                    (reg:SF 65 fr1 [orig:170 p.c.z ] [170])))
            (use (reg/v:PSI 151 ))
        ]) sh_tmp.cpp:24 426 {mulsf3_i}
     (expr_list:REG_DEAD (reg:SF 171)
        (expr_list:REG_DEAD (reg:SF 65 fr1 [orig:170 p.c.z ] [170])
            (expr_list:REG_DEAD (reg/v:PSI 151 )
                (nil)))))
sh_tmp.cpp:25:1: internal compiler error: in spill_failure, at reload1.c:2124

A GP reg is supposed to receive the result of an FP operation, which the SH
actually can't do.  It has to go through FPUL.
The error occurs because sched1 hoists a load of r0 (part of the return value)
before the failing insn:

(insn 31 15 18 2 (set (reg:SI 0 r0)
        (const_int 0 [0])) sh_tmp.cpp:25 244 {movsi_ie}
     (nil))
(insn 18 31 42 2 (parallel [
            (set (subreg:SF (reg:SI 174 [ D.1383+4 ]) 0)
                (mult:SF (reg:SF 170 [ p.c.z ])
                    (reg:SF 171)))
....

The result value transfer from FP reg to GP reg (through FPUL) seems to go a
long way during reload, and one the insns that reload checks has a R0 clobber
(not sure which one, but there are a couple of reload insns with a =&z
constraint).

On option to fix this is to split such insns.  The patch below fixes the test
case failure, but I haven't re-tested it completely.


Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md    (revision 193342)
+++ gcc/config/sh/sh.md    (working copy)
@@ -12077,6 +12077,32 @@
   [(set_attr "type" "fp")
    (set_attr "fp_mode" "single")])

+;; If the output of a floating-point operation is to be stored in a GP reg
+;; the target GP output reg might be propagated as a subreg into floating-
+;; point insns.  If we split the operation and the GP reg store
+;; (through FPUL) into separate insns before reload some trouble can be
+;; avoided during reload.
+(define_split
+  [(set (match_operand:SF 0 "fp_arith_reg_operand")
+    (match_operator:SF 1 "float_operator"
+      [(match_operand:SF 2 "fp_arith_reg_operand")
+       (match_operand:SF 3 "fp_arith_reg_operand")]))
+   (use (match_operand:PSI 4 "fpscr_operand"))]
+  "TARGET_SH2E
+   && can_create_pseudo_p () && GET_CODE (operands[0]) == SUBREG
+   && REG_P (SUBREG_REG (operands[0]))
+   && GET_MODE (SUBREG_REG (operands[0])) != SFmode"
+  [(parallel [(set (match_dup 5) (match_dup 6))
+          (use (match_dup 4))])
+   (parallel [(set (match_dup 0) (match_dup 5))
+          (use (match_dup 4))
+          (clobber (reg:SI FPUL_REG))])]
+{
+  operands[5] = gen_reg_rtx (SFmode);
+  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SFmode, operands[2],
+                operands[3]);
+})
+
 ;; FMA (fused multiply-add) patterns
 (define_expand "fmasf4"
   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
Index: gcc/config/sh/predicates.md
===================================================================
--- gcc/config/sh/predicates.md    (revision 193342)
+++ gcc/config/sh/predicates.md    (working copy)
@@ -1156,3 +1156,9 @@

   return false;
 })
+
+(define_predicate "float_operator"
+  (ior (match_operand 0 "binary_float_operator")
+       (match_operand 0 "commutative_float_operator")
+       (match_operand 0 "noncommutative_float_operator")
+       (match_operand 0 "unary_float_operator")))
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c    (revision 193342)
+++ gcc/config/sh/sh.c    (working copy)
@@ -877,6 +877,7 @@
       || (TARGET_SHMEDIA && !TARGET_PT_FIXED))
     flag_no_function_cse = 1;

+#if 0
   if (targetm.small_register_classes_for_mode_p (VOIDmode))        \
     {
       /* Never run scheduling before reload, since that can
@@ -903,6 +904,7 @@
            && !global_options_set.x_flag_schedule_insns)
     flag_schedule_insns = 0;
     }
+#endif

   /* Unwind info is not correct around the CFG unless either a frame
      pointer is present or M_A_O_A is set.  Fixing this requires rewriting



More information about the Gcc-bugs mailing list