------- Comment #27 from dberlin at gcc dot gnu dot org  2006-08-27 20:51 
-------
Subject: Re:  [4.0/4.1/4.2 Regression] alias bug with cast and call clobbered

> I don't understand how TBAA is interacting with the may-alias information.

Given a pointer, and some aliases, we ask TBAA, for each alias, "is it
possible for a load or store of this type to access this variable, of
this other type".  We use the results to answer a different question,
"is it possible for a call to function foo, which is being passed this
pointer, to access this variable".

>

> In particular, TBAA doesn't say anything about casts; it says something about
> loads and stores.  In particular, TBAA forbids accessing storage of type A
> through a pointer to type B, given certain constraints on A and B.  It does 
> not
> forbid casting an A* to a B*.

Correct.

>
> Why are the optimizers pruning may-alias sets on casts?
They are not..

>  Why isn't the fix just to stop them from doing that?
Because they are not doing that..

If you look at Andrew's complete, reduced, testcase, you will see that
what is happening is that pretty much the same as what will happen
given:

int bar(void)
{
float a;
float *b1;
int *b2;

a = 5.0;
b1 = &a;
b2 = (int *)b1;
foo(b2);
}

void foo(int *a)
{
  float *b = a;
  printf ("%f", *b); /* Or some other use of b */
  *b = 9.0;
}

I'm going to use clobbering here to mean both mod and ref, because for
our purposes, it doesn't matter.

What happens is that call clobbering is using the may-alias sets to
try to determine call clobbering.

However, the may-alias set of "b2" in function "bar" will *not*
include "a", because a dereference of b2 can *not* validly access "a"
according to TBAA.

Thus, we will claim variable "a" is *not* clobbered by the call to
foo, because it won't appear in the may-alias set of "b2", and we
compute answers to clobbering questions using alias sets.  However, it
*is* validly clobbered, because it is casted back to the right type in
foo, and stored into.

The effect of not marking it clobbered in the *actual testcase* (not
above) will be that DCE will delete the initial store, because it
appears entirely local, due to missing that it could be dereferenced
by the call.

This testcase has been failing since we started using may-alias sets
for determining call-clobbering, which is 4.0.

This is just a subtle difference between aliasing and clobbering.
Aliasing asks about stores and loads, Clobbering asks about calls.

In the context of "can a load or store to b2 access a" (the aliasing
question), the answer is no.
In the context of "can the call to foo do something that uses or
modifies our local variable a" (the clobbering question) ,the answer
is yes, *even though it can't happen directly through an access to
b2*.

Thus, the correct solution is to compute the sets used to answer the
question "what can be read/modified by a call to a function" separate
from the sets used to answer the question "what can be loaded/stored
by a dereference of this variable".

Since we have never done that before, it does require new code.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28778

Reply via email to