amd/llvm: fix LLVM 15 & 16 crashes in SelectionDAG.cpp

Cc: stable

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21041>
This commit is contained in:
Marek Olšák 2023-01-24 22:26:38 -05:00 committed by Marge Bot
parent 0c0b978938
commit da7dfbe3b8
3 changed files with 38 additions and 0 deletions

View file

@ -33,6 +33,10 @@
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/Scalar.h>
#if LLVM_VERSION_MAJOR >= 15
#include "llvm/CodeGen/SelectionDAGNodes.h"
#endif
#include <cstring>
/* DO NOT REORDER THE HEADERS
@ -48,6 +52,37 @@
using namespace llvm;
#if LLVM_VERSION_MAJOR >= 15
class RunAtExitForStaticDestructors : public SDNode
{
public:
/* getSDVTList (protected) calls getValueTypeList (private), which contains static variables. */
RunAtExitForStaticDestructors(): SDNode(0, 0, DebugLoc(), getSDVTList(MVT::Other))
{
}
};
#endif
void ac_llvm_run_atexit_for_destructors(void)
{
#if LLVM_VERSION_MAJOR >= 15
/* 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.
*/
RunAtExitForStaticDestructors();
#endif
}
bool ac_is_llvm_processor_supported(LLVMTargetMachineRef tm, const char *processor)
{
TargetMachine *TM = reinterpret_cast<TargetMachine *>(tm);

View file

@ -64,6 +64,8 @@ static void ac_init_llvm_target(void)
ac_reset_llvm_all_options_occurences();
LLVMParseCommandLineOptions(ARRAY_SIZE(argv), argv, NULL);
ac_llvm_run_atexit_for_destructors();
}
PUBLIC void ac_init_shared_llvm_once(void)

View file

@ -78,6 +78,7 @@ struct ac_llvm_compiler {
LLVMTargetRef ac_get_llvm_target(const char *triple);
const char *ac_get_llvm_processor_name(enum radeon_family family);
void ac_llvm_run_atexit_for_destructors(void);
bool ac_is_llvm_processor_supported(LLVMTargetMachineRef tm, const char *processor);
void ac_reset_llvm_all_options_occurences();
void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes);