Bug 18612 - Loop optimiser generates incorrect code.
Summary: Loop optimiser generates incorrect code.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.3
: P2 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2004-11-22 19:11 UTC by John Richardson
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: cygwin
Target: m68k-elf
Build: cygwin
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Richardson 2004-11-22 19:11:55 UTC
When the code below is compiled with -O3, func2() is called on each iteration.
The .s shows that the the comparison to Array has been moved outside of the loop
which is incorrect. If Array is not constant working code is produced, working
code is also produced if I use -fold-unroll-loops. If I don't call a function
say simply increment j, then correct code is produced too.

The other options used are:
-O3 -m68000 -msoft-float -fno-exceptions

--------------
const unsigned char Array[6] = { 10, 10, 10, 0, 0 ,0 };
void func2(void);

int j=0;

void func(void)
{
    unsigned char i;

    for(i=0; i<6; i++)
    {
        if(Array[i] > 0)
        {
	    func2();
        }
    }
}

void func2(void)
{
    j++;
}
--------------
Comment 1 Bernardo Innocenti 2004-12-13 08:53:20 UTC
What happens here is that func2() is inlined
inside func(), and j loaded into %a0 before
entering the loop, for improved speed.

The test for Array[i] > 0 is correctly
performed *inside* the loop.

This PR appears to be invalid to me, but I'll
wait for a clarification before closing it.


func:
        link.w %a6,#0
        clr.b %d0
        lea Array,%a1
        moveq #0,%d1
        move.l j,%a0
        .align  2
.L8:
        move.b %d0,%d1
        tst.b (%a1,%d1.l)
        jbeq .L5
        addq.l #1,%a0
.L5:
        addq.b #1,%d0
        cmp.b #5,%d0
        jbls .L8
        move.l %a0,j
        unlk %a6
        rts
Comment 2 John Richardson 2004-12-13 18:29:34 UTC
I'm sorry I forget to include "-fno-inline" as a compiler option I'm using. When
I compile without "-fno-inline" I do get the same code as you posted here. 

This is the code produced using this option:

	link.w %a6,#0
	move.l %d2,-(%sp)
	clr.b %d2
	lea Array,%a0
	tst.b (%a0)
	jbne .L18
	.align	2
.L7:
	addq.b #1,%d2
	cmp.b #5,%d2
	jbls .L7
	jbra .L16
	.align	2
.L18:
	jbsr _Z5func2v
	addq.b #1,%d2
	cmp.b #5,%d2
	jbhi .L16
	jbsr _Z5func2v
	addq.b #1,%d2
	cmp.b #5,%d2
	jbls .L18
.L16:
	move.l -4(%a6),%d2
	unlk %a6
	rts



John.
Comment 3 Tomas Hurka 2005-06-10 15:58:06 UTC
This seems to be fixed in GCC 4.0.0. This is the code produced by GCC 4.0.0 with following command 
line:
~/Projects/gcc_m68k/bin/m68k-bsd-elf-gcc -S -O3 -m68000 -msoft-float -fno-exceptions -fno-
inline test.c

func:
        link.w %fp,#0
        move.l %a2,-(%sp)
        lea Array,%a2
        tst.b (%a2)
        jbeq .L5
        jbra .L13
.L12:
        tst.b (%a2)
        jbeq .L5
.L13:
        jbsr func2
.L5:
        addq.l #1,%a2
        cmp.l #Array+6,%a2
        jbne .L12
        move.l -4(%fp),%a2
        unlk %fp
        rts
 
Comment 4 Andrew Pinski 2005-06-15 03:24:04 UTC
Closing as fixed then.