Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1649,7 +1649,7 @@ /// Return true if all of the instructions in the block can be speculatively /// executed. \p SafePtrs is a list of addresses that are known to be legal /// and we know that we can read from them without segfault. - bool blockCanBePredicated(BasicBlock *BB, SmallPtrSetImpl &SafePtrs); + bool blockCanBePredicated(BasicBlock *BB, SmallPtrSetImpl &SafePtrs, Instruction **SelectRemarkInstruction); /// Updates the vectorization state by adding \p Phi to the inductions list. /// This can set \p Phi as the main induction of the loop if \p Phi is a @@ -4800,9 +4800,10 @@ // We must be able to predicate all blocks that need to be predicated. if (blockNeedsPredication(BB)) { - if (!blockCanBePredicated(BB, SafePointes)) { - ORE->emit(createMissedAnalysis("NoCFGForSelect", BB->getTerminator()) - << "control flow cannot be substituted for a select"); + Instruction *SelectRemarkInstruction; + if (!blockCanBePredicated(BB, SafePointes, &SelectRemarkInstruction)) { + ORE->emit(createMissedAnalysis("NoCFGForSelect", SelectRemarkInstruction) + << "if-conversion not possible due to lack of support for predication"); return false; } } else if (BB != Header && !canIfConvertPHINodes(BB)) { @@ -5668,21 +5669,25 @@ } bool LoopVectorizationLegality::blockCanBePredicated( - BasicBlock *BB, SmallPtrSetImpl &SafePtrs) { + BasicBlock *BB, SmallPtrSetImpl &SafePtrs, Instruction **SelectRemarkInstruction) { const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel(); for (Instruction &I : *BB) { // Check that we don't have a constant expression that can trap as operand. for (Value *Operand : I.operands()) { if (auto *C = dyn_cast(Operand)) - if (C->canTrap()) - return false; + if (C->canTrap()) { + *SelectRemarkInstruction = &I; + return false; + } } // We might be able to hoist the load. if (I.mayReadFromMemory()) { auto *LI = dyn_cast(&I); - if (!LI) + if (!LI) { + *SelectRemarkInstruction = &I; return false; + } if (!SafePtrs.count(LI->getPointerOperand())) { // !llvm.mem.parallel_loop_access implies if-conversion safety. // Otherwise, record that the load needs (real or emulated) masking @@ -5695,8 +5700,10 @@ if (I.mayWriteToMemory()) { auto *SI = dyn_cast(&I); - if (!SI) + if (!SI) { + *SelectRemarkInstruction = &I; return false; + } // Predicated store requires some form of masking: // 1) masked store HW instruction, // 2) emulation via load-blend-store (only if safe and legal to do so, @@ -5705,8 +5712,10 @@ MaskedOp.insert(SI); continue; } - if (I.mayThrow()) + if (I.mayThrow()) { + *SelectRemarkInstruction = &I; return false; + } } return true; Index: test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll =================================================================== --- test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll +++ test/Transforms/LoopVectorize/X86/vectorization-remarks-missed.ll @@ -45,7 +45,7 @@ ; } ; return k; ; } -; CHECK: remark: source.cpp:29:7: loop not vectorized: control flow cannot be substituted for a select +; CHECK: remark: source.cpp:29:11: loop not vectorized: if-conversion not possible due to lack of support for predication ; CHECK: remark: source.cpp:27:3: loop not vectorized ; YAML: --- !Analysis @@ -105,11 +105,11 @@ ; YAML-NEXT: --- !Analysis ; YAML-NEXT: Pass: loop-vectorize ; YAML-NEXT: Name: NoCFGForSelect -; YAML-NEXT: DebugLoc: { File: source.cpp, Line: 29, Column: 7 } +; YAML-NEXT: DebugLoc: { File: source.cpp, Line: 29, Column: 11 } ; YAML-NEXT: Function: test_multiple_failures ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'loop not vectorized: ' -; YAML-NEXT: - String: control flow cannot be substituted for a select +; YAML-NEXT: - String: if-conversion not possible due to lack of support for predication ; YAML-NEXT: ... ; YAML-NEXT: --- !Analysis ; YAML-NEXT: Pass: loop-vectorize