[llvm] [llvm][clang] Revert split stacks implementation from runOnNewStack (PR #181743)

Michael Spencer via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 16 12:49:35 PST 2026


https://github.com/Bigcheese created https://github.com/llvm/llvm-project/pull/181743

This was potentially causing Clang to emit out of stack space warnings in rare cases, so I'm reverting it until I can verify the issue. This keeps the API change as that's known not to be the issue.

>From ccf5e71f05917aef0334100e0764250855efdd69 Mon Sep 17 00:00:00 2001
From: Michael Spencer <bigcheesegs at gmail.com>
Date: Mon, 16 Feb 2026 11:35:08 -0800
Subject: [PATCH] [llvm][clang] Revert split stacks implementation from
 runOnNewStack

This was potentially causing Clang to emit out of stack space
warnings in rare cases, so I'm reverting it until I can verify the
issue. This keeps the API change as that's known not to be the issue.
---
 llvm/include/llvm/Support/ProgramStack.h  | 11 ----
 llvm/lib/Support/CrashRecoveryContext.cpp |  5 --
 llvm/lib/Support/ProgramStack.cpp         | 70 +----------------------
 3 files changed, 1 insertion(+), 85 deletions(-)

diff --git a/llvm/include/llvm/Support/ProgramStack.h b/llvm/include/llvm/Support/ProgramStack.h
index 13729a2990588..8be0f2ae170be 100644
--- a/llvm/include/llvm/Support/ProgramStack.h
+++ b/llvm/include/llvm/Support/ProgramStack.h
@@ -12,17 +12,6 @@
 #include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/Support/Compiler.h"
 
-// LLVM_HAS_SPLIT_STACKS is exposed in the header because CrashRecoveryContext
-// needs to know if it's running on another thread or not.
-//
-// Currently only Apple AArch64 is known to support split stacks in the debugger
-// and other tooling.
-#if defined(__APPLE__) && defined(__MACH__) && defined(__aarch64__) &&         \
-    __has_extension(gnu_asm)
-# define LLVM_HAS_SPLIT_STACKS
-# define LLVM_HAS_SPLIT_STACKS_AARCH64
-#endif
-
 namespace llvm {
 
 /// \returns an address close to the current value of the stack pointer.
diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp
index 1ba0c2383daec..fc30d421506a6 100644
--- a/llvm/lib/Support/CrashRecoveryContext.cpp
+++ b/llvm/lib/Support/CrashRecoveryContext.cpp
@@ -526,10 +526,5 @@ bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn,
 
 bool CrashRecoveryContext::RunSafelyOnNewStack(function_ref<void()> Fn,
                                                unsigned RequestedStackSize) {
-#ifdef LLVM_HAS_SPLIT_STACKS
-  return runOnNewStack(RequestedStackSize,
-                       function_ref<bool()>([&]() { return RunSafely(Fn); }));
-#else
   return RunSafelyOnThread(Fn, RequestedStackSize);
-#endif
 }
diff --git a/llvm/lib/Support/ProgramStack.cpp b/llvm/lib/Support/ProgramStack.cpp
index 66f74ff660b20..e48265afb93fd 100644
--- a/llvm/lib/Support/ProgramStack.cpp
+++ b/llvm/lib/Support/ProgramStack.cpp
@@ -18,9 +18,7 @@
 # include <intrin.h>  // for _AddressOfReturnAddress
 #endif
 
-#ifndef LLVM_HAS_SPLIT_STACKS
-# include "llvm/Support/thread.h"
-#endif
+#include "llvm/Support/thread.h"
 
 using namespace llvm;
 
@@ -54,74 +52,8 @@ unsigned llvm::getDefaultStackSize() {
 #endif
 }
 
-// Not an anonymous namespace to avoid warning about undefined local function.
-namespace llvm {
-#ifdef LLVM_HAS_SPLIT_STACKS_AARCH64
-void runOnNewStackImpl(void *Stack, void (*Fn)(void *), void *Ctx) __asm__(
-    "_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_");
-
-// This can't use naked functions because there is no way to know if cfi
-// directives are being emitted or not.
-//
-// When adding new platforms it may be better to move to a .S file with macros
-// for dealing with platform differences.
-__asm__ (
-    ".globl  _ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_\n\t"
-    ".p2align  2\n\t"
-    "_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_:\n\t"
-    ".cfi_startproc\n\t"
-    "mov       x16, sp\n\t"
-    "sub       x0, x0, #0x20\n\t"            // subtract space from stack
-    "stp       xzr, x16, [x0, #0x00]\n\t"    // save old sp
-    "stp       x29, x30, [x0, #0x10]\n\t"    // save fp, lr
-    "mov       sp, x0\n\t"                   // switch to new stack
-    "add       x29, x0, #0x10\n\t"           // switch to new frame
-    ".cfi_def_cfa w29, 16\n\t"
-    ".cfi_offset w30, -8\n\t"                // lr
-    ".cfi_offset w29, -16\n\t"               // fp
-
-    "mov       x0, x2\n\t"                   // Ctx is the only argument
-    "blr       x1\n\t"                       // call Fn
-
-    "ldp       x29, x30, [sp, #0x10]\n\t"    // restore fp, lr
-    "ldp       xzr, x16, [sp, #0x00]\n\t"    // load old sp
-    "mov       sp, x16\n\t"
-    "ret\n\t"
-    ".cfi_endproc"
-);
-#endif
-} // namespace llvm
-
-namespace {
-#ifdef LLVM_HAS_SPLIT_STACKS
-void callback(void *Ctx) {
-  (*reinterpret_cast<function_ref<void()> *>(Ctx))();
-}
-#endif
-} // namespace
-
-#ifdef LLVM_HAS_SPLIT_STACKS
-void llvm::runOnNewStack(unsigned StackSize, function_ref<void()> Fn) {
-  if (StackSize == 0)
-    StackSize = getDefaultStackSize();
-
-  // We use malloc here instead of mmap because:
-  //   - it's simpler,
-  //   - many malloc implementations will reuse the allocation in cases where
-  //     we're bouncing accross the edge of a stack boundry, and
-  //   - many malloc implemenations will already provide guard pages for
-  //     allocations this large.
-  void *Stack = malloc(StackSize);
-  void *BottomOfStack = (char *)Stack + StackSize;
-
-  runOnNewStackImpl(BottomOfStack, callback, &Fn);
-
-  free(Stack);
-}
-#else
 void llvm::runOnNewStack(unsigned StackSize, function_ref<void()> Fn) {
   llvm::thread Thread(
       StackSize == 0 ? std::nullopt : std::optional<unsigned>(StackSize), Fn);
   Thread.join();
 }
-#endif



More information about the llvm-commits mailing list