[llvm] r360662 - GlobalOpt: do not promote globals used atomically to constants.

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Tue May 14 04:03:13 PDT 2019


Author: tnorthover
Date: Tue May 14 04:03:13 2019
New Revision: 360662

URL: http://llvm.org/viewvc/llvm-project?rev=360662&view=rev
Log:
GlobalOpt: do not promote globals used atomically to constants.

Some atomic loads are implemented as cmpxchg (particularly if large or
floating), and that usually requires write access to the memory involved
or it will segfault.

We can still propagate the constant value to users we understand though.

Modified:
    llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
    llvm/trunk/test/Transforms/GlobalOpt/atomic.ll

Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=360662&r1=360661&r2=360662&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Tue May 14 04:03:13 2019
@@ -1980,7 +1980,12 @@ static bool processInternalGlobal(
   }
   if (GS.StoredType <= GlobalStatus::InitializerStored) {
     LLVM_DEBUG(dbgs() << "MARKING CONSTANT: " << *GV << "\n");
-    GV->setConstant(true);
+
+    // Don't actually mark a global constant if it's atomic because atomic loads
+    // are implemented by a trivial cmpxchg in some edge-cases and that usually
+    // requires write access to the variable even if it's not actually changed.
+    if (GS.Ordering == AtomicOrdering::NotAtomic)
+      GV->setConstant(true);
 
     // Clean up any obviously simplifiable users now.
     CleanupConstantGlobalUsers(GV, GV->getInitializer(), DL, TLI);

Modified: llvm/trunk/test/Transforms/GlobalOpt/atomic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/atomic.ll?rev=360662&r1=360661&r2=360662&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/atomic.ll (original)
+++ llvm/trunk/test/Transforms/GlobalOpt/atomic.ll Tue May 14 04:03:13 2019
@@ -3,7 +3,7 @@
 @GV1 = internal global i64 1
 @GV2 = internal global i32 0
 
-; CHECK: @GV1 = internal unnamed_addr constant i64 1
+; CHECK: @GV1 = internal unnamed_addr global i64 1
 ; CHECK: @GV2 = internal unnamed_addr global i32 0
 
 define void @test1() {
@@ -23,3 +23,12 @@ entry:
   %atomic-load = load atomic i32, i32* @GV2 seq_cst, align 4
   ret i32 %atomic-load
 }
+
+
+define i64 @test3() {
+; CHECK-LABEL: @test3
+; CHECK: ret i64 1
+
+  %val = load atomic i64, i64* @GV1 acquire, align 8
+  ret i64 %val
+}




More information about the llvm-commits mailing list