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 */ }