Skip to content

Commit 4b63c54

Browse files
author
Jin Huang
committed
[AA] Improve precision for monotonic atomic load/store operations
1 parent 05c40eb commit 4b63c54

File tree

3 files changed

+67
-56
lines changed

3 files changed

+67
-56
lines changed

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -421,25 +421,23 @@ ModRefInfo AAResults::getModRefInfo(const LoadInst *L,
421421
const MemoryLocation &Loc,
422422
AAQueryInfo &AAQI) {
423423
// Be conservative in the face of atomic.
424-
if (isStrongerThan(L->getOrdering(), AtomicOrdering::Monotonic))
424+
if (isStrongerThanMonotonic(L->getOrdering()))
425425
return ModRefInfo::ModRef;
426426

427-
// For Monotonic and unordered atomic loads, if the locations are not NoAlias,
428-
// we must be conservative and return ModRef to prevent unsafe reordering of
429-
// accesses to the same memory.
430-
if (L->isAtomic()){
431-
if (Loc.Ptr &&
432-
alias(MemoryLocation::get(L), Loc, AAQI, L) != AliasResult::NoAlias)
433-
return ModRefInfo::ModRef;
434-
}
435-
436427
// If the load address doesn't alias the given address, it doesn't read
437428
// or write the specified memory.
438429
if (Loc.Ptr) {
439430
AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI, L);
440431
if (AR == AliasResult::NoAlias)
441432
return ModRefInfo::NoModRef;
442433
}
434+
435+
assert(!isStrongerThanMonotonic(L->getOrdering()) &&
436+
"Stronger atomic orderings should have been handled above!");
437+
438+
if (isStrongerThanUnordered(L->getOrdering()))
439+
return ModRefInfo::ModRef;
440+
443441
// Otherwise, a load just reads.
444442
return ModRefInfo::Ref;
445443
}
@@ -448,7 +446,7 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
448446
const MemoryLocation &Loc,
449447
AAQueryInfo &AAQI) {
450448
// Be conservative in the face of atomic.
451-
if (isStrongerThan(S->getOrdering(), AtomicOrdering::Monotonic))
449+
if (isStrongerThanMonotonic(S->getOrdering()))
452450
return ModRefInfo::ModRef;
453451

454452
if (Loc.Ptr) {
@@ -466,8 +464,14 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
466464
return ModRefInfo::NoModRef;
467465
}
468466

469-
// Otherwise, a store just writes.
470-
return ModRefInfo::ModRef;
467+
assert(!isStrongerThanMonotonic(S->getOrdering()) &&
468+
"Stronger atomic orderings should have been handled above!");
469+
470+
if (isStrongerThanUnordered(S->getOrdering()))
471+
return ModRefInfo::ModRef;
472+
473+
// A store just writes.
474+
return ModRefInfo::Mod;
471475
}
472476

473477
ModRefInfo AAResults::getModRefInfo(const FenceInst *S,

llvm/test/Transforms/DeadStoreElimination/atomic-todo.ll

Lines changed: 0 additions & 30 deletions
This file was deleted.

llvm/test/Transforms/DeadStoreElimination/atomic.ll

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,21 @@ define void @test4() {
3737
ret void
3838
}
3939

40-
; DSE unordered store overwriting non-atomic store (allowed)
40+
; DSE doesn't remove monotonic store.
4141
define void @test5() {
4242
; CHECK-LABEL: @test5(
43+
; CHECK-NEXT: store atomic i32 2, ptr @x monotonic, align 4
44+
; CHECK-NEXT: store i32 1, ptr @x, align 4
45+
; CHECK-NEXT: ret void
46+
;
47+
store atomic i32 2, ptr @x monotonic, align 4
48+
store i32 1, ptr @x
49+
ret void
50+
}
51+
52+
; DSE unordered store overwriting non-atomic store (allowed)
53+
define void @test6() {
54+
; CHECK-LABEL: @test6(
4355
; CHECK-NEXT: store atomic i32 1, ptr @x unordered, align 4
4456
; CHECK-NEXT: ret void
4557
;
@@ -49,8 +61,8 @@ define void @test5() {
4961
}
5062

5163
; DSE no-op unordered atomic store (allowed)
52-
define void @test6() {
53-
; CHECK-LABEL: @test6(
64+
define void @test7() {
65+
; CHECK-LABEL: @test7(
5466
; CHECK-NEXT: ret void
5567
;
5668
%x = load atomic i32, ptr @x unordered, align 4
@@ -60,8 +72,8 @@ define void @test6() {
6072

6173
; DSE seq_cst store (be conservative; DSE doesn't have infrastructure
6274
; to reason about atomic operations).
63-
define void @test7() {
64-
; CHECK-LABEL: @test7(
75+
define void @test8() {
76+
; CHECK-LABEL: @test8(
6577
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
6678
; CHECK-NEXT: store atomic i32 0, ptr [[A]] seq_cst, align 4
6779
; CHECK-NEXT: ret void
@@ -73,8 +85,8 @@ define void @test7() {
7385

7486
; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure
7587
; to reason about atomic operations).
76-
define i32 @test8() {
77-
; CHECK-LABEL: @test8(
88+
define i32 @test9() {
89+
; CHECK-LABEL: @test9(
7890
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
7991
; CHECK-NEXT: call void @randomop(ptr [[A]])
8092
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
@@ -88,10 +100,35 @@ define i32 @test8() {
88100
ret i32 %x
89101
}
90102

91-
; DSE across monotonic store (allowed as long as the eliminated store isUnordered)
92-
define void @test10() {
103+
; DSE across monotonic load (allowed if the monotonic load's address is NoAlias)
104+
define i32 @test10() {
93105
; CHECK-LABEL: test10
94106
; CHECK-NOT: store i32 0
107+
; CHECK: store i32 1
108+
store i32 0, ptr @x
109+
%x = load atomic i32, ptr @y monotonic, align 4
110+
store i32 1, ptr @x
111+
ret i32 %x
112+
}
113+
114+
; DSE across monotonic load (blocked if the atomic load's address isn't NoAlias)
115+
define i32 @test11(ptr %ptr) {
116+
; CHECK-LABEL: @test11(
117+
; CHECK-NEXT: store i32 0, ptr @x, align 4
118+
; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4
119+
; CHECK-NEXT: store i32 1, ptr @x, align 4
120+
; CHECK-NEXT: ret i32 [[X]]
121+
;
122+
store i32 0, ptr @x
123+
%x = load atomic i32, ptr %ptr monotonic, align 4
124+
store i32 1, ptr @x
125+
ret i32 %x
126+
}
127+
128+
; DSE across monotonic store (allowed as long as the eliminated store isUnordered)
129+
define void @test12() {
130+
; CHECK-LABEL: test12
131+
; CHECK-NOT: store i32 0
95132
; CHECK: store i32 1
96133
store i32 0, ptr @x
97134
store atomic i32 42, ptr @y monotonic, align 4
@@ -100,8 +137,8 @@ define void @test10() {
100137
}
101138

102139
; DSE across monotonic load (forbidden since the eliminated store is atomic)
103-
define i32 @test11() {
104-
; CHECK-LABEL: @test11(
140+
define i32 @test13() {
141+
; CHECK-LABEL: @test13(
105142
; CHECK-NEXT: store atomic i32 0, ptr @x monotonic, align 4
106143
; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr @y monotonic, align 4
107144
; CHECK-NEXT: store atomic i32 1, ptr @x monotonic, align 4
@@ -114,8 +151,8 @@ define i32 @test11() {
114151
}
115152

116153
; DSE across monotonic store (forbidden since the eliminated store is atomic)
117-
define void @test12() {
118-
; CHECK-LABEL: @test12(
154+
define void @test14() {
155+
; CHECK-LABEL: @test14(
119156
; CHECK-NEXT: store atomic i32 0, ptr @x monotonic, align 4
120157
; CHECK-NEXT: store atomic i32 42, ptr @y monotonic, align 4
121158
; CHECK-NEXT: store atomic i32 1, ptr @x monotonic, align 4

0 commit comments

Comments
 (0)