Bug 30159

Summary: [4.3 Regression] gcc.c-torture/execute/20010422-1.c is miscompiled
Product: gcc Reporter: Kazumoto Kojima <kkojima>
Component: tree-optimizationAssignee: Andrew Macleod <amacleod>
Status: RESOLVED FIXED    
Severity: normal CC: amacleod, danglin, gcc-bugs, rsandifo
Priority: P3 Keywords: wrong-code
Version: 4.3.0   
Target Milestone: 4.3.0   
Host: i686-pc-linux-gnu Target: sh-elf, mips-elf, i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed: 2006-12-12 14:11:13

Description Kazumoto Kojima 2006-12-12 00:15:39 UTC
On sh-elf, the function foo in 20010422-1.c

unsigned int foo(unsigned int x)
{
  if (x < 5)
    x = 4;
  else
    x = 8;
  return x;
}

is compiled to

foo:
        mov.l   r14,@-r15
        mov     r15,r14
        mov     #4,r1
        cmp/hi  r1,r1
        bf/s    .L6
        mov     #4,r0
        mov     #8,r0
.L6:
        mov     r14,r15
        mov.l   @r15+,r14
        rts
        nop

with -O1.  Thus the first parameter register r4 is ignored.
For mips-elf, foo is assembled to

foo:
        .frame  $sp,0,$31               # vars= 0, regs= 0/0, args= 0, gp= 0
        .mask   0x00000000,0
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro

        sltu    $2,$2,5
        beq     $2,$0,$L2
        nop
	...

with -O1 where $4 should be register for x.
It started after the patch

r119711 | amacleod | 2006-12-11 06:25:40 +0900 (Mon, 11 Dec 2006) | 103 lines

and the first tree dump which differs before and after this patch
is .099t.optimized:

[r119710 .099t.optimized]
;; Function foo (foo)

Analyzing Edge Insertions.
foo (x)
{
  unsigned int x.24;

<bb 2>:
  if (x <= 4) goto <L5>; else goto <L4>;

<L5>:;
  x.24 = 4;
  goto <bb 4> (<L2>);

<L4>:;
  x.24 = 8;

<L2>:;
  return x.24;

}

[r119711 .099t.optimized]
;; Function foo (foo)

Analyzing Edge Insertions.
foo (x)
{
  unsigned int x.24;

<bb 2>:
  if (x.24 <= 4) goto <L5>; else goto <L4>;

<L5>:;
  x = 4;
  goto <bb 4> (<L2>);

<L4>:;
  x = 8;

<L2>:;
  return x;

}
Comment 1 Kazumoto Kojima 2006-12-12 13:01:48 UTC
A slightly different test case

unsigned int foo(unsigned int x)
{
  if (x < 5)
    x = 4;
  else
    x = 8;
  return x;
}

int main(void)
{
  if (foo (4) != 4)
    abort ();
  if (foo (8) != 8)
    abort ();
  exit (0);
}

aborts on i686-pc-linux-gnu with -O1 and -O2.
Comment 2 Diego Novillo 2006-12-12 13:51:50 UTC
Adding Andrew to CC list.  Seems related to out-of-ssa changes.
Comment 3 Andrew Macleod 2006-12-12 14:11:13 UTC
Analyzing Edge Insertions.
foo (x)
{
  unsigned int x.24;

<bb 2>:
  if (x.24 <= 4) goto <L5>; else goto <L4>;

Yeah, this is clearly wrong. It looks like the coalescer somehow neglected to coalesce the parameter to the first use in bb2, so it ended up getting the wrong 'x' in the comparison. The x and x.24's should all be reversed.
Comment 4 Andrew Macleod 2006-12-12 15:50:31 UTC
Subject: Bug 30159

Author: amacleod
Date: Tue Dec 12 15:50:06 2006
New Revision: 119792

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=119792
Log:

2006-12-12  Andrew Macleod  <amacleod@redhat.com>

	PR tree-optimization/30159
	* tree-ssa-coalesce.c (coalesce_ssa_name): Process single ssa_name 
	functions in case a default_def coalesce is required.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-ssa-coalesce.c

Comment 5 Andrew Pinski 2006-12-12 19:53:44 UTC
*** Bug 30178 has been marked as a duplicate of this bug. ***
Comment 6 Kazumoto Kojima 2006-12-12 23:20:18 UTC
The patch fixes the problem also on sh-elf and mips-elf.  Thanks!
BTW, I'm a bit surprised that current testcases didn't catch it on x86.
How about to add a new testcase?
Comment 7 Andrew Pinski 2006-12-13 05:42:42 UTC
Fixed.