[llvm-commits] [llvm] r40624 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll

Dan Gohman djg at cray.com
Tue Jul 31 07:31:45 PDT 2007


> Log:
> Teach BasicAA about noalias function parameters. Passes all of DejaGNU and test-suite.

I just grepped through LLVM's test-suite and didn't find any uses of the
restrict keyword though...

>    // Pointing at a discernible object?
>    if (O1) {
> +    // Check for noalias attribute
> +    if (isa<Argument>(O1)) {
> +      const Argument *Arg = cast<Argument>(O1);
> +      const Function *Func = Arg->getParent();
> +      const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs();
> +      if (Attr) {
> +        unsigned Idx = 1;
> +        for (Function::const_arg_iterator I = Func->arg_begin(), 
> +              E = Func->arg_end(); I != E; ++I, ++Idx) {
> +          if (&(*I) == Arg && 
> +               Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
> +            return NoAlias;
> +        }
> +      }
> +    }

This logic is more aggressive than what C's restrict qualifier allows
in two ways.

For this testcase:

define void @foo(i32* noalias %p, i32* noalias %q, i32 %i, i32 %j) {
  %pi = getelementptr i32* %p, i32 %i
  %qi = getelementptr i32* %q, i32 %i
  %pj = getelementptr i32* %p, i32 %j
  %qj = getelementptr i32* %q, i32 %j
  store i32 0, i32* %p
  store i32 0, i32* %pi
  store i32 0, i32* %pj
  store i32 0, i32* %q
  store i32 0, i32* %qi
  store i32 0, i32* %qj
  ret void
}

basicaa is now saying this:
  15 no alias responses (100.0%)
  0 may alias responses (0.0%)
  0 must alias responses (0.0%)

The noalias logic should consider that a noalias pointer still aliases
itself. In this example, %p, %pi, and %pj should all MayAlias each other,
and %q, %qi, and %qj should all MayAlias each other.

Second, since you're mapping C's restrict qualifier on parameters to this
noalias attribute, it's necessary to consider cases like this:

declare i32* @unclear(i32* %a)

define void @foo(i32* noalias %x) {
  %y = call i32* @unclear(i32* %x)
  store i32 0, i32* %x
  store i32 0, i32* %y
  ret void
}

Right now basicaa is saying NoAlias for %x and %y. The answer should be
MayAlias, because %y may legally be "based on" %x. There's nothing in the
definition of restrict that says that "based on" relationships must be
obvious to a compiler.

So for an alias query where one of the two pointers is noalias and the
other is not, and the non-noalias one doesn't have a base object that
basicaa can find, the answer should be MayAlias. A more advanced pass
could try to prove that the non-noalias pointer couldn't possibly be
"based on" the noalias one by examining all its uses, though the specific
example here would defy such analysis.

> +      // Check for noalias atrribute independently from above logic
> +      if (isa<Argument>(O2)) {
> +        const Argument *Arg = cast<Argument>(O2);
> +        const Function *Func = Arg->getParent();
> +        const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs();
> +        if (Attr) {
> +          unsigned Idx = 1;
> +          for (Function::const_arg_iterator I = Func->arg_begin(), 
> +                E = Func->arg_end(); I != E; ++I, ++Idx) {
> +            if (&(*I) == Arg && 
> +                 Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
> +              return NoAlias;
> +          }
> +        }
> +      }

Same as above.

Dan

-- 
Dan Gohman, Cray Inc.



More information about the llvm-commits mailing list