------- Comment #10 from law at redhat dot com  2006-03-13 22:14 -------
Subject: Re:  [4.2 Regression] FAIL:
        gfortran.dg/g77/20010610.f  -O3 -fomit-frame-pointer -funroll-loops

On Wed, 2006-03-08 at 00:07 +0000, janis at gcc dot gnu dot org wrote: 
> 
> ------- Comment #5 from janis at gcc dot gnu dot org  2006-03-08 00:07 -------
> A regression hunt on powerpc64-linux using the C test case from comment #4
> identified this patch:
> 
> http://gcc.gnu.org/viewcvs?view=rev&rev=110705
> 
> r110705 | law | 2006-02-07 18:31:27 +0000 (Tue, 07 Feb 2006)
> 
> 
> That date doesn't match up with when the Fortran test started failing so I ran
> another regression hunt using it, which identified this patch:
> 
> http://gcc.gnu.org/viewcvs?view=rev&rev=108425
> 
> r108425 | law | 2005-12-12 19:59:16 +0000 (Mon, 12 Dec 2005)
> 

Zdenek -- can you take a closer look at this -- you're a lot more
familiar with the loop unroller than I am.

This bugzilla entry has two testcases which ICE in the "new"
unrolling code at least two platforms (PA64, PPC64).

In analyze_iv_to_split_insn we have:

  ok = iv_analyze_result (insn, dest, &iv);
  gcc_assert (ok);


>From reading loop-unroll.c, I believe that we could safely have
analyze_iv_to_split_insn return NULL instead of aborting when
iv_analyze_result returns false.

However, I wouldn't want to make such a change without first
giving you the opportunity to look at the code and indicate
if such a change is just papering over a problem elsewhere in
the IV code.

For the fortran testcase using a i686-pc-linux-gnu-x-powerpc64-linux
cross compiler we have the following code in a loop:

(insn 35 34 36 5 (set (reg:SI 126)
        (plus:SI (subreg/s:SI (reg:DI 123 [ D.885 ]) 4)
            (const_int 1 [0x1]))) 78 {*addsi3_internal1} (nil)
    (nil))

(insn 36 35 38 5 (set (reg/v:DI 122 [ i ])
        (sign_extend:DI (reg:SI 126))) 27 {*rs6000.md:367} (nil)
    (nil))

(insn 38 36 39 5 (set (reg:DI 123 [ D.885 ])
        (zero_extend:DI (subreg:QI (reg/v:DI 122 [ i ]) 7))) 12
{*zero_extendqidi2_internal1} (nil)
    (nil))

(insn 39 38 40 5 (set (reg:CC 127)
        (compare:CC (subreg/s:SI (reg:DI 123 [ D.885 ]) 4)
            (subreg/s:SI (reg/v:DI 122 [ i ]) 4))) 414
{*cmpsi_internal1} (nil)
    (nil))


We blow up trying to analyze insn 38 -- which of course requires
us to look at insns 36 & 35.  

iv_analyze_result ultimately returns false because iv_subreg
returned false for the following case:

iv->base        (reg:DI 123 [ D.885 ])
iv->step        (const_int 1)
iv->extend      ZERO_EXTEND
iv->extend_mode DImode
iv->mode        QImode
iv->first_special 1

The mode parameter is SImode.


We trigger this code:
401       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (iv->mode))
402         return false;


ie, if we're asking iv_subreg to extend from a narrow mode to
a wider mode via a subreg-like operation, then iv_subreg returns
false.  That eventually bubbles up to analyze_iv_to_split_insn
and triggers the ICE.

Jeff


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25569

Reply via email to