[PATCH] D15352: [EarlyCSE] DSE of atomic unordered stores
JF Bastien via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 9 02:47:46 PST 2015
jfb added a comment.
I'm not sure this is good to go as-is.
================
Comment at: lib/Transforms/Scalar/EarlyCSE.cpp:690
@@ +689,3 @@
+ // location with no intervening loads. Delete the earlier store.
+ // At the moment, we don't removal ordered stores, but do remove
+ // unordered atomic stores. There's no special requirement about
----------------
Typo "removal".
================
Comment at: test/Transforms/EarlyCSE/atomics.ll:131
@@ +130,3 @@
+ store atomic i32 3, i32* %P1 unordered, align 4
+ store i32 0, i32* %P1, align 4
+ ret void
----------------
I think the store you keep still needs to be atomic, i.e. you're "sinking" the atomicity to all post-dominating stores. Let's ignore that this is `unordered` (silly example) and imagine it's a `store release`: in that case the writer could have been writing a non-zero value, then racing with itself and writing another non-zero value to the same location. The reader observes the transition to non-zero (yes it's racy *which* non-zero is seen, but one is seen). If you drop `release` then the algorithm becomes incorrect.
```
void writer(Payload p, atomic<int> *flag) {
p->update();
flag->write(1, release);
// ...
*reinterpret_cast<int*>(flag) = 2; // WTF?
}
void reader(Payload p, atomic<int> *flag) {
while (!flag->load(acquire)) ;
p->process();
}
```
In the above example `p->process()` isn't guaranteed to see the latest state from `p`. Yes the code is already UB, but we don't need to be silly.
Seen another way, replace `reinterpret_cast` with a `flag->store(2, relaxed)` and then we're well-defined, you can eliminate the `store release`, but you have to "sink" the `release` to the later store.
================
Comment at: test/Transforms/EarlyCSE/atomics.ll:159
@@ +158,3 @@
+; CHECK-LABEL: @test26
+; CHECK-NEXT: store atomic
+; CHECK-NEXT: ret
----------------
Can you check that `3` is the value stored here? We should probably try to avoid unexpected things even when we're allowed to do the unexpected (and document that we're doing this).
================
Comment at: test/Transforms/EarlyCSE/atomics.ll:170
@@ +169,3 @@
+; CHECK-NEXT: store atomic
+; CHECK-DAG: release
+; CHECK-NEXT: ret
----------------
Why not just:
```
; CHECK-LABEL: @test27
; CHECK-NEXT: store atomic i32 3, i32* %p1 release
; CHECK-NEXT: ret
```
?
================
Comment at: test/Transforms/EarlyCSE/atomics.ll:177
@@ +176,3 @@
+
+; Can DSE a normal store in favor of a ordered one
+define void @test28(i1 %B, i32* %P1, i32* %P2) {
----------------
This test isn't testing what the documentation says it is.
================
Comment at: test/Transforms/EarlyCSE/atomics.ll:182
@@ +181,3 @@
+; CHECK-DAG: release
+; CHECK-NEXT: ret
+ store atomic i32 0, i32* %P1 unordered, align 4
----------------
Ditto on `CHECK`.
http://reviews.llvm.org/D15352
More information about the llvm-commits
mailing list