diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -2188,8 +2188,8 @@ // Scan the BB and collect legal loads and stores. Also detect any // convergent instructions. for (Instruction &I : *BB) { - if (auto *Call = dyn_cast(&I)) { - if (Call->isConvergent()) + if (auto *CB = dyn_cast(&I)) { + if (CB->isConvergent()) HasConvergentOp = true; } @@ -2204,14 +2204,10 @@ if (HasComplexMemInst) continue; - // If this is a load, save it. If this instruction can read from memory - // but is not a load, then we quit. Notice that we don't handle function - // calls that read or write. - if (I.mayReadFromMemory()) { + if (auto *Call = dyn_cast(&I)) { // Many math library functions read the rounding mode. We will only // vectorize a loop if it contains known function calls that don't set // the flag. Therefore, it is safe to ignore this read from memory. - auto *Call = dyn_cast(&I); if (Call && getVectorIntrinsicIDForCall(Call, TLI)) continue; @@ -2220,7 +2216,12 @@ if (Call && !Call->isNoBuiltin() && Call->getCalledFunction() && !VFDatabase::getMappings(*Call).empty()) continue; + } + // If this is a load, save it. If this instruction can read from memory + // but is not a load, then we quit. Notice that we don't handle function + // calls that read or write. + if (I.mayReadFromMemory()) { auto *Ld = dyn_cast(&I); if (!Ld) { recordAnalysis("CantVectorizeInstruction", Ld) diff --git a/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls-VF2-VF8.ll b/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls-VF2-VF8.ll --- a/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls-VF2-VF8.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls-VF2-VF8.ll @@ -356,7 +356,8 @@ !132 = !{!"llvm.loop.vectorize.width", i32 8} !133 = !{!"llvm.loop.vectorize.enable", i1 true} -attributes #0 = { nounwind readnone } +; functions are in fact "readnone" but clang only emits the weaker "writeonly" as other math functions may write errno. +attributes #0 = { nounwind writeonly } declare double @sin(double) #0 declare float @sinf(float) #0 diff --git a/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls.ll b/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls.ll --- a/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls.ll +++ b/llvm/test/Transforms/LoopVectorize/X86/libm-vector-calls.ll @@ -356,7 +356,8 @@ !132 = !{!"llvm.loop.vectorize.width", i32 4} !133 = !{!"llvm.loop.vectorize.enable", i1 true} -attributes #0 = { nounwind readnone } +; functions are in fact "readnone" but clang only emits the weaker "writeonly" as other math functions may write errno. +attributes #0 = { nounwind writeonly } declare double @sin(double) #0 declare float @sinf(float) #0