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

Reply via email to