[llvm] 3fb3383 - Revert "[AA] No synchronization effects for never-escaping identified local" (#196890)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 00:36:49 PDT 2026
Author: Nikita Popov
Date: 2026-05-11T07:36:44Z
New Revision: 3fb3383f453109cab772005739f5f6ad1a0f7266
URL: https://github.com/llvm/llvm-project/commit/3fb3383f453109cab772005739f5f6ad1a0f7266
DIFF: https://github.com/llvm/llvm-project/commit/3fb3383f453109cab772005739f5f6ad1a0f7266.diff
LOG: Revert "[AA] No synchronization effects for never-escaping identified local" (#196890)
Reverts llvm/llvm-project#193939
Caused buildbot failure.
Added:
Modified:
llvm/lib/Analysis/AliasAnalysis.cpp
llvm/test/Analysis/BasicAA/atomics.ll
llvm/test/Analysis/MemorySSA/atomic-clobber.ll
llvm/test/Transforms/DeadStoreElimination/fence.ll
llvm/test/Transforms/GVN/fence.ll
llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
llvm/test/Transforms/LICM/atomics.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index ffb2dc0f4e041..1449a54d1de2b 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -458,34 +458,12 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, AliasResult AR) {
// Helper method implementation
//===----------------------------------------------------------------------===//
-/// Get ModRefInfo for a synchronizing operation, such as a fence or stronger
-/// than monotonic atomic load/store.
-static ModRefInfo getSyncEffects(AAResults *AA, const MemoryLocation &Loc,
- AAQueryInfo &AAQI) {
- if (!Loc.Ptr)
- return ModRefInfo::ModRef;
-
- // If the location is *never* captured, it cannot be affected by
- // synchronizing operations. However, we cannot ignore locations that are
- // only captured after the operation, as the synchronization may still have
- // an effect if the object is only captured *later*. As such, set I to null
- // and ReturnCaptures to true here.
- const Value *Obj = getUnderlyingObject(Loc.Ptr);
- if (capturesNothing(AAQI.CA->getCapturesBefore(
- Obj, /*I=*/nullptr, /*OrAt=*/true, /*ReturnCaptures=*/true)))
- return ModRefInfo::NoModRef;
-
- // If Loc is a constant memory location, the synchronization operation
- // definitely could not modify it.
- return AA->getModRefInfoMask(Loc);
-}
-
ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) {
// Be conservative in the face of atomic.
if (isStrongerThan(L->getOrdering(), AtomicOrdering::Unordered))
- return getSyncEffects(this, Loc, AAQI);
+ return ModRefInfo::ModRef;
// If the load address doesn't alias the given address, it doesn't read
// or write the specified memory.
@@ -503,7 +481,7 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
AAQueryInfo &AAQI) {
// Be conservative in the face of atomic.
if (isStrongerThan(S->getOrdering(), AtomicOrdering::Unordered))
- return getSyncEffects(this, Loc, AAQI);
+ return ModRefInfo::ModRef;
if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI, S);
@@ -537,9 +515,14 @@ ModRefInfo AAResults::getModRefInfo(const FenceInst *F,
return ModRefInfo::NoModRef;
}
- return Result & getSyncEffects(this, Loc, AAQI);
- }
+ // Apply the ModRef mask. This ensures that if Loc is a constant memory
+ // location, we take into account the fact that the fence definitely could
+ // not modify the memory location.
+ if (!isNoModRef(Result))
+ Result &= getModRefInfoMask(Loc);
+ return Result;
+ }
return ModRefInfo::ModRef;
}
@@ -593,7 +576,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX,
AAQueryInfo &AAQI) {
// Acquire/Release cmpxchg has properties that matter for arbitrary addresses.
if (isStrongerThanMonotonic(CX->getSuccessOrdering()))
- return getSyncEffects(this, Loc, AAQI);
+ return ModRefInfo::ModRef;
if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI, CX);
@@ -611,7 +594,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW,
AAQueryInfo &AAQI) {
// Acquire/Release atomicrmw has properties that matter for arbitrary addresses.
if (isStrongerThanMonotonic(RMW->getOrdering()))
- return getSyncEffects(this, Loc, AAQI);
+ return ModRefInfo::ModRef;
if (Loc.Ptr) {
AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI, RMW);
diff --git a/llvm/test/Analysis/BasicAA/atomics.ll b/llvm/test/Analysis/BasicAA/atomics.ll
index 1101466fe7055..db0417c758e92 100644
--- a/llvm/test/Analysis/BasicAA/atomics.ll
+++ b/llvm/test/Analysis/BasicAA/atomics.ll
@@ -8,29 +8,29 @@ declare noalias ptr @malloc(i64)
; CHECK: Both ModRef: Ptr: i32* %x <-> %1 = atomicrmw add ptr %x, i32 1 monotonic, align 4
; CHECK: NoModRef: Ptr: i32* %a <-> %2 = cmpxchg ptr %x, i32 0, i32 1 monotonic monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %2 = cmpxchg ptr %x, i32 0, i32 1 monotonic monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x monotonic, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %3 = load atomic i32, ptr %x monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x monotonic, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> store atomic i32 0, ptr %x monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> fence release
+; CHECK: Both ModRef: Ptr: i32* %a <-> fence release
; CHECK: Both ModRef: Ptr: i32* %x <-> fence release
-; CHECK: NoModRef: Ptr: i32* %a <-> %4 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %4 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %4 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %5 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %5 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %5 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %6 = load atomic i32, ptr %x acquire, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %6 = load atomic i32, ptr %x acquire, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %6 = load atomic i32, ptr %x acquire, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> store atomic i32 0, ptr %x release, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> fence seq_cst
+; CHECK: Both ModRef: Ptr: i32* %a <-> fence seq_cst
; CHECK: Both ModRef: Ptr: i32* %x <-> fence seq_cst
-; CHECK: NoModRef: Ptr: i32* %a <-> %7 = atomicrmw add ptr %x, i32 1 seq_cst, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %7 = atomicrmw add ptr %x, i32 1 seq_cst, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %7 = atomicrmw add ptr %x, i32 1 seq_cst, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %8 = cmpxchg ptr %x, i32 0, i32 1 seq_cst seq_cst, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %8 = cmpxchg ptr %x, i32 0, i32 1 seq_cst seq_cst, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %8 = cmpxchg ptr %x, i32 0, i32 1 seq_cst seq_cst, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %9 = load atomic i32, ptr %x seq_cst, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %9 = load atomic i32, ptr %x seq_cst, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %9 = load atomic i32, ptr %x seq_cst, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x seq_cst, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x seq_cst, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> store atomic i32 0, ptr %x seq_cst, align 4
define void @alloca_no_escape(ptr %x) {
%a = alloca i32
@@ -83,15 +83,15 @@ define void @alloca_escape_after(ptr %x) {
}
; CHECK-LABEL: Function: noalias_no_escape:
-; CHECK: NoModRef: Ptr: i32* %a <-> fence release
+; CHECK: Both ModRef: Ptr: i32* %a <-> fence release
; CHECK: Both ModRef: Ptr: i32* %x <-> fence release
-; CHECK: NoModRef: Ptr: i32* %a <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x acquire, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x acquire, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %3 = load atomic i32, ptr %x acquire, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> store atomic i32 0, ptr %x release, align 4
define void @noalias_no_escape(ptr noalias %a, ptr %x) {
store i32 0, ptr %a
@@ -125,23 +125,21 @@ define void @noalias_escape_after(ptr noalias %a, ptr %x) {
load atomic i32, ptr %x acquire, align 4
store atomic i32 0, ptr %x release, align 4
- call void @escape(ptr %a)
-
ret void
}
; CHECK-LABEL: Function: malloc_no_escape:
; CHECK: Both ModRef: Ptr: i32* %a <-> %a = call ptr @malloc(i64 4)
; CHECK: Both ModRef: Ptr: i32* %x <-> %a = call ptr @malloc(i64 4)
-; CHECK: NoModRef: Ptr: i32* %a <-> fence release
+; CHECK: Both ModRef: Ptr: i32* %a <-> fence release
; CHECK: Both ModRef: Ptr: i32* %x <-> fence release
-; CHECK: NoModRef: Ptr: i32* %a <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %1 = atomicrmw add ptr %x, i32 1 acq_rel, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %2 = cmpxchg ptr %x, i32 0, i32 1 acq_rel monotonic, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x acquire, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> %3 = load atomic i32, ptr %x acquire, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> %3 = load atomic i32, ptr %x acquire, align 4
-; CHECK: NoModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
+; CHECK: Both ModRef: Ptr: i32* %a <-> store atomic i32 0, ptr %x release, align 4
; CHECK: Both ModRef: Ptr: i32* %x <-> store atomic i32 0, ptr %x release, align 4
define void @malloc_no_escape(ptr %x) {
%a = call ptr @malloc(i64 4)
diff --git a/llvm/test/Analysis/MemorySSA/atomic-clobber.ll b/llvm/test/Analysis/MemorySSA/atomic-clobber.ll
index 86708ecbc58fd..326ec8b15283d 100644
--- a/llvm/test/Analysis/MemorySSA/atomic-clobber.ll
+++ b/llvm/test/Analysis/MemorySSA/atomic-clobber.ll
@@ -106,7 +106,7 @@ define void @seq_cst_clobber(ptr noalias %a, ptr noalias %b) {
; If AA gets more aggressive, we can find another way.
;
; CHECK-LABEL: define void @check_aa_is_sane
-define void @check_aa_is_sane(ptr noalias %a, ptr %b) {
+define void @check_aa_is_sane(ptr noalias %a, ptr noalias %b) {
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: cmpxchg ptr %a, i32 0, i32 1 acquire acquire
cmpxchg ptr %a, i32 0, i32 1 acquire acquire
diff --git a/llvm/test/Transforms/DeadStoreElimination/fence.ll b/llvm/test/Transforms/DeadStoreElimination/fence.ll
index 3c02d715eb94d..b619b0035ce03 100644
--- a/llvm/test/Transforms/DeadStoreElimination/fence.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/fence.ll
@@ -54,6 +54,7 @@ define void @test2(ptr %addr.i) {
ret void
}
+; TODO:
; We DSE stack alloc'ed and byval locations, in the presence of fences.
; Fence does not make an otherwise thread local store visible.
; Right now the DSE in presence of fence is only done in end blocks (with no successors),
@@ -62,6 +63,7 @@ define void @test2(ptr %addr.i) {
define void @test3(ptr byval(i32) %addr.i) {
; CHECK-LABEL: define void @test3(
; CHECK-SAME: ptr byval(i32) [[ADDR_I:%.*]]) {
+; CHECK-NEXT: store i32 5, ptr [[ADDR_I]], align 4
; CHECK-NEXT: fence release
; CHECK-NEXT: ret void
;
@@ -74,11 +76,13 @@ declare void @foo(ptr nocapture %p)
declare noalias ptr @malloc(i32)
+; TODO:
; DSE of stores in locations allocated through library calls.
define void @test_nocapture() {
; CHECK-LABEL: define void @test_nocapture() {
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i32 24)
; CHECK-NEXT: call void @foo(ptr [[M]])
+; CHECK-NEXT: store i8 4, ptr [[M]], align 1
; CHECK-NEXT: fence release
; CHECK-NEXT: ret void
;
@@ -89,10 +93,14 @@ define void @test_nocapture() {
ret void
}
+
+; TODO:
; This is a full fence, but it does not make a thread local store visible.
; We can DSE the store in presence of the fence.
define void @fence_seq_cst() {
; CHECK-LABEL: define void @fence_seq_cst() {
+; CHECK-NEXT: [[P1:%.*]] = alloca i32, align 4
+; CHECK-NEXT: store i32 0, ptr [[P1]], align 4
; CHECK-NEXT: fence seq_cst
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/GVN/fence.ll b/llvm/test/Transforms/GVN/fence.ll
index 16c6b5143703d..f2b1538843681 100644
--- a/llvm/test/Transforms/GVN/fence.ll
+++ b/llvm/test/Transforms/GVN/fence.ll
@@ -37,9 +37,9 @@ define i32 @test2(ptr %addr.i) {
; ordering property (though it is that too), but a liveness
; property. We expect to eventually see the value of store by
; another thread when spinning on that location.
-define i32 @test3(ptr %addr.i) {
+define i32 @test3(ptr noalias %addr.i, ptr noalias %otheraddr) {
; CHECK-LABEL: define i32 @test3
-; CHECK-SAME: (ptr [[ADDR_I:%.*]]) {
+; CHECK-SAME: (ptr noalias [[ADDR_I:%.*]], ptr noalias [[OTHERADDR:%.*]]) {
; CHECK-NEXT: fence acquire
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[ADDR_I]], align 4
; CHECK-NEXT: fence acquire
diff --git a/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll b/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
index fc85048ebdacf..f4a4155e94f80 100644
--- a/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
+++ b/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
@@ -28,6 +28,8 @@ define hidden void @eggs(ptr %arg, i1 %arg2, ptr %arg3, i32 %arg4, ptr %arg5) un
; CHECK-NEXT: br label %[[BB9]]
; CHECK: [[BB9]]:
; CHECK-NEXT: tail call void @quux(ptr [[ARG]], i1 [[ARG2]])
+; CHECK-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP]], align 8
+; CHECK-NEXT: [[TMP18:%.*]] = icmp eq ptr [[TMP17]], null
; CHECK-NEXT: ret void
;
bb:
diff --git a/llvm/test/Transforms/LICM/atomics.ll b/llvm/test/Transforms/LICM/atomics.ll
index 1d29b038c9a53..2b3435ba2e7ef 100644
--- a/llvm/test/Transforms/LICM/atomics.ll
+++ b/llvm/test/Transforms/LICM/atomics.ll
@@ -239,7 +239,6 @@ define i32 @test7b(ptr nocapture noalias %x, ptr nocapture %y, ptr noalias nocap
; CHECK-LABEL: define i32 @test7b(
; CHECK-SAME: ptr noalias captures(none) [[X:%.*]], ptr captures(none) [[Y:%.*]], ptr noalias captures(none) [[Z:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: store i32 5, ptr [[X]], align 4
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[VALA:%.*]] = load atomic i32, ptr [[Y]] monotonic, align 4
@@ -248,6 +247,7 @@ define i32 @test7b(ptr nocapture noalias %x, ptr nocapture %y, ptr noalias nocap
; CHECK: [[END]]:
; CHECK-NEXT: [[VALA_LCSSA1:%.*]] = phi i32 [ [[VALA]], %[[LOOP]] ]
; CHECK-NEXT: [[VALA_LCSSA:%.*]] = phi i32 [ [[VALA]], %[[LOOP]] ]
+; CHECK-NEXT: store i32 5, ptr [[X]], align 4
; CHECK-NEXT: store atomic i32 [[VALA_LCSSA1]], ptr [[Z]] unordered, align 4
; CHECK-NEXT: ret i32 [[VALA_LCSSA]]
;
@@ -266,9 +266,9 @@ end:
}
-define i32 @test8(ptr nocapture %x, ptr nocapture noalias %y) {
+define i32 @test8(ptr nocapture noalias %x, ptr nocapture %y) {
; CHECK-LABEL: define i32 @test8(
-; CHECK-SAME: ptr captures(none) [[X:%.*]], ptr noalias captures(none) [[Y:%.*]]) {
+; CHECK-SAME: ptr noalias captures(none) [[X:%.*]], ptr captures(none) [[Y:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
More information about the llvm-commits
mailing list