; REQUIRES: asserts ; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize --disable-output \ ; RUN: -epilogue-tail-folding-policy=prefer-fold-tail -pass-remarks-analysis=loop-vectorize 2>&1 | FileCheck %s ; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize -enable-epilogue-vectorization=false \ ; RUN: --disable-output -epilogue-tail-folding-policy=prefer-fold-tail -pass-remarks-analysis=loop-vectorize 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-DISABLED-EPILOG define void @test_epilogue_tf(ptr %A, i64 %n) { ; CHECK-LABEL: LV: Checking a loop in 'test_epilogue_tf' ; CHECK: LV: epilogue tail-folding is not supported yet ; CHECK: remark: :0:0: The epilogue-tail-folding policy prefer-fold-tail is not supported yet, fall back to a normal epilogue ; entry: br label %for.body for.body: %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] %arrayidx = getelementptr inbounds i8, ptr %A, i64 %iv store i8 1, ptr %arrayidx, align 1 %iv.next = add nuw nsw i64 %iv, 1 %exitcond = icmp ne i64 %iv.next, %n br i1 %exitcond, label %for.body, label %exit exit: ret void } define void @epilogue_is_disabled(ptr %a, i64 %n) { ; CHECK-DISABLED-EPILOG-LABEL: LV: Checking a loop in 'epilogue_is_disabled' ; CHECK-DISABLED-EPILOG: remark: :0:0: Options conflict, epilogue vectorization is disallowed while epilogue tail-folding allowed! ; entry: br label %for.body for.body: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv store i32 1, ptr %arrayidx, align 4 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 %exitcond = icmp ne i64 %indvars.iv.next, %n br i1 %exitcond, label %for.body, label %for.end for.end: ret void } define i16 @require_scalar_epilogue(ptr %dst, i64 %x) { ; CHECK-LABEL: LV: Checking a loop in 'require_scalar_epilogue' ; CHECK: LV: Epilogue tail-folding can't be applied because scalar epilogue is required ; CHECK-NEXT: LV: Fall back to a normal epilogue ; entry: br label %loop.header loop.header: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] %gep = getelementptr inbounds i32, ptr %dst, i64 %iv store i64 0, ptr %gep br label %loop.then loop.then: %cmp3 = icmp ne i64 %iv, %x br i1 %cmp3, label %loop.latch, label %exit.1 loop.latch: %iv.next = add i64 %iv, 1 br label %loop.header exit.1: ret i16 0 exit.2: ret i16 1 } define i32 @opt_for_size(ptr %p, i32 %n) optsize { ; CHECK-LABEL: LV: Checking a loop in 'opt_for_size' ; CHECK: LV: No epilogue to apply tail-folding for. ; CHECK-NEXT: LV: Fall back to a normal epilogue ; entry: br label %for.body for.body: %iv = phi i32 [ 0, %entry ], [ %inc, %for.body ] %arrayidx = getelementptr inbounds i32, ptr %p, i32 %iv %0 = load i32, ptr %arrayidx, align 1 %cmp1 = icmp eq i32 %0, 0 %sel = select i1 %cmp1, i32 2, i32 1 store i32 %sel, ptr %arrayidx, align 1 %inc = add nsw i32 %iv, 1 %exitcond = icmp eq i32 %inc, %n br i1 %exitcond, label %for.end, label %for.body for.end: ret i32 0 }