Author: Nikita Popov
Date: 2025-04-29T15:22:30-07:00
New Revision: 1cf8c7797d2b2447a0eadd1443498bc9be38042e

URL: 
https://github.com/llvm/llvm-project/commit/1cf8c7797d2b2447a0eadd1443498bc9be38042e
DIFF: 
https://github.com/llvm/llvm-project/commit/1cf8c7797d2b2447a0eadd1443498bc9be38042e.diff

LOG: [GlobalOpt] Do not promote malloc if there are atomic loads/stores 
(#137158)

When converting a malloc stored to a global into a global, we will
introduce an i1 flag to track whether the global has been initialized.

In case of atomic loads/stores, this will result in verifier failures,
because atomic ops on i1 are illegal. Even if we changed this to i8, I
don't think it is a good idea to change atomic types in that way.

Instead, bail out of the transform is we encounter any atomic
loads/stores of the global.

Fixes https://github.com/llvm/llvm-project/issues/137152.

(cherry picked from commit 57530c23a53b5e003d389437637f61c5b9814e22)

Added: 
    llvm/test/Transforms/GlobalOpt/malloc-promote-atomic.ll

Modified: 
    llvm/lib/Transforms/IPO/GlobalOpt.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp 
b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 9586fc97a39f7..236a531317678 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -719,10 +719,14 @@ static bool allUsesOfLoadedValueWillTrapIfNull(const 
GlobalVariable *GV) {
     const Value *P = Worklist.pop_back_val();
     for (const auto *U : P->users()) {
       if (auto *LI = dyn_cast<LoadInst>(U)) {
+        if (!LI->isSimple())
+          return false;
         SmallPtrSet<const PHINode *, 8> PHIs;
         if (!AllUsesOfValueWillTrapIfNull(LI, PHIs))
           return false;
       } else if (auto *SI = dyn_cast<StoreInst>(U)) {
+        if (!SI->isSimple())
+          return false;
         // Ignore stores to the global.
         if (SI->getPointerOperand() != P)
           return false;

diff  --git a/llvm/test/Transforms/GlobalOpt/malloc-promote-atomic.ll 
b/llvm/test/Transforms/GlobalOpt/malloc-promote-atomic.ll
new file mode 100644
index 0000000000000..0ecdf095efdd8
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/malloc-promote-atomic.ll
@@ -0,0 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 
UTC_ARGS: --version 5
+; RUN: opt -passes=globalopt -S < %s | FileCheck %s
+
+@g = internal global ptr null, align 8
+
+define void @init() {
+; CHECK-LABEL: define void @init() local_unnamed_addr {
+; CHECK-NEXT:    [[ALLOC:%.*]] = call ptr @malloc(i64 48)
+; CHECK-NEXT:    store atomic ptr [[ALLOC]], ptr @g seq_cst, align 8
+; CHECK-NEXT:    ret void
+;
+  %alloc = call ptr @malloc(i64 48)
+  store atomic ptr %alloc, ptr @g seq_cst, align 8
+  ret void
+}
+
+define i1 @check() {
+; CHECK-LABEL: define i1 @check() local_unnamed_addr {
+; CHECK-NEXT:    [[VAL:%.*]] = load atomic ptr, ptr @g seq_cst, align 8
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[VAL]], null
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %val = load atomic ptr, ptr @g seq_cst, align 8
+  %cmp = icmp eq ptr %val, null
+  ret i1 %cmp
+}
+
+declare ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0)


        
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to