Bug 17064 - -falias-noargument-global doesn't eliminate dead stores/loads
Summary: -falias-noargument-global doesn't eliminate dead stores/loads
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.0.0
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: alias, missed-optimization
Depends on: 22254
Blocks: 21470
  Show dependency treegraph
Reported: 2004-08-17 14:05 UTC by Paul Brook
Modified: 2010-07-13 13:29 UTC (History)
5 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2009-04-03 11:57:05


Note You need to log in before you can comment on or make changes to this bug.
Description Paul Brook 2004-08-17 14:05:46 UTC
When the following example is compiled with -fargument-noalias-global, the 
store *p=1 is dead and should be removed. 
-fargument-noalias-global is the default for Fortran. 
#include <stdlib.h> 
int i; 
int j; 
void bar(void) 
  i = 42; 
void foo(int * p) 
  *p = 1;/* This store is dead with -fargument-noalias-global.  */ 
  bar (); 
  *p = 2; 
int main() 
  i = 0; 
  j = 0; 
  if (i != 42 || j != 2) 
  return 0; 
Comment 1 Andrew Pinski 2004-11-06 20:14:06 UTC
Even for the simple testcase, we don't eliminate dead stores:
int i;
int j;
int main()
  i = 0; <<--should be removed
  j = 0; <<--should be removed
  j = 1; <<--should be removed
  i = 42;
  j = 2;
Comment 2 Andrew Pinski 2005-02-07 19:00:06 UTC
Another testcase this time for loads:
#include <stdlib.h>
int i;

void bar(void)
  i = 42;

int foo(int * p)
  int i = *p;
  bar ();
  return *p + i;/* This load is dead with -fargument-noalias-global.  */

int main()
  int t = 2;
  int t1;
  t1 = foo(&t);
  if (t1 != 4)
  return 0;
Comment 3 Andrew Pinski 2005-03-04 03:41:45 UTC
Here is a testcase which we semi optimize on the RTL level but not at the tree level:
sum cannot alias a or b at all because of the default option for gfortran.

subroutine dot_product (sum, a, b, n)
   real*8 a(n), b(n), sum
   sum = 0
   do i = 1, n
     sum = sum + a (i) * b(i)
   end do

The reason why I say semi is because there is an extra fmr (PPC):
The loop looks like:
        lfd f13,0(r4)
        addi r4,r4,8
        lfd f0,0(r5)
        addi r5,r5,8
        fmadd f0,f13,f0,f12
        fmr f12,f0
        bdnz L4

If we had optimizate it at the tree level it would look like:
        lfd f13,0(r4)
        addi r4,r4,8
        lfd f0,0(r5)
        addi r5,r5,8
        fmadd f12,f13,f0,f12
        bdnz L4

Note how we don't have the extra fmr.
Comment 4 Andrew Pinski 2005-07-27 17:06:04 UTC
Another testcase for extra load at the tree level:
int g (int* g1, int* g2)
  int i;
  g2[0] = 2;
  g1[0] = 3;
  return g2[0];

Note the test in comment #1 has been fixed already.
Comment 5 Andrew Pinski 2005-08-06 19:51:33 UTC
Diego, sorry to steal this from you but I got a fix for this issue though there are still some issues with 
address considered call clobered which cannot be true.
Comment 6 Andrew Pinski 2005-10-05 13:21:12 UTC
Talked to Daniel Berlin about the patch I had, it was in the wrong spot, I had it in the post process and not when analyzing the code.  So assigning back to Diego.
Comment 7 Andrew Pinski 2006-01-10 20:35:03 UTC
I have a semi fix for this one but the variable is still being marked as a call clobber but that is because of a FIXME in the source.  I am going to take it anyways but not close it once I get my patch approved.
It does fix comment #3 though.
Comment 8 Andrew Pinski 2006-01-10 20:36:26 UTC
I should note that the patch is not fully done as I still need to be able to add it to the list of variables to remove before running the may_alias again (like the HEAP variables).
Comment 9 Andrew Pinski 2006-01-16 17:11:04 UTC
Partial patch posted:
Comment 10 Andrew Pinski 2006-01-26 17:51:28 UTC
Subject: Bug 17064

Author: pinskia
Date: Thu Jan 26 17:51:25 2006
New Revision: 110263

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110263
2006-01-26  Richard Guenther  <rguenther@suse.de>
            Andrew Pinski  <pinskia@physics.uc.edu>

        PR tree-opt/21470
        partial PR tree-opt/17064
        * tree-ssa-structalias.c (intra_create_variable_infos):
        Create heap variables for incoming parameters if
        flag_argument_noalias > 1.
        (find_what_p_points_to): Look through default defs of
        parameter decls.


Comment 11 Andrew Pinski 2006-01-26 17:51:49 UTC
The partial fix has been applied, I have another patch which fixes another part of this but still not fully.
It just helps the call cloberring mechanism.
Comment 12 Andrew Pinski 2006-01-26 18:15:43 UTC
This is the patch which helps the call clobering but does not fix it all the way (because a different call clobbering issue):
Index: tree-ssa-alias.c
--- tree-ssa-alias.c    (revision 110263)
+++ tree-ssa-alias.c    (working copy)
@@ -328,7 +328,8 @@ set_initial_properties (struct alias_inf
       else if (TREE_CODE (var) == PARM_DECL
               && default_def (var)
-              && POINTER_TYPE_P (TREE_TYPE (var)))
+              && POINTER_TYPE_P (TREE_TYPE (var))
+              && flag_argument_noalias > 1)
          tree def = default_def (var);
          get_ptr_info (def)->value_escapes_p = 1;
Comment 13 Andrew Pinski 2006-01-29 04:32:10 UTC
All the rest of the issues are going to be too complex for me to fix, IFort does not optimize Fortran code like this either.

So the comments which are not fixed are #0 and #2 across the functions.

The corresponding Fortran looks like:
function h(a)
integer a
a = 1
call g()
a = 1
h = 1.0
end function
Comment 14 David Edelsohn 2006-01-31 00:49:19 UTC
The parameter is considered global because it is marked DECL_EXTERNAL.  And it is marked EXTERNAL in tree-ssa-structalias.c:

    heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)), PARM_NOALIAS");
    DECL_EXTERNAL (heapvar) = 1;

Should the temp variable always be marked external?
Comment 15 Andrew Pinski 2006-01-31 01:11:34 UTC
The other time pi->pt_global_mem is set to 1 is when vi->is_artificial_var and vi->is_heap_var is set.

now trying to turn off is_artificial_var and what David pointed out does not work, because we don't have a way to say this is used after the function is done so DCE removes the both sets in the testcase in comment #13.
Comment 16 Richard Biener 2009-04-03 11:57:05 UTC
Re-confirmed with current trunk.  The issue is that PTA computes

Flow-insensitive points-to information for foo

p_1(D), points-to vars: { PARM_NOALIAS.28 } (includes global vars)

foo (int * p)
<bb 2>:
  *p_1(D) = 1;
  bar ();
  *p_1(D) = 2;

note the 'includes global vars' flag.  Note that "fixing" this would
really make _both_ stores to *p dead, as "does-not-point-to-global"
does not mean "does-point-to-local".

A more proper definition of the effect of this flag should be given.
Comment 17 Steven Bosscher 2010-07-13 10:21:25 UTC
From common.opt r161963:

Does nothing. Preserved for backward compatibility.

Does nothing. Preserved for backward compatibility.

Does nothing. Preserved for backward compatibility.

Does nothing. Preserved for backward compatibility.

This was changed in http://gcc.gnu.org/viewcvs?view=revision&revision=158060

The test case of comment #1 is now optimized on GIMPLE at -O2.

Richi, what should be done with this bug report, now that the flag doesn't even exist anymore?

Comment 18 Richard Biener 2010-07-13 11:10:54 UTC
Comment 19 Steven Bosscher 2010-07-13 11:27:13 UTC
Ehm, Richi, WONTFIX why?  Is this not what you added the alias attributes for?
Comment 20 Richard Biener 2010-07-13 13:29:56 UTC
The bug is confused now and mixes -fargument-* with other missed opts (which
I think are fixed with IPA-PTA and/or proper use of restricts or are dups
of other problems).

-fargument-noalias* problems are WONTFIX, as that options no longer exist.