[llvm] 07bc54b - [DWARFLinkerParallel] Fix incorrect uses of compare_exchange_weak (#138129)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 5 05:06:30 PDT 2025


Author: Martin Storsjö
Date: 2025-05-05T15:06:27+03:00
New Revision: 07bc54bf4554398b199f4dc849e5193b98422f23

URL: https://github.com/llvm/llvm-project/commit/07bc54bf4554398b199f4dc849e5193b98422f23
DIFF: https://github.com/llvm/llvm-project/commit/07bc54bf4554398b199f4dc849e5193b98422f23.diff

LOG: [DWARFLinkerParallel] Fix incorrect uses of compare_exchange_weak (#138129)

The documentation for compare_exchange_weak says that it is allowed to
spuriously fail. If compare_exchange_weak is called in a loop, spurious
failures usually are benign - but in these cases, a spurious failure
would give incorrect behaviour.

E.g. in TypePool::getOrCreateTypeEntryBody, we assume that if the
compare_exchange call returned false, we had been preempted by another
thread and that DIE is non-null.

This fixes running the dsymutil tests on Windows on aarch64 (built with
a mingw toolchain with libc++).

Added: 
    

Modified: 
    llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
    llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
    llvm/lib/DWARFLinker/Parallel/TypePool.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
index fa426d41854bb..38373b2c54919 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
@@ -1433,13 +1433,13 @@ DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
   if (IsDeclaration && !DeclarationDie) {
     // Alocate declaration DIE.
     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
-    if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
-                                                             NewDie))
+    if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
+                                                               NewDie))
       return NewDie;
   } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
     // Overwrite existing declaration DIE if it's parent is also an declaration
     // while parent of current declaration DIE is a definition.
-    if (TypeDescriptor->ParentIsDeclaration.compare_exchange_weak(
+    if (TypeDescriptor->ParentIsDeclaration.compare_exchange_strong(
             OldParentIsDeclaration, false)) {
       DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
       TypeDescriptor->DeclarationDie = NewDie;
@@ -1449,13 +1449,13 @@ DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
     // Alocate declaration DIE since parent of current DIE is marked as
     // declaration.
     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
-    if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
-                                                             NewDie))
+    if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
+                                                               NewDie))
       return NewDie;
   } else if (!IsDeclaration && !IsParentDeclaration) {
     // Allocate definition DIE.
     DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
-    if (TypeDescriptor->Die.compare_exchange_weak(DefinitionDie, NewDie)) {
+    if (TypeDescriptor->Die.compare_exchange_strong(DefinitionDie, NewDie)) {
       TypeDescriptor->ParentIsDeclaration = false;
       return NewDie;
     }

diff  --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
index 20e20222a4ac0..90c007ebe5f6c 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
@@ -201,7 +201,7 @@ class alignas(8) CompileUnit : public DwarfUnit {
     bool setPlacementIfUnset(DieOutputPlacement Placement) {
       auto InputData = Flags.load();
       if ((InputData & 0x7) == NotSet)
-        if (Flags.compare_exchange_weak(InputData, (InputData | Placement)))
+        if (Flags.compare_exchange_strong(InputData, (InputData | Placement)))
           return true;
 
       return false;

diff  --git a/llvm/lib/DWARFLinker/Parallel/TypePool.h b/llvm/lib/DWARFLinker/Parallel/TypePool.h
index 547532977262b..15a6428e1b8d6 100644
--- a/llvm/lib/DWARFLinker/Parallel/TypePool.h
+++ b/llvm/lib/DWARFLinker/Parallel/TypePool.h
@@ -135,7 +135,7 @@ class TypePool
       return DIE;
 
     TypeEntryBody *NewDIE = TypeEntryBody::create(Allocator);
-    if (Entry->getValue().compare_exchange_weak(DIE, NewDIE)) {
+    if (Entry->getValue().compare_exchange_strong(DIE, NewDIE)) {
       ParentEntry->getValue().load()->Children.add(Entry);
       return NewDIE;
     }


        


More information about the llvm-commits mailing list