[llvm] [StackSafety] Skip a caller's callee operand typed GlobalVariable (PR #216565)

Tomer Shafir via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 08:11:37 PDT 2026


https://github.com/tomershafir updated https://github.com/llvm/llvm-project/pull/216565

>From 399aa19b65030aafcd04d43686b789b7d0cd4b79 Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Sun, 16 Aug 2026 15:27:34 +0300
Subject: [PATCH 1/2] [StackSafety] Skip a caller's callee operand typed
 GlobalVariable

The callee operand of a call is not required to point to a function, it can be a function pointer global. A GlobalVariable is not analyzable locally.
---
 llvm/lib/Analysis/StackSafetyAnalysis.cpp     |  3 +-
 .../call-global-variable.ll                   | 31 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll

diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
index 9c20019677895..e6f17ff268155 100644
--- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp
+++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
@@ -527,7 +527,8 @@ void StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
         // dso_preemptable aliases or aliases with interposable linkage.
         const GlobalValue *Callee =
             dyn_cast<GlobalValue>(CB.getCalledOperand()->stripPointerCasts());
-        if (!Callee || isa<GlobalIFunc>(Callee)) {
+        if (!Callee || isa<GlobalIFunc>(Callee) ||
+            isa<GlobalVariable>(Callee)) {
           US.addRange(I, UnknownRange, /*IsSafe=*/false);
           break;
         }
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll b/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll
new file mode 100644
index 0000000000000..a8416367cd762
--- /dev/null
+++ b/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK
+; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL
+
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
+
+ at blob = external global [16 x i8]
+
+define dso_local void @CallGlobalVariable(ptr noundef %uaddr) local_unnamed_addr {
+; CHECK-LABEL: @CallGlobalVariable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: uaddr[]: full-set{{$}}
+; CHECK-NEXT: allocas uses:
+; GLOBAL-NEXT: safe accesses:
+; CHECK-EMPTY:
+entry:
+  tail call i64 @blob(ptr noundef %uaddr)
+  ret void
+}
+
+define dso_local void @CallGlobalVariableAlloca() local_unnamed_addr {
+; CHECK-LABEL: @CallGlobalVariableAlloca{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; CHECK-NEXT: x[4]: full-set{{$}}
+; GLOBAL-NEXT: safe accesses:
+; CHECK-EMPTY:
+entry:
+  %x = alloca i32, align 4
+  call i64 @blob(ptr noundef %x)
+  ret void
+}

>From d264eacb5935f4c3b0a275d8af4ccb3900ef2a0a Mon Sep 17 00:00:00 2001
From: tomershafir <tomer.shafir8 at gmail.com>
Date: Wed, 26 Aug 2026 18:11:18 +0300
Subject: [PATCH 2/2] fold new test into local.ll

---
 .../call-global-variable.ll                   | 31 -------------------
 .../Analysis/StackSafetyAnalysis/local.ll     | 25 +++++++++++++++
 2 files changed, 25 insertions(+), 31 deletions(-)
 delete mode 100644 llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll

diff --git a/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll b/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll
deleted file mode 100644
index a8416367cd762..0000000000000
--- a/llvm/test/Analysis/StackSafetyAnalysis/call-global-variable.ll
+++ /dev/null
@@ -1,31 +0,0 @@
-; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK
-; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL
-
-target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
-
- at blob = external global [16 x i8]
-
-define dso_local void @CallGlobalVariable(ptr noundef %uaddr) local_unnamed_addr {
-; CHECK-LABEL: @CallGlobalVariable{{$}}
-; CHECK-NEXT: args uses:
-; CHECK-NEXT: uaddr[]: full-set{{$}}
-; CHECK-NEXT: allocas uses:
-; GLOBAL-NEXT: safe accesses:
-; CHECK-EMPTY:
-entry:
-  tail call i64 @blob(ptr noundef %uaddr)
-  ret void
-}
-
-define dso_local void @CallGlobalVariableAlloca() local_unnamed_addr {
-; CHECK-LABEL: @CallGlobalVariableAlloca{{$}}
-; CHECK-NEXT: args uses:
-; CHECK-NEXT: allocas uses:
-; CHECK-NEXT: x[4]: full-set{{$}}
-; GLOBAL-NEXT: safe accesses:
-; CHECK-EMPTY:
-entry:
-  %x = alloca i32, align 4
-  call i64 @blob(ptr noundef %x)
-  ret void
-}
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
index 6944f38411003..fcb0eb00305cb 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
@@ -1131,6 +1131,31 @@ entry:
   ret void
 }
 
+define dso_local void @CallGlobalVariable(ptr noundef %uaddr) local_unnamed_addr {
+; CHECK-LABEL: @CallGlobalVariable{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: uaddr[]: full-set{{$}}
+; CHECK-NEXT: allocas uses:
+; GLOBAL-NEXT: safe accesses:
+; CHECK-EMPTY:
+entry:
+  tail call i64 @blob(ptr noundef %uaddr)
+  ret void
+}
+
+define dso_local void @CallGlobalVariableAlloca() local_unnamed_addr {
+; CHECK-LABEL: @CallGlobalVariableAlloca{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: allocas uses:
+; CHECK-NEXT: x[4]: full-set{{$}}
+; GLOBAL-NEXT: safe accesses:
+; CHECK-EMPTY:
+entry:
+  %x = alloca i32, align 4
+  call i64 @blob(ptr noundef %x)
+  ret void
+}
+
 define dso_local ptr @ifunc_resolver() {
 entry:
   ret ptr null



More information about the llvm-commits mailing list