alias analysis on llvm internal globals

Hi

I have this program in which fooBuf can only take on NULL or the
address of local_fooBuf, and fooBuf and local_fooBuf have scope of the
foo function.

Therefore there is no way for the fooPtr argument to alias with
fooBuf. However, LLVM basicaa and globalsmodref-aa say the 2 pointers
may alias.

I am thinking whether i should implement a limited form of point-to
alias on the fooBuf pointer in basicaa, i.e. looking at all stores to
it and computing what addresses it can take on and then compare with
fooPtr which can not point to local_fooBuf as it has a function
scope.

Also, LLVM global variables do not have seem to have scope
information. where can i get that information ?

Thanks,
Xin

int foo(int *fooPtr,int aconst)
{
    int i;
    int sum;
    int *fooOffsetPtr;
    static int init = 1;
    static int *fooBuf = NULL;
    static int local_fooBuf[512*4] = {};

    if (init == 1) {
        fooBuf = local_fooBuf;
        init = 0;
    }
    fooOffsetPtr = &fooBuf[aconst/2];
#pragma nounroll
    for (i=0;i<aconst;++i) {
        /// fooPtr can not point to the same memory location as fooOffsetPtr.
        fooPtr[i] = i; /// <------- HERE.
        /// should not this be moved out of the loop. at least, should not
        /// load fooOffsetPtr[0] be moved out of the loop. /// <------- HERE.
        sum += fooOffsetPtr[0];
    }
    return sum;
}

////////////////////////////////////////// opt -globalsmodref-aa -O3
ptr.ll -S //////////////////////////////////////////
@foo.init = internal unnamed_addr global i1 false
@foo.fooBuf = internal unnamed_addr global i32* null, align 8
@foo.local_fooBuf = internal global [2048 x i32] zeroinitializer, align 16

; Function Attrs: nounwind uwtable
define i32 @foo(i32* nocapture %fooPtr, i32 %aconst) #0 {
entry:
  %.b = load i1, i1* @foo.init, align 1
  br i1 %.b, label %entry.if.end_crit_edge, label %if.then

entry.if.end_crit_edge: ; preds = %entry
  %.pre = load i32*, i32** @foo.fooBuf, align 8, !tbaa !1
  br label %if.end

if.then: ; preds = %entry
  store i32* getelementptr inbounds ([2048 x i32]* @foo.local_fooBuf,
i64 0, i64 0), i32** @foo.fooBuf, align 8, !tbaa !1
  store i1 true, i1* @foo.init, align 1
  br label %if.end

if.end: ; preds =
%entry.if.end_crit_edge, %if.then
  %0 = phi i32* [ %.pre, %entry.if.end_crit_edge ], [ getelementptr
inbounds ([2048 x i32]* @foo.local_fooBuf, i64 0, i64 0), %if.then ]
  %div = sdiv i32 %aconst, 2
  %idxprom = sext i32 %div to i64
  %arrayidx = getelementptr inbounds i32, i32* %0, i64 %idxprom
  %cmp110 = icmp sgt i32 %aconst, 0
  br i1 %cmp110, label %for.body.preheader, label %for.end, !llvm.loop !5

for.body.preheader: ; preds = %if.end
  br label %for.body

for.body: ; preds =
%for.body.preheader, %for.body
  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0,
%for.body.preheader ]
  %sum.011 = phi i32 [ %add, %for.body ], [ undef, %for.body.preheader ]
  %arrayidx3 = getelementptr inbounds i32, i32* %fooPtr, i64 %indvars.iv
  %1 = trunc i64 %indvars.iv to i32
  store i32 %1, i32* %arrayidx3, align 4, !tbaa !7
  %2 = load i32, i32* %arrayidx, align 4, !tbaa !7
  %add = add nsw i32 %2, %sum.011
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
  %exitcond = icmp eq i32 %lftr.wideiv, %aconst
  br i1 %exitcond, label %for.end.loopexit, label %for.body, !llvm.loop !5

for.end.loopexit: ; preds = %for.body
  %add.lcssa = phi i32 [ %add, %for.body ]
  br label %for.end

for.end: ; preds =
%for.end.loopexit, %if.end
  %sum.0.lcssa = phi i32 [ undef, %if.end ], [ %add.lcssa, %for.end.loopexit ]
  ret i32 %sum.0.lcssa
}

Hi

I have this program in which fooBuf can only take on NULL or the
address of local_fooBuf, and fooBuf and local_fooBuf have scope of the
foo function.

Therefore there is no way for the fooPtr argument to alias with
fooBuf. However, LLVM basicaa and globalsmodref-aa say the 2 pointers
may alias.

I am thinking whether i should implement a limited form of point-to
alias on the fooBuf pointer in basicaa, i.e. looking at all stores to
it and computing what addresses it can take on and then compare with
fooPtr which can not point to local_fooBuf as it has a function
scope.

You don't want to do this in basicaa, you want to make a new pass that oes this.
Additionally, your real problem here is that it needs loop recurrence info.

Basically what you are trying to reproduce is SCEVAA

You need to have a pass to prove those static local’s addresses do not escape the function scope (i.e passed to calls, or stored to globals or other escaped memory locations). With that information available, the aliaser can then disambiguate accesses to them from argument pointers.

David

You need to have a pass to prove those static local's addresses do not
escape the function scope (i.e passed to calls, or stored to globals or
other escaped memory locations). With that information available, the
aliaser can then disambiguate accesses to them from argument pointers.

David

Yea. for static variables with function scope. LLVM translates it into
an internal global variable. but the scope information seems to be
lost. where can i recover that information or maybe should i implement
a pass to figure out that information before inlining and attache a
metadata to that static variable.

Thanks,
Xin