[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