------- 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