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();
+}

Reply via email to