diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp @@ -599,9 +599,10 @@ // Check that this PHI type is allowed. if (!PhiTy->isIntegerTy() && !PhiTy->isFloatingPointTy() && !PhiTy->isPointerTy()) { + LLVM_DEBUG(dbgs() + << "LV: Not vectorizing: Found a non-int non-pointer PHI.\n"); ORE->emit(createMissedAnalysis("CFGNotUnderstood", Phi) << "loop control flow is not understood by vectorizer"); - LLVM_DEBUG(dbgs() << "LV: Found an non-int non-pointer PHI.\n"); return false; } @@ -967,7 +968,8 @@ // We must have a loop in canonical form. Loops with indirectbr in them cannot // be canonicalized. if (!Lp->getLoopPreheader()) { - LLVM_DEBUG(dbgs() << "LV: Loop doesn't have a legal pre-header.\n"); + LLVM_DEBUG(dbgs() + << "LV: Not vectorizing: Loop doesn't have a legal pre-header.\n"); ORE->emit(createMissedAnalysis("CFGNotUnderstood") << "loop control flow is not understood by vectorizer"); if (DoExtraAnalysis) @@ -978,6 +980,8 @@ // We must have a single backedge. if (Lp->getNumBackEdges() != 1) { + LLVM_DEBUG(dbgs() + << "LV: Not vectorizing: The loop must have a single backedge.\n"); ORE->emit(createMissedAnalysis("CFGNotUnderstood") << "loop control flow is not understood by vectorizer"); if (DoExtraAnalysis) @@ -988,6 +992,8 @@ // We must have a single exiting block. if (!Lp->getExitingBlock()) { + LLVM_DEBUG(dbgs() + << "LV: Not vectorizing: The loop must have an exiting block.\n"); ORE->emit(createMissedAnalysis("CFGNotUnderstood") << "loop control flow is not understood by vectorizer"); if (DoExtraAnalysis) @@ -1000,6 +1006,8 @@ // checked at the end of each iteration. With that we can assume that all // instructions in the loop are executed the same number of times. if (Lp->getExitingBlock() != Lp->getLoopLatch()) { + LLVM_DEBUG(dbgs() + << "LV: Not vectorizing: The exiting block is not the loop latch.\n"); ORE->emit(createMissedAnalysis("CFGNotUnderstood") << "loop control flow is not understood by vectorizer"); if (DoExtraAnalysis) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1432,6 +1432,9 @@ RPOT.perform(LI); if (!containsIrreducibleCFG(RPOT, *LI)) { V.push_back(&L); + LLVM_DEBUG(dbgs() << "LV: The loop '" + << L.getName() + << "' is eligible as supported.\n"); // TODO: Collect inner loops inside marked outer loops in case // vectorization fails for the outer loop. Do not invoke // 'containsIrreducibleCFG' again for inner loops when the outer loop is @@ -7579,16 +7582,22 @@ // legality and profitability checks. This means running the loop vectorizer // will simplify all loops, regardless of whether anything end up being // vectorized. - for (auto &L : *LI) - Changed |= + for (auto &L : *LI) { + bool Simplified = simplifyLoop(L, DT, LI, SE, AC, nullptr, false /* PreserveLCSSA */); + LLVM_DEBUG( + if (Simplified) + dbgs() << "LV: The loop '" << L->getName() << "' has been simplified.\n"; + ); + Changed |= Simplified; + } // Build up a worklist of inner-loops to vectorize. This is necessary as // the act of vectorizing or partially unrolling a loop creates new loops // and can invalidate iterators across the loops. SmallVector Worklist; - for (Loop *L : *LI) + for (auto &L : *LI) collectSupportedLoops(*L, LI, ORE, Worklist); LoopsAnalyzed += Worklist.size(); diff --git a/llvm/test/Transforms/LoopVectorize/legal_loop_config.ll b/llvm/test/Transforms/LoopVectorize/legal_loop_config.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/legal_loop_config.ll @@ -0,0 +1,58 @@ +; RUN: opt < %s -loop-vectorize -debug-only=loop-vectorize -S -o /dev/null 2>&1 | FileCheck %s +; REQUIRES: asserts + +; Make sure LV legal bails out when the exiting block != loop latch. +; CHECK-LABEL: "latch_is_not_exiting" +; CHECK: LV: Not vectorizing: The exiting block is not the loop latch. +define i32 @latch_is_not_exiting() { +entry: + br label %for.body + +for.body: + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ], [%inc, %for.second] + %inc = add nsw i32 %i.02, 1 + %cmp = icmp slt i32 %inc, 16 + br i1 %cmp, label %for.body, label %for.second + +for.second: + %cmps = icmp sgt i32 %inc, 16 + br i1 %cmps, label %for.body, label %for.end + +for.end: + ret i32 0 +} + +; Make sure LV legal bails out when there is no exiting block +; CHECK-LABEL: "no_exiting_block" +; CHECK: LV: Not vectorizing: The loop must have an exiting block. +define i32 @no_exiting_block() { +entry: + br label %for.body + +for.body: + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ], [%inc, %for.second] + %inc = add nsw i32 %i.02, 1 + %cmp = icmp slt i32 %inc, 16 + br i1 %cmp, label %for.body, label %for.second + +for.second: + br label %for.body +} + +; Make sure LV legal bails out when there is a non-int, non-ptr phi +; CHECK-LABEL: "invalid_phi_types" +; CHECK: LV: Not vectorizing: Found a non-int non-pointer PHI. +define i32 @invalid_phi_types() { +entry: + br label %for.body + +for.body: + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %vec.sum.02 = phi <2 x i32> [ zeroinitializer, %entry ], [ , %for.body ] + %inc = add nsw i32 %i.02, 1 + %cmp = icmp slt i32 %inc, 16 + br i1 %cmp, label %for.body, label %for.end + +for.end: + ret i32 0 +} diff --git a/llvm/test/Transforms/LoopVectorize/legal_preheader_check.ll b/llvm/test/Transforms/LoopVectorize/legal_preheader_check.ll --- a/llvm/test/Transforms/LoopVectorize/legal_preheader_check.ll +++ b/llvm/test/Transforms/LoopVectorize/legal_preheader_check.ll @@ -1,10 +1,10 @@ -; RUN: opt < %s -loop-vectorize -debug -S -o /dev/null 2>&1 | FileCheck %s +; RUN: opt < %s -loop-vectorize -debug-only=loop-vectorize -S -o /dev/null 2>&1 | FileCheck %s ; REQUIRES: asserts ; D40973 ; Make sure LV legal bails out when the loop doesn't have a legal pre-header. -; CHECK: LV: Loop doesn't have a legal pre-header. +; CHECK: LV: Not vectorizing: Loop doesn't have a legal pre-header. define void @inc(i32 %n, i8* %P) { %1 = icmp sgt i32 %n, 0