[PATCH] Further relax the constraint on atomics in MemoryDependencyAnalysis.cpp

Philip Reames listmail at philipreames.com
Thu Aug 21 12:06:07 PDT 2014


Comments inline.  I am not yet convinced of the correctness.

================
Comment at: lib/Analysis/MemoryDependenceAnalysis.cpp:388
@@ -373,1 +387,3 @@
+  bool HasSeenAcquire = false;
+
   if (isLoad && QueryInst) {
----------------
I'm still not finding this explanation particularly clear.  I'm going to ask you not to commit this until you can justify why this approach is correct.  

A potentially more intuitive way to explain this is to why this reordering is valid:
store x = 0
acquire operator
release operation
load x < -- okay to use zero

This is valid because the first pair of operations and the second pair can both be reordered.  i.e. the intermediate state is:
acquire operation
store x = 0
load x < -- now obviously zero
release operation

What is "discriminating context"?  What does it mean to "clobber"?


================
Comment at: lib/Analysis/MemoryDependenceAnalysis.cpp:440
@@ -423,3 +439,3 @@
             return MemDepResult::getClobber(LI);
         if (auto *QuerySI = dyn_cast<StoreInst>(QueryInst))
           if (!QuerySI->isSimple())
----------------
This is a bit off topic for this review, but I may have spotted a bug here.  What if the query instruction is a RMW operation?  These can have ordering semantics, but the existing code (from your previous change) would say there's no dependence.  

================
Comment at: lib/Analysis/MemoryDependenceAnalysis.cpp:443
@@ -426,1 +442,3 @@
             return MemDepResult::getClobber(LI);
+        if (isAtLeastAcquire(LI->getOrdering()))
+          HasSeenAcquire = true;
----------------
I think this check is wrong.  (Independent of whether the approach is valid or not.)

My reasoning is that, a cst operation is "at least" an acquire.  However, it's _also_ a release and reordering these two is not legal:
load cst y
store x = 0

This would be a violation of a "release operation" ordering as used by C++11.  It's unclear whether that would violate the LLVM spec as written, but I think it probably should.  

Note that if my reasoning is sound, this is actually a problem with the previous patch as well, not just this one.  


================
Comment at: test/Transforms/DeadStoreElimination/atomic.ll:149
@@ +148,3 @@
+; CHECK: store i32 1
+  store i32 0, i32* @x
+  %x = load atomic i32* @y seq_cst, align 4
----------------
As currently specified in the LangRef, I don't think this is legal.  If I'm reading the spec right, the load must be considered both an Acquire and a Release.  (This is possibly not intended, but seems to follow from the wording.)  As a result, this is not a acquire/release pair, but both a acquire/release and release/acquire pair.  

Finding a case where this is observable would be hard, but it seems possible.  If need be, I'll spend some time thinking about it.  

================
Comment at: test/Transforms/GVN/atomic.ll:46
@@ -45,3 +45,3 @@
 
-; GVN across acquire load (load after atomic load must not be removed)
+; GVN across acquire load (allowed as the original load was not atomic)
 define i32 @test4() nounwind uwtable ssp {
----------------
I don't believe this is valid.

================
Comment at: test/Transforms/GVN/atomic.ll:98
@@ +97,3 @@
+; CHECK: test8
+; CHECK: add i32 %x, %x
+entry:
----------------
This is valid, but not necessarily for the reason you gave.  %y can move above the release.  %x can move below the acquire.  Once this happens, %x & %y can be commoned. 

================
Comment at: test/Transforms/GVN/atomic.ll:110
@@ -85,1 +109,3 @@
+define i32 @test9() nounwind uwtable ssp {
+; CHECK: test9
 ; CHECK: add i32 %x, %x
----------------
CHECK-LABEL please

http://reviews.llvm.org/D4845






More information about the llvm-commits mailing list