Bug 34363 - [4.2 Regression] Aliasing failure during tree fre
Summary: [4.2 Regression] Aliasing failure during tree fre
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.2.3
: P3 major
Target Milestone: 4.3.0
Assignee: Not yet assigned to anyone
URL:
Keywords: alias, wrong-code
: 35134 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-12-06 18:35 UTC by David Ung
Modified: 2009-03-31 01:39 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.1.3 4.3.0
Known to fail: 4.2.1 4.2.2 4.2.3 4.2.5
Last reconfirmed: 2008-02-11 19:02:38


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Ung 2007-12-06 18:35:05 UTC
Simple test case:

unsigned n;

void foo (unsigned *p)
{
  n = 4;
  *p = 0;
  if (n != 0)
    abort ();
}

main ()
{
  foo (&n);
  return 0;
}

Tested cross-compiling for MIPS, also verified that x86 also has the same problem.
attached dump from the fre pass.
**** basically n.0_4 should not be assigned the value of 4, since *p can alias it.

;; Function foo (foo)

Created value VH.0 for p_3
exp_gen[0] := {  }
tmp_gen[0] := { p_3 (VH.0)  }
avail_out[0] := { p_3 (VH.0)  }
exp_gen[2] := {  }
tmp_gen[2] := {  }
avail_out[2] := { p_3 (VH.0)  }
exp_gen[3] := {  }
tmp_gen[3] := {  }
avail_out[3] := { p_3 (VH.0)  }
exp_gen[4] := {  }
tmp_gen[4] := {  }
avail_out[4] := { p_3 (VH.0)  }
exp_gen[1] := {  }
tmp_gen[1] := {  }
avail_out[1] := {  }
Replaced n with 4 in n.0_4 = n;
foo (p)
{
  unsigned int n.0;

<bb 2>:
  n = 4;
  *p_3 = 0;
  n.0_4 = 4;                                    *****
  if (n.0_4 != 0) goto <L0>; else goto <L1>;

<L0>:;
  abort ();

<L1>:;
  return;

}
Comment 1 Andrew Pinski 2007-12-07 00:14:35 UTC
This worked in "4.3.0 20071127".
Comment 2 Richard Biener 2007-12-07 10:25:13 UTC
Confirmed.  Wrong alias info:

foo (p)
{
  unsigned int n.0;

<bb 2>:
  #   n_2 = V_MUST_DEF <n_1>;
  n = 4;
  #   NONLOCAL.6_6 = V_MAY_DEF <NONLOCAL.6_5>;
  *p_3 = 0;
  #   VUSE <n_2>;
  n.0_4 = n;
  if (n.0_4 != 0) goto <L0>; else goto <L1>;

<L0>:;
  #   VUSE <n_2>;
  #   VUSE <NONLOCAL.6_6>;
  abort ();

<L1>:;
  return;
Comment 3 Joseph S. Myers 2008-02-01 16:55:13 UTC
4.2.3 is being released now, changing milestones of open bugs to 4.2.4.
Comment 4 Andrew Pinski 2008-02-08 00:30:32 UTC
*** Bug 35134 has been marked as a duplicate of this bug. ***
Comment 5 Sandra Loosemore 2008-04-30 20:17:56 UTC
Here's another testcase for the same bug, or one closely related to it:

#include <stdio.h>
unsigned x = 8;
unsigned *addr()
{
  return &x;
}
int main()
{
  x = 4;
  *addr() = *addr() / 2;
  printf ("*addr() = %d, x = %d\n", *addr(), x);
  return 0;
}

I've determined that both this test case and the original one reported with this issue were fixed on mainline by the commit r119502, this patch:

http://gcc.gnu.org/ml/gcc-patches/2006-12/msg00225.html

I'm not familiar enough with this code (yet!) to be able to tell whether this was a lurking bug fixed by that patch, or whether it is a lurking bug that was merely obscured by that patch and is still present on mainline.
Comment 6 Richard Biener 2008-04-30 21:24:10 UTC
The problem is that NONLOCAL has to alias all global symbols but does not:

  #   x_2 = V_MUST_DEF <x_1>;
  x = 4;
...
  #   NONLOCAL.53_13 = V_MAY_DEF <NONLOCAL.53_12>;
  *D.2057_3 = D.2060_6;

That is, during flow insensitive alias computation we'd need to add these, but
this makes the whole point of the NONLOCAL tag moot.  So getting rid of it
is the "fix".

But this is way too invasive for 4.2, so 4.2 joins 4.1 in the set of
worst-aliasing-bugs-since-ever releases ;)
Comment 7 Joseph S. Myers 2008-05-19 20:23:58 UTC
4.2.4 is being released, changing milestones to 4.2.5.
Comment 8 Joseph S. Myers 2009-03-31 01:39:14 UTC
Closing 4.2 branch, fixed in 4.3.