Skip to content

Bump LLVM to v20 #58142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions contrib/refresh_checksums.mk
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@ checksum-$(1)-$(2)-$(3): clean-$(1)
# Add this guy to his project target
checksum-$(1): checksum-$(1)-$(2)-$(3)

# Add a dependency to the pack target
# TODO: can we make this so it only adds an ordering but not a dependency?
pack-checksum-$(1): | checksum-$(1)

# Add this guy to the `checksum` and `pack-checksum` default targets (e.g. `make -f contrib/refresh_checksums.mk openblas`)
checksum: checksum-$1
$1 pack-checksum: pack-checksum-$1
Expand Down Expand Up @@ -100,7 +96,7 @@ checksum-doc-unicodedata:
all: checksum-doc-unicodedata
.PHONY: checksum-doc-unicodedata

# merge substring project names to avoid races
# merge substring project names (llvm and llvm-tools, libsuitesparse and suitesparse) to avoid races
pack-checksum-llvm-tools: | pack-checksum-llvm
@# nothing to do but disable the prefix rule
pack-checksum-llvm: | checksum-llvm-tools
Expand All @@ -110,18 +106,21 @@ pack-checksum-compilersupportlibraries: | checksum-csl
pack-checksum-libsuitesparse: | pack-checksum-suitesparse
@# nothing to do but disable the prefix rule
pack-checksum-suitesparse: | checksum-libsuitesparse
# This is a bit tricky: we want llvmunwind to be separate from unwind and llvm,
# This is a bit tricky: we want llvmunwind, clang, and lld to be separate from unwind and llvm,
# so we add a rule to process those first
pack-checksum-llvm pack-checksum-unwind: | pack-checksum-llvmunwind
# and the name for LLVMLibUnwind is awkward, so handle that with a regex
pack-checksum-llvmunwind: | pack-checksum-llvm.*unwind
pack-checksum-llvm: | pack-checksum-clang pack-checksum-lld
# and the name for LLVMLibUnwind is awkward, so handle that packing with a regex
checksum-llvm.*unwind: checksum-llvmunwind
@# nothing to do but disable the prefix rule
pack-checksum-llvmunwind: | pack-checksum-llvm.*unwind # override general rule below
cd "$(JULIAHOME)/deps/checksums" && mv 'llvm.*unwind' llvmunwind

clean-%: FORCE
-rm "$(JULIAHOME)/deps/checksums"/'$*'

# define how to pack parallel checksums into a single file format
pack-checksum-%: FORCE
pack-checksum-%: FORCE | checksum-%
@echo making "$(JULIAHOME)/deps/checksums/"'$*'
@cd "$(JULIAHOME)/deps/checksums" && \
for each in $$(ls | grep -i '$*'); do \
Expand Down
120 changes: 120 additions & 0 deletions deps/checksums/clang

Large diffs are not rendered by default.

120 changes: 120 additions & 0 deletions deps/checksums/lld

Large diffs are not rendered by default.

726 changes: 244 additions & 482 deletions deps/checksums/llvm

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion deps/clang.version
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
## jll artifact
# Clang (paired with LLVM, only here as a JLL download)
CLANG_JLL_NAME := Clang
CLANG_JLL_VER := 19.1.7+1
CLANG_JLL_VER := 20.1.2+0
2 changes: 1 addition & 1 deletion deps/lld.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

## jll artifact
LLD_JLL_NAME := LLD
LLD_JLL_VER := 19.1.7+1
LLD_JLL_VER := 20.1.2+0
4 changes: 2 additions & 2 deletions deps/llvm-tools.version
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
## jll artifact
# LLVM_tools (downloads LLVM_jll to get things like `lit` and `opt`)
LLVM_TOOLS_JLL_NAME := LLVM
LLVM_TOOLS_JLL_VER := 19.1.7+1
LLVM_TOOLS_ASSERT_JLL_VER := 19.1.7+1
LLVM_TOOLS_JLL_VER := 20.1.2+0
LLVM_TOOLS_ASSERT_JLL_VER := 20.1.2+0
12 changes: 6 additions & 6 deletions deps/llvm.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

## jll artifact
LLVM_JLL_NAME := libLLVM
LLVM_ASSERT_JLL_VER := 19.1.7+2
LLVM_ASSERT_JLL_VER := 20.1.2+0
## source build
# Version number of LLVM
LLVM_VER := 19.1.7
LLVM_VER := 20.1.2
# Git branch name in `LLVM_GIT_URL` repository
LLVM_BRANCH=julia-19.1.7-2
LLVM_BRANCH=julia-20.1.2-0
# Git ref in `LLVM_GIT_URL` repository
LLVM_SHA1=julia-19.1.7-2
LLVM_SHA1=julia-20.1.2-0

## Following options are used to automatically fetch patchset from Julia's fork. This is
## useful if you want to build an external LLVM while still applying Julia's patches.
Expand All @@ -18,6 +18,6 @@ LLVM_APPLY_JULIA_PATCHES := 0
# GitHub repository to use for fetching the Julia patches to apply to LLVM source code.
LLVM_JULIA_DIFF_GITHUB_REPO := https://github.com/llvm/llvm-project
# Base GitHub ref for generating the diff.
LLVM_BASE_REF := llvm:llvmorg-19.1.7
LLVM_BASE_REF := llvm:llvmorg-20.1.2
# Julia fork's GitHub ref for generating the diff.
LLVM_JULIA_REF := JuliaLang:julia-19.1.7-2
LLVM_JULIA_REF := JuliaLang:julia-20.1.2-0
8 changes: 7 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endif
JCFLAGS += -Wold-style-definition -Wstrict-prototypes -Wc++-compat

ifeq ($(USECLANG),1)
FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment
FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment -Wno-nullability-extension -Wno-nullability-completeness # required to be allowed to use nullability extension and not be required to annotate all of everything
endif

ifeq (${USE_THIRD_PARTY_GC},mmtk)
Expand Down Expand Up @@ -226,6 +226,12 @@ DEBUGFLAGS_GCC += $(FLAGS) $(ADDL_DEBUGFLAGS)
SHIPFLAGS_CLANG += $(FLAGS) $(ADDL_SHIPFLAGS)
DEBUGFLAGS_CLANG += $(FLAGS) $(ADDL_DEBUGFLAGS)

DEBUGFLAGS_CLANG += -Wno-nullability-extension -Wno-nullability-completeness # required to be allowed to use nullability extension and not be required to annotate all of everything
ifeq ($(USEGCC),1) # TODO: we currently set flags incorrectly for clang analyze, but mostly it works out okay
DEBUGFLAGS_CLANG += -Wno-unknown-warning-option
endif
DEBUGFLAGS_CLANG += -Wno-return-type-c-linkage # TODO: do we care about fixing this instead? (it is not a bug, just a nuisance)

ifeq ($(USE_CROSS_FLISP), 1)
FLISPDIR := $(BUILDDIR)/flisp/host
FLISP_EXECUTABLE_debug := $(FLISPDIR)/flisp-debug$(BUILD_EXE)
Expand Down
7 changes: 5 additions & 2 deletions src/genericmemory.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jl_genericmemory_t *_new_genericmemory_(jl_value_t *mtype, size_t nel, int8_t is
{
if (nel == 0) // zero-sized allocation optimization
return (jl_genericmemory_t*)((jl_datatype_t*)mtype)->instance;
size_t nbytes;
size_t nbytes = 0; // initialized to workaround clang sa bug on v20: https://github.com/llvm/llvm-project/issues/136292
int overflow = __builtin_mul_overflow(nel, elsz, &nbytes);
if (isunion) {
// an extra byte for each isbits union memory element, stored at m->ptr + m->length
Expand Down Expand Up @@ -152,7 +152,7 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void
if (((uintptr_t)data) & ((align > JL_HEAP_ALIGNMENT ? JL_HEAP_ALIGNMENT : align) - 1))
jl_exceptionf(jl_argumenterror_type,
"unsafe_wrap: pointer %p is not properly aligned to %u bytes", data, align);
size_t nbytes;
size_t nbytes = 0; // initialized to workaround clang sa bug on v20: https://github.com/llvm/llvm-project/issues/136292
int overflow = __builtin_mul_overflow(nel, elsz, &nbytes);
if (isunion) {
// an extra byte for each isbits union memory element, stored at m->ptr + m->length
Expand Down Expand Up @@ -283,6 +283,9 @@ JL_DLLEXPORT jl_genericmemory_t *jl_genericmemory_copy_slice(jl_genericmemory_t
memcpy(jl_genericmemory_typetagdata(new_mem), jl_genericmemory_typetagdata(mem) + (size_t)data, len);
}
else if (layout->first_ptr != -1) {
if (data == NULL) {
assert(len * elsz / sizeof(void*) == 0); // make static analyzer happy
}
memmove_refs((_Atomic(void*)*)new_mem->ptr, (_Atomic(void*)*)data, len * elsz / sizeof(void*));
}
else if (data != NULL) {
Expand Down
3 changes: 0 additions & 3 deletions src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2008,17 +2008,14 @@ JuliaOJIT::JuliaOJIT()
reinterpret_cast<void *>(static_cast<uintptr_t>(msan_workaround::MSanTLS::origin))), JITSymbolFlags::Exported};
cantFail(GlobalJD.define(orc::absoluteSymbols(msan_crt)));
#endif
#if JL_LLVM_VERSION < 200000
#ifdef _COMPILER_ASAN_ENABLED_
// this is a hack to work around a bad assertion:
// /workspace/srcdir/llvm-project/llvm/lib/ExecutionEngine/Orc/Core.cpp:3028: llvm::Error llvm::orc::ExecutionSession::OL_notifyResolved(llvm::orc::MaterializationResponsibility&, const SymbolMap&): Assertion `(KV.second.getFlags() & ~JITSymbolFlags::Common) == (I->second & ~JITSymbolFlags::Common) && "Resolving symbol with incorrect flags"' failed.
// hopefully fixed upstream by e7698a13e319a9919af04d3d693a6f6ea7168a44
static int64_t jl___asan_globals_registered;
orc::SymbolMap asan_crt;
asan_crt[mangle("___asan_globals_registered")] = {ExecutorAddr::fromPtr(&jl___asan_globals_registered), JITSymbolFlags::Common | JITSymbolFlags::Exported};
cantFail(JD.define(orc::absoluteSymbols(asan_crt)));
#endif
#endif
}

JuliaOJIT::~JuliaOJIT() = default;
Expand Down
14 changes: 7 additions & 7 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,17 +489,17 @@ typedef struct _jl_abi_override_t {

typedef struct {
JL_DATA_TYPE
jl_sym_t *name;
jl_value_t *lb; // lower bound
jl_value_t *ub; // upper bound
jl_sym_t *JL_NONNULL name;
jl_value_t *JL_NONNULL lb; // lower bound
jl_value_t *JL_NONNULL ub; // upper bound
} jl_tvar_t;

// UnionAll type (iterated union over all values of a variable in certain bounds)
// written `body where lb<:var<:ub`
typedef struct {
JL_DATA_TYPE
jl_tvar_t *var;
jl_value_t *body;
jl_tvar_t *JL_NONNULL var;
jl_value_t *JL_NONNULL body;
} jl_unionall_t;

// represents the "name" part of a DataType, describing the syntactic structure
Expand Down Expand Up @@ -534,8 +534,8 @@ typedef struct {

typedef struct {
JL_DATA_TYPE
jl_value_t *a;
jl_value_t *b;
jl_value_t *JL_NONNULL a;
jl_value_t *JL_NONNULL b;
} jl_uniontype_t;

// in little-endian, isptr is always the first bit, avoiding the need for a branch in computing isptr
Expand Down
28 changes: 22 additions & 6 deletions src/llvm-expand-atomic-modify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <llvm/IR/InstIterator.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/IntrinsicInst.h>
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include <llvm/IR/Module.h>
#include <llvm/IR/Operator.h>
#include <llvm/IR/PassManager.h>
Expand Down Expand Up @@ -141,12 +142,28 @@ std::pair<Value *, Value *> insertRMWCmpXchgLoop(
}

// from AtomicExpandImpl
struct ReplacementIRBuilder : IRBuilder<InstSimplifyFolder> {
// IRBuilder to be used for replacement atomic instructions.
struct ReplacementIRBuilder
: IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> {
MDNode *MMRAMD = nullptr;

// Preserves the DebugLoc from I, and preserves still valid metadata.
// Enable StrictFP builder mode when appropriate.
explicit ReplacementIRBuilder(Instruction *I, const DataLayout &DL)
: IRBuilder(I->getContext(), DL) {
: IRBuilder(I->getContext(), InstSimplifyFolder(DL),
IRBuilderCallbackInserter(
[this](Instruction *I) { addMMRAMD(I); })) {
SetInsertPoint(I);
this->CollectMetadataToCopy(I, {LLVMContext::MD_pcsections});
if (BB->getParent()->getAttributes().hasFnAttr(Attribute::StrictFP))
this->setIsFPConstrained(true);

MMRAMD = I->getMetadata(LLVMContext::MD_mmra);
}

void addMMRAMD(Instruction *I) {
if (canInstructionHaveMMRAs(*I))
I->setMetadata(LLVMContext::MD_mmra, MMRAMD);
}
};

Expand Down Expand Up @@ -321,7 +338,6 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
Type *Ty = Modify.getFunctionType()->getReturnType()->getStructElementType(0);

ReplacementIRBuilder Builder(&Modify, Modify.getModule()->getDataLayout());
Builder.setIsFPConstrained(Modify.hasFnAttr(Attribute::StrictFP));

CallInst *ModifyOp;
{
Expand Down Expand Up @@ -366,7 +382,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
ModifyOp = cast<CallInst>(ValOp->getUser());
LoadedOp = ValOp;
assert(LoadedOp->get() == RMW);
RMW->moveBefore(ModifyOp); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
RMW->moveBeforePreserving(ModifyOp->getIterator()); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
BinOp = false;
if (++attempts > 3)
break;
Expand All @@ -383,7 +399,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
assert(isa<UndefValue>(RMW->getOperand(1))); // RMW was previously being used as the placeholder for Val
Value *Val;
if (ValOp != nullptr) {
RMW->moveBefore(cast<Instruction>(ValOp->getUser())); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
RMW->moveBeforePreserving(cast<Instruction>(ValOp->getUser())->getIterator()); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
Val = ValOp->get();
} else if (RMWOp == AtomicRMWInst::Xchg) {
Val = NewVal;
Expand Down Expand Up @@ -411,7 +427,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
Builder, Ty, Ptr, *Alignment, Ordering, SSID, Modify,
[&](IRBuilderBase &Builder, Value *Loaded) JL_NOTSAFEPOINT {
LoadedOp->set(Loaded);
ModifyOp->moveBefore(*Builder.GetInsertBlock(), Builder.GetInsertPoint());
ModifyOp->moveBeforePreserving(*Builder.GetInsertBlock(), Builder.GetInsertPoint());
return ModifyOp;
},
CreateWeakCmpXchg);
Expand Down
6 changes: 5 additions & 1 deletion src/stackwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,11 @@ static void decode_backtrace(jl_bt_element_t *bt_data, size_t bt_size,
bt = *btout = jl_alloc_array_1d(array_ptr_void_type, bt_size);
static_assert(sizeof(jl_bt_element_t) == sizeof(void*),
"jl_bt_element_t is presented as Ptr{Cvoid} on julia side");
memcpy(jl_array_data(bt, jl_bt_element_t), bt_data, bt_size * sizeof(jl_bt_element_t));
if (bt_data != NULL) {
memcpy(jl_array_data(bt, jl_bt_element_t), bt_data, bt_size * sizeof(jl_bt_element_t));
} else {
assert(bt_size == 0);
}
bt2 = *bt2out = jl_alloc_array_1d(jl_array_any_type, 0);
// Scan the backtrace buffer for any gc-managed values
for (size_t i = 0; i < bt_size; i += jl_bt_entry_size(bt_data + i)) {
Expand Down
10 changes: 6 additions & 4 deletions src/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ typedef struct {
// Most of the complexity is due to the "diagonal rule", requiring us to
// identify which type vars range over only concrete types.
typedef struct jl_varbinding_t {
jl_tvar_t *var;
jl_value_t *lb;
jl_value_t *ub;
jl_tvar_t *var; // store NULL to "delete" this from env (temporarily)
jl_value_t *JL_NONNULL lb;
jl_value_t *JL_NONNULL ub;
int8_t right; // whether this variable came from the right side of `A <: B`
int8_t occurs_inv; // occurs in invariant position
int8_t occurs_cov; // # of occurrences in covariant position
Expand Down Expand Up @@ -356,7 +356,7 @@ static void free_stenv(jl_stenv_t *e) JL_NOTSAFEPOINT

static void restore_env(jl_stenv_t *e, jl_savedenv_t *se, int root) JL_NOTSAFEPOINT
{
jl_value_t **roots = NULL;
jl_value_t *JL_NONNULL *roots = NULL;
int nroots = 0;
if (root) {
if (se->gcframe.nroots == JL_GC_ENCODE_PUSHARGS(1)) {
Expand Down Expand Up @@ -1182,12 +1182,14 @@ static int subtype_tuple_varargs(
if (bxp1) {
if (bxp1->intvalued == 0)
bxp1->intvalued = 1;
assert(bxp1->lb); // make static analyzer happy
if (jl_is_long(bxp1->lb))
xp1 = bxp1->lb;
}
if (byp1) {
if (byp1->intvalued == 0)
byp1->intvalued = 1;
assert(byp1->lb); // make static analyzer happy
if (jl_is_long(byp1->lb))
yp1 = byp1->lb;
}
Expand Down
21 changes: 11 additions & 10 deletions src/typemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,20 +286,20 @@ static _Atomic(jl_value_t*) *mtcache_hash_lookup_bp(jl_genericmemory_t *cache JL
return pml;
}

static void mtcache_hash_insert(_Atomic(jl_genericmemory_t*) *cache, jl_value_t *parent, jl_value_t *key, jl_typemap_t *val)
static void mtcache_hash_insert(_Atomic(jl_genericmemory_t*) *pcache, jl_value_t *parent, jl_value_t *key, jl_typemap_t *val)
{
int inserted = 0;
jl_genericmemory_t *a = jl_atomic_load_relaxed(cache);
jl_genericmemory_t *a = jl_atomic_load_relaxed(pcache);
if (a == (jl_genericmemory_t*)jl_an_empty_memory_any) {
a = jl_alloc_memory_any(16);
jl_atomic_store_release(cache, a);
jl_atomic_store_release(pcache, a);
if (parent)
jl_gc_wb(parent, a);
}
a = jl_eqtable_put(a, key, val, &inserted);
assert(inserted);
if (a != jl_atomic_load_relaxed(cache)) {
jl_atomic_store_release(cache, a);
if (a != jl_atomic_load_relaxed(pcache)) {
jl_atomic_store_release(pcache, a);
if (parent)
jl_gc_wb(parent, a);
}
Expand Down Expand Up @@ -1293,9 +1293,10 @@ static void jl_typemap_memory_insert_(
static jl_value_t *jl_method_convert_list_to_cache(
jl_typemap_t *map, jl_typemap_entry_t *ml, int8_t tparam, int8_t offs, int8_t doublesplit)
{
jl_value_t *cache = doublesplit ? jl_an_empty_memory_any : (jl_value_t*)jl_new_typemap_level();
_Atomic(jl_genericmemory_t*) dblcache = (jl_genericmemory_t*)jl_an_empty_memory_any;
jl_typemap_level_t *cache = doublesplit ? NULL : jl_new_typemap_level();
jl_typemap_entry_t *next = NULL;
JL_GC_PUSH3(&cache, &next, &ml);
JL_GC_PUSH4(&cache, &dblcache, &next, &ml);
while (ml != (void*)jl_nothing) {
next = jl_atomic_load_relaxed(&ml->next);
jl_atomic_store_relaxed(&ml->next, (jl_typemap_entry_t*)jl_nothing);
Expand All @@ -1316,14 +1317,14 @@ static jl_value_t *jl_method_convert_list_to_cache(
assert(jl_is_type_type(key));
key = jl_tparam0(key);
}
jl_typemap_memory_insert_(map, (_Atomic(jl_genericmemory_t*)*)&cache, key, ml, NULL, 0, offs, NULL);
jl_typemap_memory_insert_(map, &dblcache, key, ml, NULL, 0, offs, NULL);
}
else
jl_typemap_level_insert_(map, (jl_typemap_level_t*)cache, ml, offs);
jl_typemap_level_insert_(map, cache, ml, offs);
ml = next;
}
JL_GC_POP();
return cache;
return doublesplit ? (jl_value_t*)jl_atomic_load_relaxed(&dblcache) : (jl_value_t*)cache;
}

static void jl_typemap_list_insert_(
Expand Down
4 changes: 2 additions & 2 deletions stdlib/LLD_jll/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "LLD_jll"
uuid = "d55e3150-da41-5e91-b323-ecfd1eec6109"
version = "19.1.7+1"
version = "20.1.2+0"

[deps]
Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a"
Expand All @@ -10,7 +10,7 @@ Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[compat]
julia = "1.13"
libLLVM_jll = "19.1.7"
libLLVM_jll = "20.1.2"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
Loading