Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2695,8 +2695,21 @@ if (C->isZero()) return; - assert(!BB->getParent()->hasOptSize() && - "Cannot SCEV check stride or overflow when optimizing for size"); + // FIXME: we should gracefully bail a lot earlier. The problem is that + // in runtimeChecksRequired(), where code-size increase is checked the first + // time, everything is different as e.g. unrolling is not applied yet. Thus, + // the SCEV information is different, and won't find any SCEV predicates, + // which we do find later, resulting in emitting SCEV runtime checks. As a + // workaround, we emit an optimization remark warning about the increase. + if (BB->getParent()->hasOptSize()) { + ORE->emit([&]() { + return OptimizationRemarkAnalysis(DEBUG_TYPE, "VectorizationCodeSize", + L->getStartLoc(), L->getHeader()) + << "Optimizing for size, but overflow checks are emitted. Can " + "this be avoided by e.g. using a larger loop induction " + "variable type?"; + }); + } // Create a new block containing the stride check. BB->setName("vector.scevcheck"); Index: llvm/test/Transforms/LoopVectorize/pr43371-optsize-scevchecks.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/pr43371-optsize-scevchecks.ll @@ -0,0 +1,41 @@ +; RUN: opt -S -loop-vectorize -pass-remarks-analysis='loop-vectorize' < %s 2>&1 | FileCheck %s + +@cm_array = external global [2592 x i16], align 1 + +define void @pr43371() optsize { +; +; remark: :0:0: Optimizing for size, but overflow checks are emitted. Can this be avoided by e.g. using a larger loop induction variable type? + +; CHECK-LABEL: @pr43371 +; +; FIXME: SCEV checks need to emitted. So when optimizing for size, we shouldn't +; vectorize this. +; +; CHECK: vector.scevcheck: +; CHECK: vector.body: +; +entry: + br label %for.body + +for.cond.for.cond.cleanup_crit_edge: + br label %for.body29 + +for.body: + br label %for.cond.for.cond.cleanup_crit_edge + +for.cond.cleanup28: + unreachable + +for.body29: + %i24.0170 = phi i16 [ 0, %for.cond.for.cond.cleanup_crit_edge ], [ %inc37, %for.inc36 ] + %add33 = add i16 undef, %i24.0170 + %idxprom34 = zext i16 %add33 to i32 + %arrayidx35 = getelementptr [2592 x i16], [2592 x i16] * @cm_array, i32 0, i32 %idxprom34 + store i16 0, i16 * %arrayidx35, align 1 + br label %for.inc36 + +for.inc36: + %inc37 = add i16 %i24.0170, 1 + %cmp26 = icmp ult i16 %inc37, 756 + br i1 %cmp26, label %for.body29, label %for.cond.cleanup28 +}