[Bug rtl-optimization/55294] New: Invalid RTL sharing in lower-subreg

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Nov 12 21:53:00 GMT 2012


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: unassigned@gcc.gnu.org
        ReportedBy: olegendo@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 */
  }



More information about the Gcc-bugs mailing list