[PATCH] D118808: Loop Strength Reduce - Optimize unused IVs to final values in the exit block with SCEV

Zaara Syeda via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 2 10:16:20 PST 2022


syzaara added a comment.

In D118808#3290873 <https://reviews.llvm.org/D118808#3290873>, @lebedev.ri wrote:

> This is normally a IndVar's problem, but i guess LSR runs so late that there is no IndVar's scheduled after it?
> Do you have a phase-ordering test showing this missing simplification?

Are you referring to IndVarSimplify? Yes, it looks LSR is run after IndVarSimplify.
I thought to implement it in LSR because LSR is the one that was responsible for optimizing away the uses of the IV but leaving behind the single use of increments in the loop.
Here is an example testcase:

  int do_work(int * a, int m, int n, int x, int* b) {
     int i,j;
     for( j = 0 ; j < m ; j++ ) {
        for( i = 0 ; i < n ; i++ )
        {
           a[i] += x*b[i];
        }
     }
     return x;
  }

Before LSR, we have:

  for.body3.us.prol:                                ; preds = %for.body3.us.prol.preheader, %for.body3.us.prol
   %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %for.body3.us.prol ], [ %indvars.iv.ph, %for.body3.us.prol.preheader ]
    %prol.iter = phi i64 [ %prol.iter.next, %for.body3.us.prol ], [ 0, %for.body3.us.prol.preheader ]
    %arrayidx.us.prol = getelementptr inbounds i32, i32* %b, i64 %indvars.iv.prol <------
    %30 = load i32, i32* %arrayidx.us.prol, align 4, !tbaa !3
    %mul.us.prol = mul nsw i32 %30, %x
    %arrayidx5.us.prol = getelementptr inbounds i32, i32* %a, i64 %indvars.iv.prol <------
    %31 = load i32, i32* %arrayidx5.us.prol, align 4, !tbaa !3
    %add.us.prol = add nsw i32 %31, %mul.us.prol
    store i32 %add.us.prol, i32* %arrayidx5.us.prol, align 4, !tbaa !3
    %indvars.iv.next.prol = add nuw nsw i64 %indvars.iv.prol, 1 <------
    %prol.iter.next = add i64 %prol.iter, 1
    %prol.iter.cmp.not = icmp eq i64 %prol.iter.next, %xtraiter
    br i1 %prol.iter.cmp.not, label %for.body3.us.prol.loopexit.loopexit, label %for.body3.us.prol, !llvm.loop !15

After LSR, all uses of %indvars.iv.prol are removed:

  for.body3.us.prol:                                ; preds = %for.body3.us.prol.preheader, %for.body3.us.prol
    %lsr.iv120 = phi i64 [ %30, %for.body3.us.prol.preheader ], [ %lsr.iv.next, %for.body3.us.prol ]
    %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %for.body3.us.prol ], [ %indvars.iv.ph, %for.body3.us.prol.preheader ]
    %prol.iter = phi i64 [ %prol.iter.next, %for.body3.us.prol ], [ 0, %for.body3.us.prol.preheader ]
    %uglygep125 = getelementptr i8, i8* %b124, i64 %lsr.iv120 <------
    %uglygep125126 = bitcast i8* %uglygep125 to i32*
    %31 = load i32, i32* %uglygep125126, align 4, !tbaa !3
    %mul.us.prol = mul nsw i32 %31, %x
    %uglygep122 = getelementptr i8, i8* %a121, i64 %lsr.iv120 <------
    %uglygep122123 = bitcast i8* %uglygep122 to i32*
    %32 = load i32, i32* %uglygep122123, align 4, !tbaa !3
    %add.us.prol = add nsw i32 %32, %mul.us.prol
    store i32 %add.us.prol, i32* %uglygep122123, align 4, !tbaa !3
    %indvars.iv.next.prol = add nuw nsw i64 %indvars.iv.prol, 1
    %prol.iter.next = add i64 %prol.iter, 1
    %lsr.iv.next = add nuw nsw i64 %lsr.iv120, 4
    %prol.iter.cmp.not = icmp eq i64 %prol.iter.next, %xtraiter
    br i1 %prol.iter.cmp.not, label %for.body3.us.prol.loopexit.loopexit, label %for.body3.us.prol, !llvm.loop !15

But there is no follow on to remove unused %indvars.iv.next.prol within the loop.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118808/new/

https://reviews.llvm.org/D118808



More information about the llvm-commits mailing list