diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index 697b40403902c..dcd8a910d0f49 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1283,8 +1283,10 @@ void AccessAnalysis::processMemAccesses() { bool SetHasWrite = false; - // Map of pointers to last access encountered. - typedef DenseMap UnderlyingObjToAccessMap; + // Map of (pointer to underlying objects, accessed address space) to last + // access encountered. + typedef DenseMap, MemAccessInfo> + UnderlyingObjToAccessMap; UnderlyingObjToAccessMap ObjToLastAccess; // Set of access to check after all writes have been processed. @@ -1364,12 +1366,14 @@ void AccessAnalysis::processMemAccesses() { UnderlyingObj->getType()->getPointerAddressSpace())) continue; + unsigned AccessAS = cast(Ptr->getType())->getAddressSpace(); UnderlyingObjToAccessMap::iterator Prev = - ObjToLastAccess.find(UnderlyingObj); + ObjToLastAccess.find({UnderlyingObj,AccessAS + }); if (Prev != ObjToLastAccess.end()) DepCands.unionSets(Access, Prev->second); - ObjToLastAccess[UnderlyingObj] = Access; + ObjToLastAccess[{UnderlyingObj, AccessAS}] = Access; LLVM_DEBUG(dbgs() << " " << *UnderlyingObj << "\n"); } } diff --git a/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-different-address-spaces.ll b/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-different-address-spaces.ll new file mode 100644 index 0000000000000..adf73c091be00 --- /dev/null +++ b/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-different-address-spaces.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes='print' -disable-output %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + +; Test case for https://github.com/llvm/llvm-project/issues/124759. The same +; underlying object is access through pointers with different address spaces. +define void @same_underlying_object_different_address_spaces(ptr %dst1.as1, ptr %dst2.as1) { +; CHECK-LABEL: 'same_underlying_object_different_address_spaces' +; CHECK-NEXT: loop: +; CHECK-NEXT: Report: cannot identify array bounds +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %alloc = alloca i8, i64 0, align 128 + %as3 = addrspacecast ptr %alloc to ptr addrspace(3) + %as4 = addrspacecast ptr %alloc to ptr addrspace(4) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + store i32 0, ptr addrspace(4) %as4, align 4 + store i32 0, ptr %dst1.as1, align 4 + %l = load i64, ptr addrspace(3) %as3, align 4 + store i64 %l, ptr %dst2.as1, align 4 + %iv.next = add i64 %iv, 1 + %c = icmp eq i64 %iv.next, 100 + br i1 %c, label %loop, label %exit + +exit: + ret void +}