EarlyCSE: It isn't safe to CSE across synchronization boundaries
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 10 Feb 2015 23:09:43 +0000 (23:09 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 10 Feb 2015 23:09:43 +0000 (23:09 +0000)
This fixes PR22514.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228760 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/EarlyCSE.cpp
test/Transforms/EarlyCSE/basic.ll

index 9a9f9651f3f316149468b3cdf8486efd82c576b7..862622f5932f05bffa8b56e86bcd2f38c1f74564 100644 (file)
@@ -527,6 +527,9 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
       // Ignore volatile loads.
       if (MemInst.isVolatile()) {
         LastStore = nullptr;
+        // Don't CSE across synchronization boundaries.
+        if (Inst->mayWriteToMemory())
+          ++CurrentGeneration;
         continue;
       }
 
index dee428cc28f0f1690fb89e4ba445e07a3071afd7..5b785318a3dc9f4d5ff7495ef99a303fd6ab9747 100644 (file)
@@ -193,4 +193,10 @@ define void @test11(i32 *%P) {
   ; CHECK-NEXT: ret void
 }
 
-
+define i32 @test12(i1 %B, i32* %P1, i32* %P2) {
+  %load0 = load i32* %P1
+  %1 = load atomic i32* %P2 seq_cst, align 4
+  %load1 = load i32* %P1
+  %sel = select i1 %B, i32 %load0, i32 %load1
+  ret i32 %sel
+}