Module: Mesa Branch: staging/23.3 Commit: 548cc0dd8c8413b7e1c030c37b4694e18f34f3cc URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=548cc0dd8c8413b7e1c030c37b4694e18f34f3cc
Author: Dave Airlie <airl...@redhat.com> Date: Thu Jan 4 06:17:50 2024 +1000 gallivm: handle llvm 16 atexit ordering problems. This is ported from amd ac_llvm_helper.cpp, thanks to Marek for the pointer. This is needed to avoid crashes due to atexit ordering between some piglit tests and mesa internals. Cc: mesa-stable Reviewed-by: Konstantin Seurer <konstantin.seu...@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26883> (cherry picked from commit b3cfec2fd824a52023c92fd5928f4f5c1cb449a0) --- .pick_status.json | 2 +- src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 34 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index e5127e99f5c..eb12e5ec938 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -364,7 +364,7 @@ "description": "gallivm: handle llvm 16 atexit ordering problems.", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index e213f7e4be1..a5e84d708f2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -62,6 +62,7 @@ #include <llvm/Support/PrettyStackTrace.h> #include <llvm/ExecutionEngine/ObjectCache.h> #include <llvm/Support/TargetSelect.h> +#include <llvm/CodeGen/SelectionDAGNodes.h> #if LLVM_VERSION_MAJOR >= 15 #include <llvm/Support/MemoryBuffer.h> #endif @@ -100,6 +101,8 @@ #include "lp_bld_misc.h" #include "lp_bld_debug.h" +static void lp_run_atexit_for_destructors(void); + namespace { class LLVMEnsureMultithreaded { @@ -147,6 +150,7 @@ static void init_native_targets() } } #endif + lp_run_atexit_for_destructors(); } extern "C" void @@ -623,3 +627,33 @@ lp_set_module_stack_alignment_override(LLVMModuleRef MRef, unsigned align) M->setOverrideStackAlignment(align); #endif } + +using namespace llvm; + +class GallivmRunAtExitForStaticDestructors : public SDNode +{ +public: + /* getSDVTList (protected) calls getValueTypeList (private), which contains static variables. */ + GallivmRunAtExitForStaticDestructors(): SDNode(0, 0, DebugLoc(), getSDVTList(MVT::Other)) + { + } +}; + +static void +lp_run_atexit_for_destructors(void) +{ + /* LLVM >= 16 registers static variable destructors on the first compile, which gcc + * implements by calling atexit there. Before that, u_queue registers its atexit + * handler to kill all threads. Since exit() runs atexit handlers in the reverse order, + * the LLVM destructors are called first while shader compiler threads may still be + * running, which crashes in LLVM in SelectionDAG.cpp. + * + * The solution is to run the code that declares the LLVM static variables first, + * so that atexit for LLVM is registered first and u_queue is registered after that, + * which ensures that all u_queue threads are terminated before LLVM destructors are + * called. + * + * This just executes the code that declares static variables. + */ + GallivmRunAtExitForStaticDestructors(); +}