[llvm-dev] Canonicalize induction variables

Ehsan Amiri via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 25 13:30:42 PDT 2016


But even for a very simple loop:

int test1 (int *x, int *y, int *z, int k) {
  int sum = 0;
  for (int i = 10; i < k; i++) {
    z[i] = x[i] / y[i];
  }
  return sum;
}

The initial value of induction variable is not zero after compiling with
-O3 -mcpu=power8 x.cpp -S -c -emit-llvm -fno-unroll-loops (see bottom of
the email for IR)

Also I can write somewhat more complicated loop where step size is a
constant > 1, and the conditions are so that IV will not overflow:

int test2 (int *x, int *y, int *z, int k) {
  int sum = 0;
  for (int i = 10; i < k && i < k-5; i+=5) {
    z[i] = x[i] / y[i];
  }
  return sum;
}

again this is not canonicalized in the above sense (see IR at the end of
the email). Maybe this condition is too complicated?















IR for test1


for.body:                                         ; preds =
%for.body.preheader, %for.body
*  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 10,
%for.body.preheader ]*
  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  %0 = load i32, i32* %arrayidx, align 4, !tbaa !1
  %arrayidx2 = getelementptr inbounds i32, i32* %y, i64 %indvars.iv
  %1 = load i32, i32* %arrayidx2, align 4, !tbaa !1
  %div = sdiv i32 %0, %1
  %arrayidx4 = getelementptr inbounds i32, i32* %z, i64 %indvars.iv
  store i32 %div, i32* %arrayidx4, align 4, !tbaa !1
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
  br i1 %exitcond, label %for.cond.cleanup, label %for.body

IR for test2

for.body:                                         ; preds =
%for.body.preheader, %for.body
*  %indvars.iv = phi i64 [ 10, %for.body.preheader ], [ %indvars.iv.next,
%for.body ]*
  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
  %2 = load i32, i32* %arrayidx, align 4, !tbaa !1
  %arrayidx3 = getelementptr inbounds i32, i32* %y, i64 %indvars.iv
  %3 = load i32, i32* %arrayidx3, align 4, !tbaa !1
  %div = sdiv i32 %2, %3
  %arrayidx5 = getelementptr inbounds i32, i32* %z, i64 %indvars.iv
  store i32 %div, i32* %arrayidx5, align 4, !tbaa !1
*  %indvars.iv.next = add nuw i64 %indvars.iv, 5*
  %cmp = icmp slt i64 %indvars.iv.next, %1
  %cmp1 = icmp slt i64 %indvars.iv.next, %0
  %or.cond = and i1 %cmp, %cmp1
  br i1 %or.cond, label %for.body, label %for.cond.cleanup.loopexit



On Thu, Aug 25, 2016 at 4:02 PM, Michael Kruse via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Not sure whether these are the actual reasons, but to explain the
> difficulties with those loops.
>
> 2016-08-25 3:48 GMT+02:00 Yaoqing Gao via llvm-dev <
> llvm-dev at lists.llvm.org>:
> > I just subscribed this group.  This is my first time to post a question
> (not
> > sure if this is a right place for discussion) after I have a brief look
> at
> > LLVM OPT (dev trunk).   I would expect loop simplification and induction
> > variable canonicalization pass (IndVarSimplify pass) should be able to
> > convert the following loops into a simple canonical form, i.e., there is
> a
> > canonical induction variable which starts at zero and steps by one,
> > getCanonicalInductionVariable() returns  the first PHI node in the loop
> > header block.
> >
> > int test1 (int x[], int k, int s) {
> >   int sum = 0;
> >   for (int i = 0; i < k; i+=s) {
> >     sum += x[i];
> >   }
> >   return sum;
> > }
>
> s could be zero making this an endless loop (C has some rules saying
> that it can assume that certain loops do terminate, but I think it
> does not apply to LLVM IR)
>
>
> > int test2(int x[], int k, int s) {
> >   int sum = 0;
> >   for (int i = k; i > 0; i--) {
> >     sum += x[i];
> >   }
> >   return sum;
> > }
>
> with k = INT_MIN where is no upper limit in that range. Neither
>
> for (int j = 0; j < -INT_MIN; j++)
>
> nor
>
> for (int j = 0; j <= INT_MAX; j++)
>
> do work here.
>
> >
> > Anyone can help explain why the current LLVM cannot canonicalize
> induction
> > variables for the above loops (by design or a limitation to be fixed in
> the
> > future)?  Thanks.
>
> The first could be tackled with loop versioning of the s==0 case. The
> second might be converted to
>
> for (int j = -1; j < -(k+1); j++)
>
> although this isn't the canonical form.
>
>
> Michael
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160825/c2f1a537/attachment.html>


More information about the llvm-dev mailing list