<div dir="ltr">Hi, <br><br>I wrote a small test case and tried to force epilog vectorization for the loop.<br><br>void foo(double * restrict  a,  double * restrict b, int N) {<br>for(int i = 0; i < N; ++i)<br>       a[i] = sin(i);<br>}<br><br>clang -O3 -mavx2 -fveclib=libmvec sin.c -mllvm -epilogue-vectorization-minimum-VF=4 -S  -emit-llvm -fno-unroll-loops<br><br>But I ended up with epilog vectorization failing at this check.<br>In the function "isCandidateForEpilogueVectorization", I find the below check.<div><br></div><div>-- Snip llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --<br><br>// Induction variables that are widened require special handling that is<br>// currently not supported.<br>if (any_of(Legal->getInductionVars(), [&](auto &Entry) {<br>       return !(this->isScalarAfterVectorization(Entry.first, VF) ||<br>                  this->isProfitableToScalarize(Entry.first, VF));<br>-- Snip -- </div><div><br>I understand that when induction variables are widened as per the VPLAN , we don't support such loops <br>for epilog vectorization at the moment. <br><br>But can someone please explain the "special handling" we need to do here?<br><br>If I remove the check from the source, the epilog vectorization is happening, but the generated LLVM IR seems to be wrong. <br><br>---Snip--<br><br>12:                                               ; preds = %12, %10<br>  %13 = phi i64 [ 0, %10 ], [ %19, %12 ]<br>  %14 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %10 ], [ %20, %12 ]<br>  %15 = sitofp <4 x i32> %14 to <4 x double><br>  %16 = call <4 x double> @_ZGVdN4v_sin(<4 x double> %15)<br>  %17 = getelementptr inbounds double, double* %0, i64 %13<br>  %18 = bitcast double* %17 to <4 x double>*<br>  store <4 x double> %16, <4 x double>* %18, align 8, !tbaa !3<br>  %19 = add nuw i64 %13, 4<br>  %20 = add <4 x i32> %14, <i32 4, i32 4, i32 4, i32 4><br>  %21 = icmp eq i64 %19, %11<br>  br i1 %21, label %22, label %12, !llvm.loop !7<br><br>22:                                               ; preds = %12<br>  %23 = icmp eq i64 %11, %6<br>  br i1 %23, label %44, label %24<br><br>24:                                               ; preds = %22<br>  %25 = and i64 %6, 2<br>  %26 = icmp eq i64 %25, 0<br>  br i1 %26, label %42, label %27<br><br>27:                                               ; preds = %8, %24<br>  %28 = phi i64 [ %11, %24 ], [ 0, %8 ]<br>  %29 = and i64 %6, 4294967294<br>  br label %30<br><br>30:                                               ; preds = %30, %27<br>  %31 = phi i64 [ %28, %27 ], [ %37, %30 ]<br>  %32 = phi <2 x i32> [ <i32 0, i32 1>, %27 ], [ %38, %30 ]             <== Resume value seem to be wrong. <br>  %33 = sitofp <2 x i32> %32 to <2 x double><br>  %34 = call <2 x double> @_ZGVbN2v_sin(<2 x double> %33)<br>  %35 = getelementptr inbounds double, double* %0, i64 %31<br>  %36 = bitcast double* %35 to <2 x double>*<br>  store <2 x double> %34, <2 x double>* %36, align 8, !tbaa !3<br>  %37 = add nuw i64 %31, 2<br>  %38 = add <2 x i32> %32, <i32 2, i32 2><br>  %39 = icmp eq i64 %37, %29<br>  br i1 %39, label %40, label %30, !llvm.loop !11<br>--- Snip--<br><br>I see the resume value for the widened phi node in the epilog loop is not updated correctly.<br>Are there any other issues here apart from handling the widened induction variable's resume value ?<br></div><div><br></div><div>Regards,</div><div>Venkat.</div></div>