[LLVMdev] c const

Daniel Berlin dberlin at dberlin.org
Mon Aug 27 15:49:59 PDT 2007


On 8/26/07, Christopher Lamb <christopher.lamb at gmail.com> wrote:
> Hi Daniel,
>
> On Aug 24, 2007, at 10:20 AM, Daniel Berlin wrote:
>
> > On 8/22/07, Christopher Lamb <christopher.lamb at gmail.com> wrote:
> >>
> >>
> >> On Aug 22, 2007, at 3:48 PM, Duncan Sands wrote:
> >>
> >> Hi Christopher,
> >>
> >>
> >> If A and B are function arguments then there is no "based on"
> >> relationship between pointer expressions A+0 and B+0. This is because
> >> changing one of the pointers, A for example, to point to a copy of
> >> the object it points to would change the value of the pointer
> >> expression A+0, but not the expression B+0.
> >>
> >> I was assuming that *(A+0) and *(B+0) are pointer expressions.  Is
> >> that not the case?
> >> I believe the expressions you mention are indeed not  pointer
> >> expressions as
> >> they evaluate to a value of the pointed-to type rather than a
> >> pointer to the
> >> type. Only pointers may be "based on" other pointers from my
> >> reading of the
> >> spec.
> >
> > Christopher, just to point something out.
> >
> > Earlier you said that restrict says something about the relationship
> > of a pointer to non-restricted pointers.  This is not true except for
> > one small case.
> > Restricted pointers in general only tell you things about a
> > relationship to other restricted pointers.
>
> I'm not sure which previous statement was unclear, but I can believe
> I was a bit loose with the details on this point. My understanding is
> that as long as the analysis can determine the "based on"
> relationship between two pointers, then restrict does say something
> about those two pointers, even if one is not restrict.
>
> > IE the following is perfectly legal:
> >
> > int foo(int *a, restrict int *b)
> > {
> > int *c = a;
> >
> > a = b; (1)
> > *a = 90;
> > a = c; (2)
> > *a = 90;
> > }
>
> Here the alias analysis would be incorrect if it determined that the
> value of 'a' at point (2) was "based on" 'b'. This allows restrict to
> play a role in allowing the query alias(a(2), b) == No.

Any alias anlysis performed on SSA form will already get that (a(2),
b) = No without restrict.

Restrict answers no query you can't already answer here.

>
> Here's an example where restrict would have a harder time playing a
> role:
>
> int foo(int *a, restrict int *b)
> {
> int *c = bar(a, b);
>
> a = b; (1)
> *a = 90;
> a = c; (2)
> *a = 90;
> }
>

> Here 'a' at point (2) may be "based on" 'b', depending on the
> implementation of bar(). Unless the compiler can determine that the
> second parameter of bar() has no affect on its return value, then the
> alias analysis will have to return alias(a(2), b) == May.

Again, SSA form alias analysis takes care of this without restrict

> Indeed, if you are referring to Example 3 in 6.7.3.1 this does not
> imply that the compiler must determine that these pointers may or
> must alias.
>My reading of this example is that it explains that even
>though the compiler can assume that two restrict pointers, or even a
>restrict and a non-restrict pointer, do not alias, when those
>pointers point to the same object it will not lead to undefined
>behavior if the two pointers are not used to modify the objects they
>point to.
It says the example "illustrate how an unmodified object can be aliased
through two restricted pointers."

You cannot assume they do not alias simply because they are
restricted, as you claim, as the object they point to is not modified.
As a result, they must be assumed to alias unless you can prove
otherwise, and again, restrict does nothing.

You also say, following your example.
"
As neither p nor q is "based on" r, the alias analysis is free to
determine that they do not alias r given the restrict nature of q and
q. "

Where do you find support for this?  Nowhere in the function is an
pointer based on q modified, so why do you believe that you can
suddenly determine that q and r do not alias.

You can only assume that p and q do not alias, and p and r do not
alias, based on the restrict clause, as otherwise, it would invoke
undefined behavior.

I see no undefined behavior from q and r aliasing.

> > Restrict is sadly not that useful in the way the standard actually
> > specfiies.
>
> In practice I have actually found the restrict qualifier to be
> critical to generating efficient code in certain circumstances. These
> cases were specialized compute codes, however, not typically user apps.

I will bet you a large amount of money the compiler you are using and
seeing these performance gains is not implementing restrict properly.

In particular, they use it to say things about two loads when they shouldn't.


--Dan




More information about the llvm-dev mailing list