Bug 29751

Summary: not optimizing access a[0] , a[1]
Product: gcc Reporter: Tobias Burnus <burnus>
Component: tree-optimizationAssignee: Andrew Pinski <pinskia>
Status: RESOLVED FIXED    
Severity: enhancement CC: gcc-bugs
Priority: P3 Keywords: alias, missed-optimization, TREE
Version: 4.3.0   
Target Milestone: 4.6.0   
Host: Target:
Build: Known to work: 4.6.0
Known to fail: Last reconfirmed: 2009-01-01 21:49:33
Attachments: Patch which I am testing
more correct patch

Description Tobias Burnus 2006-11-07 13:10:10 UTC
In the following program, the if() is only removed if one removes the line "r[1]=0;". (4.3.0 20061107; x86_64-unknown-linux-gnu-gcc)

#include <stdlib.h>
void foo (void);
int main() {
  int *restrict r;
  r = malloc(2*sizeof(int));
  r[0] = 0;
  r[1] = 0;
  if(r[0]) foo();
  return 0;
}


main ()
{
  int * restrict r;
  void * D.1998;
<bb 2>:
  D.1998 = malloc (8);
  r = (int * restrict) D.1998;
  *r = 0;
  *(r + 4B) = 0;
  if (*r != 0) goto <L0>; else goto <L1>;
<L0>:;
  foo ();
<L1>:;
  return 0;
}
Comment 1 Andrew Pinski 2006-11-14 01:06:00 UTC
This is a problem of our VOPs not having base+offset and has nothing to do with restrict.


int f(int *r)
{
  r[0] = 0;
  r[1] = 0;
  if(r[0]) foo();
}

is enough to reproduce the issue.  Also I think there might be a couple dups of this with respect of structs instead.
Comment 2 Andrew Pinski 2007-06-11 00:30:03 UTC
Confirmed, this is only a tree level missed optimization.
Comment 3 Richard Biener 2008-03-14 21:21:32 UTC
Related to PR34172, but not fixed.  MEM_REF will get this right as we effectively
have array refs on pointers there.
Comment 4 Andrew Pinski 2008-04-07 01:28:41 UTC
Hmm, if we change r to be an array, fre does the correct thing but shouldn't it do the correct thing for the non array case too?
Comment 5 Richard Biener 2008-04-07 08:51:40 UTC
Only if you extend refs_may_alias_p, as for pointers you have

 p_2 = p_1 + 1;
 *p_2
 *p_1

and it doesn't follow def-use chains to see the pointer-plus to disambiguate
both pointer de-references.  With arrays you see

 a[0]
 a[1]

which it handles fine.  It also should handle

 (*p_2)[0]
 (*p_2)[1]

fine (if you convert p_! to (int *)[] first).
Comment 6 Andrew Pinski 2009-06-09 02:35:11 UTC
I have a simple patch (which needs some cleanups but it works).
Comment 7 Andrew Pinski 2009-08-05 17:52:27 UTC
Created attachment 18307 [details]
Patch which I am testing

This patch fixes the problem including a+1 and a+2 not aliasing each other.
It adds two testcases and removes a xfail on one.
It also fixes a bug in cfgexpand.c (update_alias_info_with_stack_vars) so that it does not create SSA_NAMES with a define statement of NULL.
Comment 8 Andrew Pinski 2011-09-23 22:09:14 UTC
(In reply to comment #7)
> Created attachment 18307 [details]
> Patch which I am testing

There is one bug in that patch which I have a fix for.
Comment 9 Andrew Pinski 2011-11-17 22:03:34 UTC
Created attachment 25847 [details]
more correct patch

An updated patch which is more correct than the previous patch and it works correctly with MEM_REF which has an offset.  Also moves some code to do addition of the bit offset to a function.
Comment 10 Andrew Pinski 2012-01-25 09:14:07 UTC
(In reply to comment #9)
> Created attachment 25847 [details]
> more correct patch
> 
> An updated patch which is more correct than the previous patch and it works
> correctly with MEM_REF which has an offset.  Also moves some code to do
> addition of the bit offset to a function.
I just noticed it does not have the fix for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44838 in it really.

Will retest and submit tomorrow.
Comment 11 Richard Biener 2012-01-25 10:30:28 UTC
The original testcase is fixed during early FRE since we have MEM_REF, and
DCE makes main empty even in 4.7.