Bug 25569 - [4.2 Regression] FAIL: gfortran.dg/g77/20010610.f -O3 -fomit-frame-pointer -funroll-loops
Summary: [4.2 Regression] FAIL: gfortran.dg/g77/20010610.f -O3 -fomit-frame-pointer -...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.2.0
Assignee: Zdenek Dvorak
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 25925
  Show dependency treegraph
 
Reported: 2005-12-26 18:36 UTC by John David Anglin
Modified: 2006-03-22 18:01 UTC (History)
6 users (show)

See Also:
Host:
Target: hppa64-hp-hpux11.11, powerpc64-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-03-14 01:03:42


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John David Anglin 2005-12-26 18:36:52 UTC
Executing on host: /mnt/gnu/gcc-3.3/objdir/stage3-gcc/testsuite/../gfortran -B/m
nt/gnu/gcc-3.3/objdir/stage3-gcc/testsuite/../ /mnt/gnu/gcc-3.3/gcc/gcc/testsuit
e/gfortran.dg/g77/20010610.f   -O3 -fomit-frame-pointer -funroll-loops   -pedant
ic-errors  -L/mnt/gnu/gcc-3.3/objdir/hppa64-hp-hpux11.11/./libgfortran/.libs -L/
mnt/gnu/gcc-3.3/objdir/hppa64-hp-hpux11.11/./libgfortran/.libs -L/mnt/gnu/gcc-3.
3/objdir/hppa64-hp-hpux11.11/./libiberty  -lm   -o ./20010610.exe    (timeout =
300)
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f: In function 'MAIN
__':
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f:2: internal compil
er error: in analyze_iv_to_split_insn, at loop-unroll.c:1674
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
compiler exited with status 1
output is:
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f: In function 'MAIN
__':
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f:2: internal compil
er error: in analyze_iv_to_split_insn, at loop-unroll.c:1674
Please submit a full bug report,
with preprocessed source if appropriate.

Also,

Executing on host: /mnt/gnu/gcc-3.3/objdir/stage3-gcc/testsuite/../gfortran -B/m
nt/gnu/gcc-3.3/objdir/stage3-gcc/testsuite/../ /mnt/gnu/gcc-3.3/gcc/gcc/testsuit
e/gfortran.dg/g77/20010610.f   -O3 -fomit-frame-pointer -funroll-all-loops -finl
ine-functions   -pedantic-errors  -L/mnt/gnu/gcc-3.3/objdir/hppa64-hp-hpux11.11/
./libgfortran/.libs -L/mnt/gnu/gcc-3.3/objdir/hppa64-hp-hpux11.11/./libgfortran/
.libs -L/mnt/gnu/gcc-3.3/objdir/hppa64-hp-hpux11.11/./libiberty  -lm   -o ./2001
0610.exe    (timeout = 300)
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f: In function 'MAIN
__':
/mnt/gnu/gcc-3.3/gcc/gcc/testsuite/gfortran.dg/g77/20010610.f:2: internal compil
er error: in analyze_iv_to_split_insn, at loop-unroll.c:1674
Please submit a full bug report,
with preprocessed source if appropriate.

This bug appears to have been introduced between 2005-12-02 and 2005-12-23.
Comment 1 John David Anglin 2005-12-30 23:24:35 UTC
This is the call that returns 0:

(gdb) bt
#0  iv_analyze (insn=0x800003fffedfcfa0, def=0x800003fffedfd3e0,
    iv=0x800003fffeff1230) at ../../gcc/gcc/loop-iv.c:998
...

(gdb) p *iv
$8 = {base = 0x800003fffedfff80, step = 0x800003fffed58410,
  extend = ZERO_EXTEND, delta = 0x800003fffed58400,
  mult = 0x800003fffed58410, extend_mode = DImode, mode = SImode,
  analysed = 1, first_special = 0}
(gdb) p debug_rtx (insn)
(insn 41 39 42 5 (set (reg:DI 71 [ D.775 ])
        (zero_extend:DI (subreg:QI (reg/v:DI 70 [ i ]) 7))) 129 {*pa.md:4636} (nil)
    (nil))
$9 = void
(gdb) p debug_rtx (iv->base)
(plus:DI (reg:DI 69 [ ivtmp___25 ])
    (const_int 1 [0x1]))
$10 = void
(gdb) p debug_rtx (iv->step)
(const_int 1 [0x1])
$11 = void
(gdb) p debug_rtx (iv->delta)
(const_int 0 [0x0])
$12 = void
(gdb) p debug_rtx (iv->mult)
(const_int 1 [0x1])
$13 = void

Here is the rtl:

(gdb) p debug_rtx_list (get_insns (), 50)
(note 12 0 14 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 14 12 15 2 (set (reg:SI 26 %r26)
        (const_int 118 [0x76])) 70 {*pa.md:2308} (nil)
    (nil))

(insn 15 14 16 2 (set (reg:SI 25 %r25)
        (const_int 127 [0x7f])) 70 {*pa.md:2308} (nil)
    (nil))

(insn 16 15 17 2 (set (reg/f:DI 29 %r29)
        (plus:DI (reg/f:DI 30 %r30)
            (const_int -48 [0xffffffffffffffd0]))) 158 {*pa.md:4980} (nil)
    (nil))

(call_insn 17 16 19 2 (parallel [
            (call (mem:SI (symbol_ref/v:DI ("@_gfortran_set_std") [flags 0x41] <function_decl 800003fffedd2d00 _gfortran_set_std>) [0 S4 A32])
                (const_int 64 [0x40]))
            (clobber (reg:DI 1 %r1))
            (clobber (reg:DI 2 %r2))
            (clobber (reg:DI 4 %r4))
            (use (reg:DI 27 %r27))
            (use (reg/f:DI 29 %r29))
            (use (const_int 0 [0x0]))
        ]) 257 {call_symref_64bit} (nil)
    (nil)
    (expr_list:REG_DEP_TRUE (use (reg:SI 25 %r25))
        (expr_list:REG_DEP_TRUE (use (reg:SI 26 %r26))
            (nil))))

(insn 19 17 21 2 (set (reg:DI 71 [ D.775 ])
        (const_int 1 [0x1])) 119 {*pa.md:4174} (nil)
    (nil))

(insn 21 19 24 2 (set (reg:DI 69 [ ivtmp___25 ])
        (const_int 0 [0x0])) 119 {*pa.md:4174} (nil)
    (nil))

(code_label 24 21 25 3 3 "" [1 uses])

(note 25 24 26 3 [bb 3] NOTE_INSN_BASIC_BLOCK)

(insn 26 25 27 3 (set (reg/f:DI 29 %r29)
        (plus:DI (reg/f:DI 30 %r30)
            (const_int -48 [0xffffffffffffffd0]))) 158 {*pa.md:4980} (nil)
    (nil))

(call_insn 27 26 29 3 (parallel [
            (call (mem:SI (symbol_ref/v:DI ("@_gfortran_abort") [flags 0x41] <function_decl 800003fffede8400 _gfortran_abort>) [0 S4 A32])
                (const_int 64 [0x40]))
            (clobber (reg:DI 1 %r1))
            (clobber (reg:DI 2 %r2))
            (clobber (reg:DI 4 %r4))
            (use (reg:DI 27 %r27))
            (use (reg/f:DI 29 %r29))
            (use (const_int 0 [0x0]))
        ]) 257 {call_symref_64bit} (nil)
    (expr_list:REG_NORETURN (const_int 0 [0x0])
        (nil))
    (nil))

(code_label 29 27 30 4 2 "" [0 uses])

(note 30 29 31 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 31 30 32 4 (set (reg:SI 73)
        (plus:SI (subreg/s/u:SI (reg:DI 69 [ ivtmp___25 ]) 4)
            (const_int 1 [0x1]))) 161 {addsi3} (nil)
    (nil))

(insn 32 31 34 4 (set (reg:DI 69 [ ivtmp___25 ])
        (zero_extend:DI (reg:SI 73))) 131 {*pa.md:4672} (nil)
    (nil))

(insn 34 32 35 4 (set (reg:SI 74)
        (const_int 255 [0xff])) 70 {*pa.md:2308} (nil)
    (nil))

(jump_insn 35 34 37 4 (set (pc)
        (if_then_else (eq (subreg/s/u:SI (reg:DI 69 [ ivtmp___25 ]) 4)
                (reg:SI 74))
            (label_ref/s:DI 53)
            (pc))) 46 {*pa.md:1700} (nil)
    (expr_list:REG_EQUAL (if_then_else (eq (subreg/s/u:SI (reg:DI 69 [ ivtmp___25 ]) 4)
                (const_int 255 [0xff]))
            (label_ref:DI 53)
            (pc))
        (expr_list:REG_BR_PROB (const_int 532 [0x214])
            (nil))))

(note 37 35 38 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(insn 38 37 39 5 (set (reg:SI 75)
        (plus:SI (subreg/s:SI (reg:DI 71 [ D.775 ]) 4)
            (const_int 1 [0x1]))) 161 {addsi3} (nil)
    (nil))

(insn 39 38 41 5 (set (reg/v:DI 70 [ i ])
        (sign_extend:DI (reg:SI 75))) 137 {extendsidi2} (nil)
    (nil))

(insn 41 39 42 5 (set (reg:DI 71 [ D.775 ])
        (zero_extend:DI (subreg:QI (reg/v:DI 70 [ i ]) 7))) 129 {*pa.md:4636} (nil)
    (nil))

(jump_insn 42 41 63 5 (set (pc)
        (if_then_else (ne (subreg/s:SI (reg:DI 71 [ D.775 ]) 4)
                (subreg/s:SI (reg/v:DI 70 [ i ]) 4))
            (label_ref/s 24)
            (pc))) 46 {*pa.md:1700} (nil)
    (expr_list:REG_BR_PROB (const_int 107 [0x6b])
        (nil)))

(note 63 42 53 8 [bb 8] NOTE_INSN_BASIC_BLOCK)

(code_label 53 63 56 7 6 "" [1 uses])

(note 56 53 0 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

$18 = void
Comment 2 Alan Modra 2006-01-20 00:56:48 UTC
Also fails on powerpc64-linux
Comment 3 Andrew Pinski 2006-03-06 15:00:27 UTC
(In reply to comment #1)
> (gdb) p debug_rtx (insn)
> (insn 41 39 42 5 (set (reg:DI 71 [ D.775 ])
>         (zero_extend:DI (subreg:QI (reg/v:DI 70 [ i ]) 7))) 129 {*pa.md:4636}
> (nil)
>     (nil))
> $9 = void

This is a similar instruction which effects ppc64 also.  It also fails the same way on powerpc64-darwin.
Comment 4 Andrew Pinski 2006-03-06 15:49:23 UTC
Janis could you do a regression hunt on what caused this testcase to start to fail?
The C testcase is:
int f(void)
{
  int i;
  for(i=0;i<256;i++)
  {
    char a = i;
    int ii = a;
    if (ii != i)  __builtin_abort();
  }
}
Comment 5 Janis Johnson 2006-03-08 00:07:18 UTC
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)
Comment 6 Jeffrey A. Law 2006-03-10 19:37:39 UTC
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)
Just an FYI -- I probably won't be able to start looking at this
until Monday.  Hopefully it'll be something I can hunt down
with a cross compiler as I don't have a ppc64 box :-)

jeff

Comment 7 Jeffrey A. Law 2006-03-13 21:17:22 UTC
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)
What I suspect is going on here is that we've got a latent
bug in the RTL IV code.  The patches referenced above merely
expose instances of that underlying latent bug.

I'm still trying to learn my way around the RTL IV code, if
I can't figure it out pretty quickly I'll have to hand this off
to Zdenek.

jeff


Comment 8 dave 2006-03-13 21:30:45 UTC
Subject: Re:  [4.2 Regression] FAIL: gfortran.dg/g77/20010610.f  -O3 -fomit-frame-pointer -funroll-loops

> > r108425 | law | 2005-12-12 19:59:16 +0000 (Mon, 12 Dec 2005)
> What I suspect is going on here is that we've got a latent
> bug in the RTL IV code.  The patches referenced above merely
> expose instances of that underlying latent bug.

We have the following IV bug still open on the PA:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26244

Dave
Comment 9 Jeffrey A. Law 2006-03-13 21:45:56 UTC
Subject: Re:  [4.2 Regression] FAIL:
	gfortran.dg/g77/20010610.f  -O3 -fomit-frame-pointer -funroll-loops

On Mon, 2006-03-13 at 21:31 +0000, dave at hiauly1 dot hia dot nrc dot
ca wrote:
> 
> ------- Comment #8 from dave at hiauly1 dot hia dot nrc dot ca  2006-03-13 21:30 -------
> Subject: Re:  [4.2 Regression] FAIL: gfortran.dg/g77/20010610.f  -O3
> -fomit-frame-pointer -funroll-loops
> 
> > > r108425 | law | 2005-12-12 19:59:16 +0000 (Mon, 12 Dec 2005)
> > What I suspect is going on here is that we've got a latent
> > bug in the RTL IV code.  The patches referenced above merely
> > expose instances of that underlying latent bug.
> 
> We have the following IV bug still open on the PA:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26244
Thanks.  I doubt the problems in 26244 and 25569 are related.

26244 is a code generation error apparently related to loop
invariant code motion, 25569 is an ICE due to unrolling.

Jeff


Comment 10 Jeffrey A. Law 2006-03-13 22:14:00 UTC
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






Comment 11 Zdenek Dvorak 2006-03-14 01:10:06 UTC
>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.

This is definitely a bug in loop-iv.c -- once biv_p (SET_DEST (single_set (insn))) returns true, iv_analyze_result must succeed as well.
Comment 12 Zdenek Dvorak 2006-03-21 21:35:19 UTC
(In reply to comment #11)
> This is definitely a bug in loop-iv.c -- once biv_p (SET_DEST (single_set
> (insn))) returns true, iv_analyze_result must succeed as well.

While I still consider this desirable, it is somewhat difficult to achieve
(it requires big changes to iv_analyze_... routines, and I am not even quite sure the gain would be worth the cost).

Replacing the assert in analyze_iv_to_split_insn with return NULL should be safe, in the meantime.
Comment 13 Jeffrey A. Law 2006-03-22 18:01:30 UTC
Fixed via today's checkin to loop-unroll.c