Index: llvm/include/llvm/Analysis/VectorUtils.h =================================================================== --- llvm/include/llvm/Analysis/VectorUtils.h +++ llvm/include/llvm/Analysis/VectorUtils.h @@ -96,6 +96,11 @@ assert(hasValidParameterList() && "Invalid parameter list"); } + // Get trivial mapping to scalar function for VF=1 + static VFShape getTriivalMapping(const CallInst &CI) { + return VFShape::get(CI, {1, false}, false); + } + // Retrieve the basic vectorization shape of the function, where all // parameters are mapped to VFParamKind::Vector with \p EC // lanes. Specifies whether the function has a Global Predicate @@ -239,10 +244,14 @@ /// /// @{ /// Retrieve the Function with VFShape \p Shape. - Function *getVectorizedFunction(const VFShape &Shape) const { - for (const auto &Info : ScalarToVectorMappings) + Function *getVectorizedFunction(const VFShape &Shape, + const CallInst &CI) const { + for (const auto &Info : ScalarToVectorMappings) { + if (Shape == VFShape::getTriivalMapping(CI)) + return M->getFunction(Info.ScalarName); if (Info.Shape == Shape) return M->getFunction(Info.VectorName); + } return nullptr; } Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3295,7 +3295,7 @@ // cost is the cost we need to return. NeedToScalarize = true; VFShape Shape = VFShape::get(*CI, {VF, false}, false /*HasGlobalPred*/); - Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape); + Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape, *CI); if (!TLI || CI->isNoBuiltin() || !VecFunc) return Cost; @@ -4388,13 +4388,14 @@ VFShape::get(*CI, {VF, false} /*EC*/, false /*HasGlobalPred*/); #ifndef NDEBUG const SmallVector Infos = VFDatabase::getMappings(*CI); - assert(std::find_if(Infos.begin(), Infos.end(), - [&Shape](const VFInfo &Info) { - return Info.Shape == Shape; - }) != Infos.end() && + assert((std::find_if(Infos.begin(), Infos.end(), + [&Shape](const VFInfo &Info) { + return Info.Shape == Shape; + }) != Infos.end() || + VF == 1) && "Vector function shape is missing from the database."); #endif - VectorF = VFDatabase(*CI).getVectorizedFunction(Shape); + VectorF = VFDatabase(*CI).getVectorizedFunction(Shape, *CI); } assert(VectorF && "Can't create vector function."); Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -3249,7 +3249,7 @@ auto Shape = VFShape::get(*CI, {static_cast(VecTy->getNumElements()), false}, false /*HasGlobalPred*/); - Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape); + Function *VecFunc = VFDatabase(*CI).getVectorizedFunction(Shape, *CI); int LibCost = IntrinsicCost; if (!CI->isNoBuiltin() && VecFunc) { // Calculate the cost of the vector library call. @@ -4511,7 +4511,7 @@ VFShape Shape = VFShape::get( *CI, {static_cast(VecTy->getNumElements()), false}, false /*HasGlobalPred*/); - CF = VFDatabase(*CI).getVectorizedFunction(Shape); + CF = VFDatabase(*CI).getVectorizedFunction(Shape, *CI); } SmallVector OpBundles; Index: llvm/test/Transforms/LoopVectorize/scalarizeVFne.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/scalarizeVFne.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -passes=loop-vectorize -S 2>&1 | FileCheck %s +; REQUIRES: asserts + +target triple = "powerpc64le-unknown-linux-gnu" +%type = type { [3 x double] } + +define void @foo(double* %A, double* %C, %type* %B) #0 { +; CHECK-NOT: Vector function shape is missing from the database +entry: + br label %for.body + +for.body: + %i = phi i64 [ %inc, %for.body ], [ 0, %entry ] + %dummyload2 = load double, double* %A, align 8 + %arrayidx.i24 = getelementptr inbounds %type, %type* %B, i64 %i, i32 0, i32 0 + %_15 = load double, double* %arrayidx.i24, align 8 + %call10 = tail call fast double @atan(double %_15) #1 + %inc = add i64 %i, 1 + %cmp = icmp ugt i64 1000, %inc + br i1 %cmp, label %for.body, label %for.end + +for.end: + ret void +} + +declare double @atan(double) local_unnamed_addr +declare <2 x double> @__atand2_massv(<2 x double>) #1 +attributes #0 = { "target-cpu"="pwr9" } +attributes #1 = { nounwind readnone "vector-function-abi-variant"="_ZGV_LLVM_N2v_atan(__atand2_massv)" }