[llvm] 69e4514 - [GlobalOpt] Do not fold away addrspacecasts which may be runtime operations (#153753)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 17 19:11:55 PDT 2025


Author: Owen Anderson
Date: 2025-08-18T02:11:51Z
New Revision: 69e4514978cf77e2a13b3feb868053e4ad65a7cd

URL: https://github.com/llvm/llvm-project/commit/69e4514978cf77e2a13b3feb868053e4ad65a7cd
DIFF: https://github.com/llvm/llvm-project/commit/69e4514978cf77e2a13b3feb868053e4ad65a7cd.diff

LOG: [GlobalOpt] Do not fold away addrspacecasts which may be runtime operations (#153753)

Specifically in the context of the once-stored transformation, GlobalOpt
would strip
all pointer casts unconditionally, even though addrspacecasts might be
runtime operations.
This manifested particularly on CHERI targets.

This patch was inspired by an existing change in CHERI LLVM
(https://github.com/CHERIoT-Platform/llvm-project/commit/91afa60f17ea1b91e5cdba21a5c90400024b2b6a),
but has been reimplemented with updated conventions, and a testcase
constructed from scratch.

Added: 
    llvm/test/Transforms/GlobalOpt/stored-once-addrspacecast.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 bdda4980c1005..d7edd1288309b 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1133,9 +1133,6 @@ static bool
 optimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
                          const DataLayout &DL,
                          function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
-  // Ignore no-op GEPs and bitcasts.
-  StoredOnceVal = StoredOnceVal->stripPointerCasts();
-
   // If we are dealing with a pointer global that is initialized to null and
   // only has one (non-null) value stored into it, then we can optimize any
   // users of the loaded value (often calls and loads) that would trap if the

diff  --git a/llvm/test/Transforms/GlobalOpt/stored-once-addrspacecast.ll b/llvm/test/Transforms/GlobalOpt/stored-once-addrspacecast.ll
new file mode 100644
index 0000000000000..35678598032dc
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/stored-once-addrspacecast.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
+; RUN: opt -passes=globalopt < %s -S | FileCheck %s
+
+; Test that we do not fold away addresscasts when optimizing once-stored
+; globals, as these may be runtime operations.
+
+ at g1 = internal global ptr null
+ at g2 = addrspace(1) global i32 0
+
+;.
+; CHECK: @g1 = internal unnamed_addr global ptr null
+; CHECK: @g2 = addrspace(1) global i32 0
+; CHECK: @g4 = local_unnamed_addr addrspace(1) global i32 0
+;.
+define i64 @test1() {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:    [[TMP1:%.*]] = addrspacecast ptr addrspace(1) @g2 to ptr
+; CHECK-NEXT:    store ptr [[TMP1]], ptr @g1, align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr @g1, align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
+; CHECK-NEXT:    ret i64 [[TMP3]]
+;
+  %l1 = addrspacecast ptr addrspace(1) @g2 to ptr
+  store ptr %l1, ptr @g1, align 8
+  %l2 = load ptr, ptr @g1, align 8
+  %l3 = load i64, ptr %l2, align 8
+  ret i64 %l3
+}
+
+ at g3 = internal global ptr null
+ at g4 = addrspace(1) global i32 0
+
+define i64 @test2() {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr addrspacecast (ptr addrspace(1) @g4 to ptr), align 8
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  store ptr addrspacecast (ptr addrspace(1) @g4 to ptr), ptr @g3, align 8
+  %l1 = load ptr, ptr @g3, align 8
+  %l2 = load i64, ptr %l1, align 8
+  ret i64 %l2
+}


        


More information about the llvm-commits mailing list