aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LoopAccessAnalysis.cpp
diff options
context:
space:
mode:
authorBenjamin Maxwell <benjamin.maxwell@arm.com>2024-09-23 16:05:55 +0100
committerGitHub <noreply@github.com>2024-09-23 16:05:55 +0100
commit50a1ab12abbe948e6d3f8418f11bfa1951c8d19e (patch)
tree3984518ecb63c5c0e200cd1abc7ee68ffa246a65 /llvm/lib/Analysis/LoopAccessAnalysis.cpp
parent606557ddd68bcb082fb82fd21b0afb260222ae14 (diff)
downloadllvm-50a1ab12abbe948e6d3f8418f11bfa1951c8d19e.zip
llvm-50a1ab12abbe948e6d3f8418f11bfa1951c8d19e.tar.gz
llvm-50a1ab12abbe948e6d3f8418f11bfa1951c8d19e.tar.bz2
[LAA] Don't assume libcalls with output/input pointers can be vectorized (#108980)
LoopAccessAnalysis currently does not check/track aliasing from the output pointers, but assumes vectorizing library calls with a mapping is safe. This can result in incorrect codegen if something like the following is vectorized: ``` for(int i=0; i<N; i++) { // No aliasing between input and output pointers detected. sincos(cos_out[0], sin_out+i, cos_out+i); } ``` Where for VF >= 2 `cos_out[1]` to `cos_out[VF-1]` is the cosine of the original value of `cos_out[0]` not the updated value.
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 980f142..3f18972 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -2449,13 +2449,20 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
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.
+ // but is not a load, we only allow it if it's a call to a function with a
+ // vector mapping and no pointer arguments.
if (I.mayReadFromMemory()) {
- // If the function has an explicit vectorized counterpart, we can safely
- // assume that it can be vectorized.
+ auto hasPointerArgs = [](CallBase *CB) {
+ return any_of(CB->args(), [](Value const *Arg) {
+ return Arg->getType()->isPointerTy();
+ });
+ };
+
+ // If the function has an explicit vectorized counterpart, and does not
+ // take output/input pointers, we can safely assume that it can be
+ // vectorized.
if (Call && !Call->isNoBuiltin() && Call->getCalledFunction() &&
- !VFDatabase::getMappings(*Call).empty())
+ !hasPointerArgs(Call) && !VFDatabase::getMappings(*Call).empty())
continue;
auto *Ld = dyn_cast<LoadInst>(&I);