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



             Bug #: 55294

           Summary: Invalid RTL sharing in lower-subreg

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: rtl-optimization

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: olege...@gcc.gnu.org

            Target: sh*-*-*





I ran into this one while trying out a couple of things on rev 193423 in the SH

backend.



What I did was to disallow SF subregs of integer regs/pseudos in the

'fp_arith_reg_operand' predicate, like that:



Index: gcc/config/sh/predicates.md

===================================================================

--- gcc/config/sh/predicates.md    (revision 193423)

+++ gcc/config/sh/predicates.md    (working copy)

@@ -319,16 +319,24 @@

   if (register_operand (op, mode))

     {

       int regno;

+      machine_mode m;



       if (REG_P (op))

-    regno = REGNO (op);

+    {

+      regno = REGNO (op);

+      m = GET_MODE (op);

+    }

       else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))

-    regno = REGNO (SUBREG_REG (op));

+    {

+      regno = REGNO (SUBREG_REG (op));

+      m = GET_MODE (SUBREG_REG (op));

+    }

       else

     return 1;



-      return (regno >= FIRST_PSEUDO_REGISTER

-          || FP_REGISTER_P (regno));

+      return (regno >= FIRST_PSEUDO_REGISTER || FP_REGISTER_P (regno))

+         && (GET_MODE_CLASS (m) == MODE_FLOAT

+         || GET_MODE_CLASS (m) == MODE_VECTOR_FLOAT);

     }

   return 0;

 })



... to avoid operands such as 'subreg:SF (reg:SI)'.  On SH FP values might end

up in GP regs (in particular FP vectors .. see e.g. PR 13423) and have to be

loaded into FP regs first.  This is currently done during/by reload, but there

are some cases where this causes trouble.  Doing the GP -> FP reg copies before

reload seems to be a bit better.

After applying the patch above, the following code:



typedef float V2SF __attribute__ ((vector_size (8)));



V2SF

foo (V2SF a, float x, float y)

{

  return a * (V2SF) { x, y };

}



compiled with -m4 -O2, makes the lower-subreg 2 pass transform the two insns:



(insn 23 7 24 2 (parallel [

            (set (reg:SF 174 [ D.1360 ])

                (mult:SF (reg:SF 69 fr5 [ x ])

                    (subreg:SF (reg/v:V2SF 167 [ a ]) 0)))

            (use (reg/v:PSI 151 ))

        ]) sh_tmp.cpp:7 426 {mulsf3_i}

     (expr_list:REG_DEAD (reg:SF 69 fr5 [ x ])

        (nil)))



...



(insn 27 24 28 2 (parallel [

            (set (reg:SF 177 [ D.1360 ])

                (mult:SF (reg:SF 68 fr4 [ y ])

                    (subreg:SF (reg/v:V2SF 167 [ a ]) 4)))

            (use (reg/v:PSI 151 ))

        ]) sh_tmp.cpp:7 426 {mulsf3_i}

     (expr_list:REG_DEAD (reg/v:V2SF 167 [ a ])

        (expr_list:REG_DEAD (reg:SF 68 fr4 [ y ])

            (nil))))



into:



(insn 23 7 24 2 (parallel [

            (set (reg:SF 174 [ D.1360 ])

                (mult:SF (reg:SF 69 fr5 [ x ])

                    (subreg:SF (concatn/v:V2SF [

                                (reg:SI 191 [ a ])

                                (reg:SI 192 [ a+4 ])

                            ]) 0)))

            (use (reg/v:PSI 151 ))

        ]) sh_tmp.cpp:7 426 {mulsf3_i}

     (expr_list:REG_DEAD (reg:SF 69 fr5 [ x ])

        (nil)))



...



(insn 27 24 28 2 (parallel [

            (set (reg:SF 177 [ D.1360 ])

                (mult:SF (reg:SF 68 fr4 [ y ])

                    (subreg:SF (concatn/v:V2SF [

                                (reg:SI 191 [ a ])

                                (reg:SI 192 [ a+4 ])

                            ]) 4)))

            (use (reg/v:PSI 151 ))

        ]) sh_tmp.cpp:7 426 {mulsf3_i}

     (expr_list:REG_DEAD (reg:SF 68 fr4 [ y ])

        (nil)))



.. which results in an invalid rtl sharing:



sh_tmp.cpp:8:1: error: shared rtx

(concatn/v:V2SF [

        (reg:SI 191 [ a ])

        (reg:SI 192 [ a+4 ])

    ])

sh_tmp.cpp:8:1: internal compiler error: internal consistency failure





Note: I had to disable the assert in lower-subreg.c:1582 to get this info,

because the assert would actually trigger before it gets to the rtl sharing

checks.  The original call stack is:



sh_tmp.cpp: In function 'foo':

sh_tmp.cpp:8:1: internal compiler error: in decompose_multiword_subregs, at

lower-subreg.c:1582

 }

 ^

0x89184f5 decompose_multiword_subregs

    ../../gcc-trunk2/gcc/lower-subreg.c:1582

0x89185ac rest_of_handle_lower_subreg2

    ../../gcc-trunk2/gcc/lower-subreg.c:1659

Please submit a full bug report,



I've attached the logs of the split1 pass before subreg2 and the log of the

subreg2 pass which I got after applying this:



Index: gcc/lower-subreg.c

===================================================================

--- gcc/lower-subreg.c    (revision 193423)

+++ gcc/lower-subreg.c    (working copy)

@@ -1579,7 +1579,7 @@

             }



               i = apply_change_group ();

-              gcc_assert (i);

+//              gcc_assert (i);

             }

         }

         }

@@ -1697,7 +1697,7 @@

   0,                                    /* properties_provided */

   0,                                    /* properties_destroyed */

   0,                                    /* todo_flags_start */

-  TODO_df_finish | TODO_verify_rtl_sharing |

+  TODO_df_finish /*| TODO_verify_rtl_sharing */|

   TODO_ggc_collect |

   TODO_verify_flow                      /* todo_flags_finish */

  }

Reply via email to