[LLVMdev] loop vectorizer
Nadav Rotem
nrotem at apple.com
Wed Oct 30 09:25:09 PDT 2013
Hi Frank,
The access pattern to arrays a and b is non-linear. Unrolled loops are usually handled by the SLP-vectorizer. Are ir0 and ir1 consecutive for all values for i ?
Thanks,
Nadav
On Oct 30, 2013, at 9:05 AM, Frank Winter <fwinter at jlab.org> wrote:
> The loop vectorizer seems to be not able to vectorize the following code:
>
> void bar(std::uint64_t start, std::uint64_t end, float * __restrict__ c, float * __restrict__ a, float * __restrict__ b)
> {
> const std::uint64_t inner = 4;
> for (std::uint64_t i = start ; i < end ; ++i ) {
> const std::uint64_t ir0 = ( (i/inner) * 2 + 0 ) * inner + i%4;
> const std::uint64_t ir1 = ( (i/inner) * 2 + 1 ) * inner + i%4;
> c[ ir0 ] = a[ ir0 ] + b[ ir0 ];
> c[ ir1 ] = a[ ir1 ] + b[ ir1 ];
> }
> }
>
> LV: Found a loop: for.body
> LV: Found an induction variable.
> LV: We need to do 0 pointer comparisons.
> LV: Checking memory dependencies
> LV: Bad stride - Not an AddRecExpr pointer %arrayidx11 = getelementptr inbounds float* %c, i64 %add2 SCEV: ((4 * %add2)<nsw> + %c)<nsw>
> LV: Bad stride - Not an AddRecExpr pointer %arrayidx15 = getelementptr inbounds float* %c, i64 %add8 SCEV: ((4 * %add8)<nsw> + %c)<nsw>
> LV: Src Scev: ((4 * %add2)<nsw> + %c)<nsw>Sink Scev: ((4 * %add8)<nsw> + %c)<nsw>(Induction step: 0)
> LV: Distance for store float %add10, float* %arrayidx11, align 4 to store float %add14, float* %arrayidx15, align 4: ((4 * %add8)<nsw> + (-4 * %add2))
> Non-consecutive pointer access
> LV: We don't need a runtime memory check.
> LV: Can't vectorize due to memory conflicts
> LV: Not vectorizing.
>
> Here the code:
>
> entry:
> %cmp14 = icmp ult i64 %start, %end
> br i1 %cmp14, label %for.body, label %for.end
>
> for.body: ; preds = %entry, %for.body
> %i.015 = phi i64 [ %inc, %for.body ], [ %start, %entry ]
> %div = lshr i64 %i.015, 2
> %mul = shl i64 %div, 3
> %rem = and i64 %i.015, 3
> %add2 = or i64 %mul, %rem
> %add8 = or i64 %add2, 4
> %arrayidx = getelementptr inbounds float* %a, i64 %add2
> %0 = load float* %arrayidx, align 4
> %arrayidx9 = getelementptr inbounds float* %b, i64 %add2
> %1 = load float* %arrayidx9, align 4
> %add10 = fadd float %0, %1
> %arrayidx11 = getelementptr inbounds float* %c, i64 %add2
> store float %add10, float* %arrayidx11, align 4
> %arrayidx12 = getelementptr inbounds float* %a, i64 %add8
> %2 = load float* %arrayidx12, align 4
> %arrayidx13 = getelementptr inbounds float* %b, i64 %add8
> %3 = load float* %arrayidx13, align 4
> %add14 = fadd float %2, %3
> %arrayidx15 = getelementptr inbounds float* %c, i64 %add8
> store float %add14, float* %arrayidx15, align 4
> %inc = add i64 %i.015, 1
> %exitcond = icmp eq i64 %inc, %end
> br i1 %exitcond, label %for.end, label %for.body
>
> for.end: ; preds = %for.body, %entry
> ret void
>
> Why is it saying Bad stride?Are the 'rem' and 'div' instruction asking too much from it?
>
> The code should be vectorizable. Here the index access for start=0, end=16:
>
> loop count i = 0 index_0 = 0 index_1 = 4
> loop count i = 1 index_0 = 1 index_1 = 5
> loop count i = 2 index_0 = 2 index_1 = 6
> loop count i = 3 index_0 = 3 index_1 = 7
> loop count i = 4 index_0 = 8 index_1 = 12
> loop count i = 5 index_0 = 9 index_1 = 13
> loop count i = 6 index_0 = 10 index_1 = 14
> loop count i = 7 index_0 = 11 index_1 = 15
> loop count i = 8 index_0 = 16 index_1 = 20
> loop count i = 9 index_0 = 17 index_1 = 21
> loop count i = 10 index_0 = 18 index_1 = 22
> loop count i = 11 index_0 = 19 index_1 = 23
> loop count i = 12 index_0 = 24 index_1 = 28
> loop count i = 13 index_0 = 25 index_1 = 29
> loop count i = 14 index_0 = 26 index_1 = 30
> loop count i = 15 index_0 = 27 index_1 = 31
>
> Any ideas?
>
> Frank
>
>
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
More information about the llvm-dev
mailing list