This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR 21144, fix endless loop in postreload
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 29 Apr 2005 20:36:56 +0200 (CEST)
- Subject: PR 21144, fix endless loop in postreload
Hi,
this patch fixes the above problem report. My analysis from the PR:
The problem is in reload_cse_move2add. It has such a loop:
for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
narrow_mode != GET_MODE (reg);
narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
{
where 'reg' comes from a simple SET insn. In this testcase the insn is:
(set (reg:BI r15) (const_int 1))
note the mode of reg being BImode. Now, BImode is in fact a
FRACTIONAL_INT_MODE, not an INT_MODE (although GET_MODE_CLASS would return
INT_MODE, so using this instead of hard-coded INT_MODE wouldn't help).
And GET_CLASS_NARROWEST_MODE(INT_MODE) is QImode, as it will ignore modes
with precision 1 bit in genmodes.c (I think because the rest of the
compiler is not prepared to really see an BImode here, but I may be wrong,
there are not that many instance of GET_CLASS_NARROWEST_MODE and most look
safe, but will iterate one more time uselessly if started from BImode).
So, this loop starts with QImode, widens the mode each time, and waits for
it to become equal to the mode of 'reg', i.e. BImode. This of course
never happens, so somewhen it is VOIDmode, and that's the fixed point
of GET_CLASS_NARROWEST_MODE. So we are endlessly looping.
I've regtested the patch on {i686,ppc,ia64,x86_64,s390,s390x,ppc64}-linux
without regressions. I was not able to reduce the testcase significantly.
Removing too many of the statements in the affected function made the
problem go away. So this is without testcase :-(
As Jim Wilson approved the patch in the bugzilla already, I've committed
it to 4.0 branch and trunk.
Ciao,
Michael.
--
PR rtl-optimization/21144
* postreload.c (reload_cse_move2add): Check for VOIDmode.
--- gcc-4.0.1-20050424/gcc/postreload.c.mm 2005-01-18 13:11:48.000000000 +0100
+++ gcc-4.0.1-20050424/gcc/postreload.c 2005-04-25 15:10:45.566341341 +0200
@@ -1273,7 +1273,8 @@ reload_cse_move2add (rtx first)
{
enum machine_mode narrow_mode;
for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
- narrow_mode != GET_MODE (reg);
+ narrow_mode != VOIDmode
+ && narrow_mode != GET_MODE (reg);
narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
{
if (have_insn_for (STRICT_LOW_PART, narrow_mode)