[LLVMdev] alias analysis on llvm internal globals

Xin Tong trent.tong at gmail.com
Sat Apr 25 16:32:05 PDT 2015


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
}



More information about the llvm-dev mailing list