This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix several endless loops in cse_insn for certain targettypes combinations
- From: Igor Shevlyakov <igor at microunity dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 16 May 2005 21:04:56 -0700
- Subject: [PATCH] Fix several endless loops in cse_insn for certain targettypes combinations
I'm working on my own target which my company is not ready to sumbit
back yet.
After merging my back-end into gcc 4.0 tree I had multiple hangs of the
compiler during libgcc build.
I found several places in cse.c with similar code which supposed to be
iterating class of type modes:
for (wider_mode = GET_MODE_WIDER_MODE (mode);
GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
&& src_related == 0;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
But in a situation when widest mode in a class as wide as BITS_PER_WORD
(like in my case registers are 128 bits and largest mode we use is
TImode), this loop will never stop. So there should be an extra check
that VOIDmode is reached.
I couldn't provide a testcase because it's not a case for any back-end
currently in the tree, but I hope that my explanation is clear enough
and changes are very staight-forward.
I'm attaching two patch files. One agains the 4.0.0 release sources and
another one againts current developmenty branch.
Thanks,
Igor Shevlyakov
Microunity, Inc.
Index: cse.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cse.c,v
retrieving revision 1.354
diff -c -3 -p -r1.354 cse.c
*** cse.c 22 Apr 2005 16:14:52 -0000 1.354
--- cse.c 17 May 2005 03:04:04 -0000
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5169,5174 ****
--- 5169,5175 ----
for (wider_mode = GET_MODE_WIDER_MODE (mode);
GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
+ && wider_mode != VOIDmode
&& src_related == 0;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
{
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5203,5209 ****
rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
tmode = GET_MODE_WIDER_MODE (tmode))
{
rtx inner = gen_lowpart (tmode, XEXP (src, 0));
--- 5204,5211 ----
rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
rtx inner = gen_lowpart (tmode, XEXP (src, 0));
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5255,5261 ****
XEXP (memory_extend_rtx, 0) = src;
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
tmode = GET_MODE_WIDER_MODE (tmode))
{
struct table_elt *larger_elt;
--- 5257,5264 ----
XEXP (memory_extend_rtx, 0) = src;
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
struct table_elt *larger_elt;
2005-05-16 Igor Shevlyakov <igor@microunity.com>
* cse.c (cse_insn): Alternative check for the end of a class
of modes. Prevents endless loop when largest mode have a size
of BITS_PER_WORD.
Index: cse.c
===================================================================
RCS file: /p/cvsroot/gnu-new/gcc/cse.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 cse.c
*** cse.c 27 Apr 2005 22:51:48 -0000 1.1.1.1
--- cse.c 10 May 2005 21:17:27 -0000
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5180,5185 ****
--- 5180,5186 ----
for (wider_mode = GET_MODE_WIDER_MODE (mode);
GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
+ && wider_mode != VOIDmode
&& src_related == 0;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
{
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5214,5220 ****
rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
tmode = GET_MODE_WIDER_MODE (tmode))
{
rtx inner = gen_lowpart (tmode, XEXP (src, 0));
--- 5215,5222 ----
rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
rtx inner = gen_lowpart (tmode, XEXP (src, 0));
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5266,5272 ****
XEXP (memory_extend_rtx, 0) = src;
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
tmode = GET_MODE_WIDER_MODE (tmode))
{
struct table_elt *larger_elt;
--- 5268,5275 ----
XEXP (memory_extend_rtx, 0) = src;
for (tmode = GET_MODE_WIDER_MODE (mode);
! GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
struct table_elt *larger_elt;