Date: Wednesday, June 22, 2022 @ 16:48:43 Author: arojas Revision: 1238979
LLVM/clang 14 rebuild Added: julia/trunk/074d761f.patch julia/trunk/144ebbaf.patch julia/trunk/ed9851b0.patch Modified: julia/trunk/PKGBUILD ----------------+ 074d761f.patch | 62 ++ 144ebbaf.patch | 1181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD | 12 ed9851b0.patch | 96 ++++ 4 files changed, 1350 insertions(+), 1 deletion(-) Added: 074d761f.patch =================================================================== --- 074d761f.patch (rev 0) +++ 074d761f.patch 2022-06-22 16:48:43 UTC (rev 1238979) @@ -0,0 +1,62 @@ +From 074d761f00c41fc55f6fab0cb4c6969a9c09e27b Mon Sep 17 00:00:00 2001 +From: Valentin Churavy <[email protected]> +Date: Fri, 18 Feb 2022 14:37:41 -0500 +Subject: [PATCH] fix some missing includes + +--- + src/llvm-alloc-helpers.cpp | 2 ++ + src/llvm-demote-float16.cpp | 1 + + src/llvm-late-gc-lowering.cpp | 1 + + src/llvm-lower-handlers.cpp | 1 + + src/llvm-remove-ni.cpp | 1 + + 5 files changed, 6 insertions(+) + +diff --git a/src/llvm-demote-float16.cpp b/src/llvm-demote-float16.cpp +index 25c93252558bb..46126c0ec06e3 100644 +--- a/src/llvm-demote-float16.cpp ++++ b/src/llvm-demote-float16.cpp +@@ -19,6 +19,8 @@ + #include "support/dtypes.h" + #include "passes.h" + ++#include <llvm/Pass.h> ++#include <llvm/IR/IntrinsicInst.h> + #include <llvm/IR/IRBuilder.h> + #include <llvm/IR/LegacyPassManager.h> + #include <llvm/IR/PassManager.h> +diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp +index 6069c7f2e2869..e0163b14a0189 100644 +--- a/src/llvm-late-gc-lowering.cpp ++++ b/src/llvm-late-gc-lowering.cpp +@@ -34,6 +34,7 @@ + #include "julia_internal.h" + #include "julia_assert.h" + #include "llvm-pass-helpers.h" ++#include <map> + + #define DEBUG_TYPE "late_lower_gcroot" + +diff --git a/src/llvm-lower-handlers.cpp b/src/llvm-lower-handlers.cpp +index 324c591f77be8..045056805bddd 100644 +--- a/src/llvm-lower-handlers.cpp ++++ b/src/llvm-lower-handlers.cpp +@@ -22,6 +22,7 @@ + + #include "julia.h" + #include "julia_assert.h" ++#include <map> + + #define DEBUG_TYPE "lower_handlers" + #undef DEBUG +diff --git a/src/llvm-remove-ni.cpp b/src/llvm-remove-ni.cpp +index 50a6041c017e0..13680064211c7 100644 +--- a/src/llvm-remove-ni.cpp ++++ b/src/llvm-remove-ni.cpp +@@ -3,6 +3,7 @@ + #include "llvm-version.h" + #include "passes.h" + ++#include <llvm/Pass.h> + #include <llvm/IR/Module.h> + #include <llvm/IR/PassManager.h> + #include <llvm/IR/LegacyPassManager.h> Added: 144ebbaf.patch =================================================================== --- 144ebbaf.patch (rev 0) +++ 144ebbaf.patch 2022-06-22 16:48:43 UTC (rev 1238979) @@ -0,0 +1,1181 @@ +From 144ebbaf7ad0594986bd9a6d08aae57246643de9 Mon Sep 17 00:00:00 2001 +From: David Nadlinger <[email protected]> +Date: Wed, 5 Jan 2022 03:25:54 +0100 +Subject: [PATCH] Support LLVM 14 (upstream Git main) (#43628) + +Compiles against llvm/llvm-project#2ec3ca747732, with some of +our unmerged local patches from 13.x still required. + +Unfortunately, there is quite a bit of fallout from the various +attribute API renames. I chose to introduce some function shims +to separate out all the preprocessor #if clutter. +--- + src/aotcompile.cpp | 4 + + src/ccall.cpp | 40 ++++----- + src/cgutils.cpp | 49 +++++------ + src/codegen.cpp | 83 ++++++++++--------- + src/codegen_shared.h | 128 ++++++++++++++++++++++++++++- + src/disasm.cpp | 8 ++ + src/intrinsics.cpp | 14 ++-- + src/jitlayers.cpp | 8 +- + src/llvm-alloc-opt.cpp | 14 ++-- + src/llvm-final-gc-lowering.cpp | 16 ++-- + src/llvm-gc-invariant-verifier.cpp | 2 +- + src/llvm-julia-licm.cpp | 2 +- + src/llvm-late-gc-lowering.cpp | 20 ++--- + src/llvm-pass-helpers.cpp | 8 +- + src/llvm-ptls.cpp | 4 +- + src/llvm-remove-addrspaces.cpp | 16 +++- + 16 files changed, 287 insertions(+), 129 deletions(-) + +diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp +index f96894f93c17d..7284d0bf7f0a7 100644 +--- a/src/aotcompile.cpp ++++ b/src/aotcompile.cpp +@@ -8,7 +8,11 @@ + + // target support + #include <llvm/ADT/Triple.h> ++#if JL_LLVM_VERSION >= 140000 ++#include <llvm/MC/TargetRegistry.h> ++#else + #include <llvm/Support/TargetRegistry.h> ++#endif + #include <llvm/Target/TargetMachine.h> + #include <llvm/IR/DataLayout.h> + #include <llvm/Analysis/TargetTransformInfo.h> +diff --git a/src/ccall.cpp b/src/ccall.cpp +index f6d3dd5e8b1f9..c51385e647790 100644 +--- a/src/ccall.cpp ++++ b/src/ccall.cpp +@@ -223,8 +223,7 @@ static GlobalVariable *emit_plt_thunk( + // NoReturn function can trigger LLVM verifier error when declared as + // MustTail since other passes might replace the `ret` with + // `unreachable` (LLVM should probably accept `unreachable`). +- if (attrs.hasAttribute(AttributeList::FunctionIndex, +- Attribute::NoReturn)) { ++ if (hasFnAttr(attrs, Attribute::NoReturn)) { + irbuilder.CreateUnreachable(); + } + else { +@@ -272,7 +271,7 @@ static Value *emit_plt( + functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib); + } + GlobalVariable *got = prepare_global_in(jl_Module, sharedgot); +- LoadInst *got_val = ctx.builder.CreateAlignedLoad(got, Align(sizeof(void*))); ++ LoadInst *got_val = ctx.builder.CreateAlignedLoad(got->getType()->getElementType(), got, Align(sizeof(void*))); + // See comment in `runtime_sym_lookup` above. This in principle needs a + // consume ordering too. This is even less likely to cause issues though + // since the only thing we do to this loaded pointer is to call it +@@ -404,7 +403,7 @@ static Value *llvm_type_rewrite( + to = emit_bitcast(ctx, from, target_type->getPointerTo()); + } + ctx.builder.CreateAlignedStore(v, from, Align(align)); +- return ctx.builder.CreateAlignedLoad(to, Align(align)); ++ return ctx.builder.CreateAlignedLoad(target_type, to, Align(align)); + } + + // --- argument passing and scratch space utilities --- +@@ -422,8 +421,7 @@ static Value *runtime_apply_type_env(jl_codectx_t &ctx, jl_value_t *ty) + ConstantInt::get(T_size, sizeof(jl_svec_t) / sizeof(jl_value_t*))) + }; + auto call = ctx.builder.CreateCall(prepare_call(jlapplytype_func), makeArrayRef(args)); +- call->addAttribute(AttributeList::ReturnIndex, +- Attribute::getWithAlignment(jl_LLVMContext, Align(16))); ++ addRetAttr(call, Attribute::getWithAlignment(jl_LLVMContext, Align(16))); + return call; + } + +@@ -1125,16 +1123,13 @@ std::string generate_func_sig(const char *fname) + const auto &as = paramattrs.at(i); + if (!as.hasAttributes()) + continue; +- attributes = attributes.addAttributes(jl_LLVMContext, i + 1, as); ++ attributes = addAttributesAtIndex(attributes, jl_LLVMContext, i + 1, as); + } + // If return value is boxed it must be non-null. + if (retboxed) +- attributes = attributes.addAttribute(jl_LLVMContext, AttributeList::ReturnIndex, +- Attribute::NonNull); ++ attributes = addRetAttribute(attributes, jl_LLVMContext, Attribute::NonNull); + if (rt == jl_bottom_type) { +- attributes = attributes.addAttribute(jl_LLVMContext, +- AttributeList::FunctionIndex, +- Attribute::NoReturn); ++ attributes = addFnAttribute(attributes, jl_LLVMContext, Attribute::NoReturn); + } + return ""; + } +@@ -1487,8 +1482,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + Value *ptask_i16 = emit_bitcast(ctx, get_current_task(ctx), T_pint16); + const int tid_offset = offsetof(jl_task_t, tid); +- Value *ptid = ctx.builder.CreateInBoundsGEP(ptask_i16, ConstantInt::get(T_size, tid_offset / sizeof(int16_t))); +- LoadInst *tid = ctx.builder.CreateAlignedLoad(ptid, Align(sizeof(int16_t))); ++ Value *ptid = ctx.builder.CreateInBoundsGEP(T_int16, ptask_i16, ConstantInt::get(T_size, tid_offset / sizeof(int16_t))); ++ LoadInst *tid = ctx.builder.CreateAlignedLoad(T_int16, ptid, Align(sizeof(int16_t))); + tbaa_decorate(tbaa_gcframe, tid); + return mark_or_box_ccall_result(ctx, tid, retboxed, rt, unionall, static_rt); + } +@@ -1500,8 +1495,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + Value *ptls_i32 = emit_bitcast(ctx, get_current_ptls(ctx), T_pint32); + const int finh_offset = offsetof(jl_tls_states_t, finalizers_inhibited); +- Value *pfinh = ctx.builder.CreateInBoundsGEP(ptls_i32, ConstantInt::get(T_size, finh_offset / 4)); +- LoadInst *finh = ctx.builder.CreateAlignedLoad(pfinh, Align(sizeof(int32_t))); ++ Value *pfinh = ctx.builder.CreateInBoundsGEP(T_int32, ptls_i32, ConstantInt::get(T_size, finh_offset / 4)); ++ LoadInst *finh = ctx.builder.CreateAlignedLoad(T_int32, pfinh, Align(sizeof(int32_t))); + Value *newval; + if (is_libjulia_func(jl_gc_disable_finalizers_internal)) { + newval = ctx.builder.CreateAdd(finh, ConstantInt::get(T_int32, 1)); +@@ -1527,7 +1522,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + Value *ptls_pv = emit_bitcast(ctx, get_current_ptls(ctx), T_ppjlvalue); + const int nt_offset = offsetof(jl_tls_states_t, next_task); +- Value *pnt = ctx.builder.CreateInBoundsGEP(ptls_pv, ConstantInt::get(T_size, nt_offset / sizeof(void*))); ++ Value *pnt = ctx.builder.CreateInBoundsGEP(T_pjlvalue, ptls_pv, ConstantInt::get(T_size, nt_offset / sizeof(void*))); + ctx.builder.CreateStore(emit_pointer_from_objref(ctx, boxed(ctx, argv[0])), pnt); + return ghostValue(jl_nothing_type); + } +@@ -1537,7 +1532,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + ctx.builder.CreateCall(prepare_call(gcroot_flush_func)); + Value *pdefer_sig = emit_defer_signal(ctx); +- Value *defer_sig = ctx.builder.CreateLoad(pdefer_sig); ++ Value *defer_sig = ctx.builder.CreateLoad(T_sigatomic, pdefer_sig); + defer_sig = ctx.builder.CreateAdd(defer_sig, ConstantInt::get(T_sigatomic, 1)); + ctx.builder.CreateStore(defer_sig, pdefer_sig); + emit_signal_fence(ctx); +@@ -1549,7 +1544,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + ctx.builder.CreateCall(prepare_call(gcroot_flush_func)); + Value *pdefer_sig = emit_defer_signal(ctx); +- Value *defer_sig = ctx.builder.CreateLoad(pdefer_sig); ++ Value *defer_sig = ctx.builder.CreateLoad(T_sigatomic, pdefer_sig); + emit_signal_fence(ctx); + error_unless(ctx, + ctx.builder.CreateICmpNE(defer_sig, ConstantInt::get(T_sigatomic, 0)), +@@ -1566,6 +1561,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + checkBB, contBB); + ctx.builder.SetInsertPoint(checkBB); + ctx.builder.CreateLoad( ++ T_size, + ctx.builder.CreateConstInBoundsGEP1_32(T_size, get_current_signal_page(ctx), -1), + true); + ctx.builder.CreateBr(contBB); +@@ -1725,8 +1721,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) + JL_GC_POP(); + const int hash_offset = offsetof(jl_sym_t, hash); + Value *ph1 = emit_bitcast(ctx, decay_derived(ctx, boxed(ctx, val)), T_psize); +- Value *ph2 = ctx.builder.CreateInBoundsGEP(ph1, ConstantInt::get(T_size, hash_offset / sizeof(size_t))); +- LoadInst *hashval = ctx.builder.CreateAlignedLoad(ph2, Align(sizeof(size_t))); ++ Value *ph2 = ctx.builder.CreateInBoundsGEP(T_size, ph1, ConstantInt::get(T_size, hash_offset / sizeof(size_t))); ++ LoadInst *hashval = ctx.builder.CreateAlignedLoad(T_size, ph2, Align(sizeof(size_t))); + tbaa_decorate(tbaa_const, hashval); + return mark_or_box_ccall_result(ctx, hashval, retboxed, rt, unionall, static_rt); + } +@@ -1951,7 +1947,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( + // something alloca'd above is SSA + if (static_rt) + return mark_julia_slot(result, rt, NULL, tbaa_stack); +- result = ctx.builder.CreateLoad(result); ++ result = ctx.builder.CreateLoad(cast<PointerType>(result->getType())->getElementType(), result); + } + } + else { +diff --git a/src/cgutils.cpp b/src/cgutils.cpp +index 007827ebe7b7e..9bff5634382c4 100644 +--- a/src/cgutils.cpp ++++ b/src/cgutils.cpp +@@ -795,19 +795,21 @@ static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, Value *idx) + idx); + } + +-static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, Value *idx, MDNode *tbaa, Type *ptype) ++static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, Value *idx, MDNode *tbaa, Type *type) + { +- // p = (jl_value_t**)v; *(ptype)&p[n] ++ // p = (jl_value_t**)v; *(type*)&p[n] + Value *vptr = emit_nthptr_addr(ctx, v, idx); +- return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(emit_bitcast(ctx, vptr, ptype)))); ++ return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type, ++ emit_bitcast(ctx, vptr, PointerType::get(type, 0))))); + } + +-static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa, Type *ptype) ++static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa, Type *type) + { +- // p = (jl_value_t**)v; *(ptype)&p[n] ++ // p = (jl_value_t**)v; *(type*)&p[n] + Value *vptr = emit_nthptr_addr(ctx, v, n); +- return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(emit_bitcast(ctx, vptr, ptype)))); +-} ++ return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type, ++ emit_bitcast(ctx, vptr, PointerType::get(type, 0))))); ++ } + + static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &v); + +@@ -1506,7 +1508,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j + alignment = sizeof(void*); + else if (!alignment) + alignment = julia_alignment(jltype); +- LoadInst *load = ctx.builder.CreateAlignedLoad(data, Align(alignment), false); ++ LoadInst *load = ctx.builder.CreateAlignedLoad(elty, data, Align(alignment), false); + load->setOrdering(Order); + if (aliasscope) + load->setMetadata("alias.scope", aliasscope); +@@ -1519,7 +1521,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j + instr = ctx.builder.CreateTrunc(instr, realelty); + if (intcast) { + ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo())); +- instr = ctx.builder.CreateLoad(intcast); ++ instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + } + if (maybe_null_if_boxed) { + Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr); +@@ -1586,7 +1588,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, + return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv); + } + } +- Value *intcast = nullptr; ++ AllocaInst *intcast = nullptr; + if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) { + const DataLayout &DL = jl_data_layout; + unsigned nb = DL.getTypeSizeInBits(elty); +@@ -1736,7 +1738,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, + if (intcast) { + ctx.builder.CreateStore(realCompare, ctx.builder.CreateBitCast(intcast, realCompare->getType()->getPointerTo())); + if (maybe_null_if_boxed) +- realCompare = ctx.builder.CreateLoad(intcast); ++ realCompare = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + } + if (maybe_null_if_boxed) { + Value *first_ptr = isboxed ? Compare : extract_first_ptr(ctx, Compare); +@@ -1816,7 +1818,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, + ctx.builder.CreateStore(realinstr, ctx.builder.CreateBitCast(intcast, realinstr->getType()->getPointerTo())); + oldval = mark_julia_slot(intcast, jltype, NULL, tbaa_stack); + if (maybe_null_if_boxed) +- realinstr = ctx.builder.CreateLoad(intcast); ++ realinstr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + } + else { + oldval = mark_julia_type(ctx, realinstr, isboxed, jltype); +@@ -1876,7 +1878,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, + instr = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, instr, realelty)); + if (intcast) { + ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo())); +- instr = ctx.builder.CreateLoad(intcast); ++ instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast); + } + if (maybe_null_if_boxed) { + Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr); +@@ -1949,18 +1951,18 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Va + dstty = dstel->getPointerTo(); + } + +- bool direct = false; ++ llvm::Type *directel = nullptr; + if (srcel->isSized() && srcel->isSingleValueType() && DL.getTypeStoreSize(srcel) == sz) { +- direct = true; ++ directel = srcel; + dst = emit_bitcast(ctx, dst, srcty); + } + else if (dstel->isSized() && dstel->isSingleValueType() && + DL.getTypeStoreSize(dstel) == sz) { +- direct = true; ++ directel = dstel; + src = emit_bitcast(ctx, src, dstty); + } +- if (direct) { +- auto val = tbaa_decorate(tbaa_src, ctx.builder.CreateAlignedLoad(src, Align(align), is_volatile)); ++ if (directel) { ++ auto val = tbaa_decorate(tbaa_src, ctx.builder.CreateAlignedLoad(directel, src, Align(align), is_volatile)); + tbaa_decorate(tbaa_dst, ctx.builder.CreateAlignedStore(val, dst, Align(align), is_volatile)); + return; + } +@@ -2430,7 +2432,7 @@ static Value *emit_arraysize(jl_codectx_t &ctx, const jl_cgval_t &tinfo, Value * + auto load = emit_nthptr_recast(ctx, + t, + ctx.builder.CreateAdd(dim, ConstantInt::get(dim->getType(), o)), +- tbaa, T_psize); ++ tbaa, T_size); + MDBuilder MDB(jl_LLVMContext); + auto rng = MDB.createRange(V_size0, ConstantInt::get(T_size, arraytype_maxsize(tinfo.typ))); + load->setMetadata(LLVMContext::MD_range, rng); +@@ -2466,7 +2468,7 @@ static Value *emit_arraylen_prim(jl_codectx_t &ctx, const jl_cgval_t &tinfo) + Value *addr = ctx.builder.CreateStructGEP(jl_array_llvmt, + emit_bitcast(ctx, decay_derived(ctx, t), jl_parray_llvmt), + 1); //index (not offset) of length field in jl_parray_llvmt +- LoadInst *len = ctx.builder.CreateAlignedLoad(addr, Align(sizeof(size_t))); ++ LoadInst *len = ctx.builder.CreateAlignedLoad(T_size, addr, Align(sizeof(size_t))); + len->setOrdering(AtomicOrdering::NotAtomic); + MDBuilder MDB(jl_LLVMContext); + auto rng = MDB.createRange(V_size0, ConstantInt::get(T_size, arraytype_maxsize(tinfo.typ))); +@@ -2519,7 +2521,8 @@ static Value *emit_arrayptr_internal(jl_codectx_t &ctx, const jl_cgval_t &tinfo, + PointerType::get(PPT->getElementType(), AS), + PT->getAddressSpace())); + } +- LoadInst *LI = ctx.builder.CreateAlignedLoad(addr, Align(sizeof(char*))); ++ LoadInst *LI = ctx.builder.CreateAlignedLoad( ++ cast<PointerType>(addr->getType())->getElementType(), addr, Align(sizeof(char*))); + LI->setOrdering(AtomicOrdering::NotAtomic); + LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(jl_LLVMContext, None)); + tbaa_decorate(tbaa, LI); +@@ -2828,9 +2831,9 @@ static Value *as_value(jl_codectx_t &ctx, Type *to, const jl_cgval_t &v) + static Value *load_i8box(jl_codectx_t &ctx, Value *v, jl_datatype_t *ty) + { + auto jvar = ty == jl_int8_type ? jlboxed_int8_cache : jlboxed_uint8_cache; +- Constant *gv = prepare_global_in(jl_Module, jvar); ++ GlobalVariable *gv = prepare_global_in(jl_Module, jvar); + Value *idx[] = {ConstantInt::get(T_int32, 0), ctx.builder.CreateZExt(v, T_int32)}; +- auto slot = ctx.builder.CreateInBoundsGEP(gv, idx); ++ auto slot = ctx.builder.CreateInBoundsGEP(gv->getType()->getElementType(), gv, idx); + return tbaa_decorate(tbaa_const, maybe_mark_load_dereferenceable( + ctx.builder.CreateAlignedLoad(T_pjlvalue, slot, Align(sizeof(void*))), false, + (jl_value_t*)ty)); +diff --git a/src/codegen.cpp b/src/codegen.cpp +index ba933b60e554d..18e95fc169c8d 100644 +--- a/src/codegen.cpp ++++ b/src/codegen.cpp +@@ -30,7 +30,11 @@ + + // target machine computation + #include <llvm/CodeGen/TargetSubtargetInfo.h> ++#if JL_LLVM_VERSION >= 140000 ++#include <llvm/MC/TargetRegistry.h> ++#else + #include <llvm/Support/TargetRegistry.h> ++#endif + #include <llvm/Target/TargetOptions.h> + #include <llvm/Support/Host.h> + #include <llvm/Support/TargetSelect.h> +@@ -867,11 +871,6 @@ extern "C" { + jl_rettype_inferred, NULL }; + } + +-template<typename T> +-static void add_return_attr(T *f, Attribute::AttrKind Kind) +-{ +- f->addAttribute(AttributeList::ReturnIndex, Kind); +-} + + static MDNode *best_tbaa(jl_value_t *jt) { + jt = jl_unwrap_unionall(jt); +@@ -1822,7 +1821,7 @@ static void visitLine(jl_codectx_t &ctx, uint64_t *ptr, Value *addend, const cha + Value *pv = ConstantExpr::getIntToPtr( + ConstantInt::get(T_size, (uintptr_t)ptr), + T_pint64); +- Value *v = ctx.builder.CreateLoad(pv, true, name); ++ Value *v = ctx.builder.CreateLoad(T_int64, pv, true, name); + v = ctx.builder.CreateAdd(v, addend); + ctx.builder.CreateStore(v, pv, true); // volatile, not atomic, so this might be an underestimate, + // but it's faster this way +@@ -2961,7 +2960,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, + Value *idx = emit_unbox(ctx, T_size, fld, (jl_value_t*)jl_long_type); + idx = emit_bounds_check(ctx, va_ary, NULL, idx, valen, boundscheck); + idx = ctx.builder.CreateAdd(idx, ConstantInt::get(T_size, ctx.nReqArgs)); +- Instruction *v = ctx.builder.CreateAlignedLoad(T_prjlvalue, ctx.builder.CreateInBoundsGEP(ctx.argArray, idx), Align(sizeof(void*))); ++ Instruction *v = ctx.builder.CreateAlignedLoad(T_prjlvalue, ctx.builder.CreateInBoundsGEP(T_prjlvalue, ctx.argArray, idx), Align(sizeof(void*))); + // if we know the result type of this load, we will mark that information here too + tbaa_decorate(tbaa_value, maybe_mark_load_dereferenceable(v, false, rt)); + *ret = mark_julia_type(ctx, v, /*boxed*/ true, rt); +@@ -3278,7 +3277,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, Function *theFptr, Value *theF, + CallInst *result = ctx.builder.CreateCall(FTy, + ctx.builder.CreateBitCast(theFptr, FTy->getPointerTo()), + theArgs); +- add_return_attr(result, Attribute::NonNull); ++ addRetAttr(result, Attribute::NonNull); + result->setCallingConv(cc); + return result; + } +@@ -3409,7 +3408,7 @@ static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty + { + auto theFptr = cast<Function>( + jl_Module->getOrInsertFunction(specFunctionObject, jl_func_sig).getCallee()); +- add_return_attr(theFptr, Attribute::NonNull); ++ addRetAttr(theFptr, Attribute::NonNull); + theFptr->addFnAttr(Thunk); + Value *ret = emit_jlcall(ctx, theFptr, nullptr, argv, nargs, JLCALL_F_CC); + return update_julia_type(ctx, mark_julia_type(ctx, ret, true, jlretty), inferred_retty); +@@ -4285,7 +4284,8 @@ static void emit_stmtpos(jl_codectx_t &ctx, jl_value_t *expr, int ssaval_result) + else { + if (!jl_is_method(ctx.linfo->def.method) && !ctx.is_opaque_closure) { + // TODO: inference is invalid if this has any effect (which it often does) +- Value *world = ctx.builder.CreateAlignedLoad(prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t))); ++ LoadInst *world = ctx.builder.CreateAlignedLoad(T_size, ++ prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t))); + // TODO: world->setOrdering(AtomicOrdering::Monotonic); + ctx.builder.CreateAlignedStore(world, ctx.world_age_field, Align(sizeof(size_t))); + } +@@ -4659,7 +4659,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval) + + jl_cgval_t world_age = mark_julia_type(ctx, + tbaa_decorate(tbaa_gcframe, +- ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))), ++ ctx.builder.CreateAlignedLoad(T_size, ctx.world_age_field, Align(sizeof(size_t)))), + false, + jl_long_type); + +@@ -4823,8 +4823,7 @@ static Value *get_current_signal_page(jl_codectx_t &ctx) + // return ctx.builder.CreateCall(prepare_call(reuse_signal_page_func)); + auto ptls = get_current_ptls(ctx); + int nthfield = offsetof(jl_tls_states_t, safepoint) / sizeof(void *); +- return emit_nthptr_recast(ctx, ptls, nthfield, tbaa_const, +- PointerType::get(T_psize, 0)); ++ return emit_nthptr_recast(ctx, ptls, nthfield, tbaa_const, T_psize); + } + + static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_codegen_params_t ¶ms) +@@ -4927,7 +4926,7 @@ static void emit_cfunc_invalidate( + } + else { + gf_ret = emit_bitcast(ctx, gf_ret, gfrt->getPointerTo()); +- ctx.builder.CreateRet(ctx.builder.CreateAlignedLoad(gf_ret, Align(julia_alignment(rettype)))); ++ ctx.builder.CreateRet(ctx.builder.CreateAlignedLoad(gfrt, gf_ret, Align(julia_alignment(rettype)))); + } + break; + } +@@ -5033,7 +5032,13 @@ static Function* gen_cfun_wrapper( + // we are adding the extra nest parameter after sret arg. + std::vector<std::pair<unsigned, AttributeSet>> newAttributes; + newAttributes.reserve(attributes.getNumAttrSets() + 1); ++#if JL_LLVM_VERSION >= 140000 ++ auto it = *attributes.indexes().begin(); ++ const auto it_end = *attributes.indexes().end(); ++#else + auto it = attributes.index_begin(); ++ const auto it_end = attributes.index_end(); ++#endif + + // Skip past FunctionIndex + if (it == AttributeList::AttrIndex::FunctionIndex) { +@@ -5042,7 +5047,7 @@ static Function* gen_cfun_wrapper( + + // Move past ReturnValue and parameter return value + for (;it < AttributeList::AttrIndex::FirstArgIndex + sig.sret; ++it) { +- if (attributes.hasAttributes(it)) { ++ if (hasAttributesAtIndex(attributes, it)) { + newAttributes.emplace_back(it, attributes.getAttributes(it)); + } + } +@@ -5054,17 +5059,17 @@ static Function* gen_cfun_wrapper( + + // Shift forward the rest of the attributes + if (attributes.getNumAttrSets() > 0) { // without this check the loop range below is invalid +- for(;it < attributes.index_end(); ++it) { +- if (attributes.hasAttributes(it)) { ++ for(; it != it_end; ++it) { ++ if (hasAttributesAtIndex(attributes, it)) { + newAttributes.emplace_back(it + 1, attributes.getAttributes(it)); + } + } + } + + // Remember to add back FunctionIndex +- if (attributes.hasAttributes(AttributeList::AttrIndex::FunctionIndex)) { ++ if (hasAttributesAtIndex(attributes, AttributeList::AttrIndex::FunctionIndex)) { + newAttributes.emplace_back(AttributeList::AttrIndex::FunctionIndex, +- attributes.getAttributes(AttributeList::AttrIndex::FunctionIndex)); ++ getFnAttrs(attributes)); + } + + // Create the new AttributeList +@@ -5098,8 +5103,9 @@ static Function* gen_cfun_wrapper( + // TODO: in the future, try to initialize a full TLS context here + // for now, just use a dummy field to avoid a branch in this function + ctx.world_age_field = ctx.builder.CreateSelect(have_tls, ctx.world_age_field, dummy_world); +- Value *last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))); +- Value *world_v = ctx.builder.CreateAlignedLoad(prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t))); ++ Value *last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(T_size, ctx.world_age_field, Align(sizeof(size_t)))); ++ Value *world_v = ctx.builder.CreateAlignedLoad(T_size, ++ prepare_global_in(jl_Module, jlgetworld_global), Align(sizeof(size_t))); + // TODO: cast<LoadInst>(world_v)->setOrdering(AtomicOrdering::Monotonic); + + Value *age_ok = NULL; +@@ -5180,7 +5186,7 @@ static Function* gen_cfun_wrapper( + } + else { + val = emit_bitcast(ctx, val, T->getPointerTo()); +- val = ctx.builder.CreateAlignedLoad(val, Align(1)); // make no alignment assumption about pointer from C ++ val = ctx.builder.CreateAlignedLoad(T, val, Align(1)); // make no alignment assumption about pointer from C + inputarg = mark_julia_type(ctx, val, false, jargty); + } + } +@@ -5241,7 +5247,7 @@ static Function* gen_cfun_wrapper( + assert(jl_is_datatype(jargty)); + if (sig.byRefList.at(i)) { + assert(cast<PointerType>(val->getType())->getElementType() == sig.fargt[i]); +- val = ctx.builder.CreateAlignedLoad(val, Align(1)); // unknown alignment from C ++ val = ctx.builder.CreateAlignedLoad(sig.fargt[i], val, Align(1)); // unknown alignment from C + } + else { + bool issigned = jl_signed_type && jl_subtype(jargty_proper, (jl_value_t*)jl_signed_type); +@@ -5298,7 +5304,7 @@ static Function* gen_cfun_wrapper( + else { + assert(theFptr->getFunctionType() == jl_func_sig); + } +- add_return_attr(theFptr, Attribute::NonNull); ++ addRetAttr(theFptr, Attribute::NonNull); + theFptr->addFnAttr(Thunk); + } + BasicBlock *b_generic, *b_jlcall, *b_after; +@@ -5721,7 +5727,7 @@ static Function *gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlret + Module *M, jl_codegen_params_t ¶ms) + { + Function *w = Function::Create(jl_func_sig, GlobalVariable::ExternalLinkage, funcName, M); +- add_return_attr(w, Attribute::NonNull); ++ addRetAttr(w, Attribute::NonNull); + w->addFnAttr(Thunk); + jl_init_function(w); + Function::arg_iterator AI = w->arg_begin(); +@@ -5795,7 +5801,7 @@ static Function *gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlret + if (!isboxed) { + theArg = decay_derived(ctx, emit_bitcast(ctx, theArg, PointerType::get(lty, 0))); + if (!lty->isAggregateType()) // keep "aggregate" type values in place as pointers +- theArg = ctx.builder.CreateAlignedLoad(theArg, Align(julia_alignment(ty))); ++ theArg = ctx.builder.CreateAlignedLoad(lty, theArg, Align(julia_alignment(ty))); + } + assert(dyn_cast<UndefValue>(theArg) == NULL); + args[idx] = theArg; +@@ -5905,22 +5911,22 @@ static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, String + (void)srt; // silence unused variable error + #else + Attribute sret = Attribute::getWithStructRetType(jl_LLVMContext, srt); +- attributes = attributes.addAttribute(jl_LLVMContext, argno, sret); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, sret); + #endif +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoAlias); +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoCapture); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoAlias); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoCapture); + } + if (props.cc == jl_returninfo_t::Union) { + unsigned argno = 1; +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoAlias); +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoCapture); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoAlias); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoCapture); + } + + if (props.return_roots) { + fsig.push_back(ArrayType::get(T_prjlvalue, props.return_roots)->getPointerTo(0)); + unsigned argno = fsig.size(); +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoAlias); +- attributes = attributes.addAttribute(jl_LLVMContext, argno, Attribute::NoCapture); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoAlias); ++ attributes = addAttributeAtIndex(attributes, jl_LLVMContext, argno, Attribute::NoCapture); + } + + for (size_t i = 0; i < jl_nparams(sig); i++) { +@@ -5962,7 +5968,7 @@ static jl_returninfo_t get_specsig_function(jl_codectx_t &ctx, Module *M, String + assert(f->getFunctionType() == ftype); + } + if (rt == T_prjlvalue) +- add_return_attr(f, Attribute::NonNull); ++ addRetAttr(f, Attribute::NonNull); + props.decl = f; + return props; + } +@@ -6210,7 +6216,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t> + GlobalVariable::ExternalLinkage, + declarations.specFunctionObject, M); + jl_init_function(f); +- add_return_attr(f, Attribute::NonNull); ++ addRetAttr(f, Attribute::NonNull); + f->addFnAttr(Thunk); + // TODO: (if needsparams) add attributes: dereferenceable<sizeof(void*) * length(sp)>, readonly, nocapture + // TODO: add attributes: dereferenceable<sizeof(ft)>, readonly, nocapture - e.g. maybe_mark_argument_dereferenceable(Arg, argType); +@@ -6233,8 +6239,8 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t> + } + + if (returninfo.cc == jl_returninfo_t::Union) { +- f->addAttribute(1, Attribute::getWithDereferenceableBytes(jl_LLVMContext, returninfo.union_bytes)); +- f->addAttribute(1, Attribute::getWithAlignment(jl_LLVMContext, Align(returninfo.union_align))); ++ addAttributeAtIndex(f, 1, Attribute::getWithDereferenceableBytes(jl_LLVMContext, returninfo.union_bytes)); ++ addAttributeAtIndex(f, 1, Attribute::getWithAlignment(jl_LLVMContext, Align(returninfo.union_align))); + } + + #ifdef JL_DEBUG_BUILD +@@ -6388,7 +6394,8 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t> + Value *last_age = NULL; + emit_last_age_field(ctx); + if (toplevel || ctx.is_opaque_closure) { +- last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad(ctx.world_age_field, Align(sizeof(size_t)))); ++ last_age = tbaa_decorate(tbaa_gcframe, ctx.builder.CreateAlignedLoad( ++ T_size, ctx.world_age_field, Align(sizeof(size_t)))); + } + + // step 7. allocate local variables slots +diff --git a/src/codegen_shared.h b/src/codegen_shared.h +index 883d804a20911..906443cd43fe6 100644 +--- a/src/codegen_shared.h ++++ b/src/codegen_shared.h +@@ -133,13 +133,14 @@ static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder + { + using namespace llvm; + auto T_ppjlvalue = JuliaType::get_ppjlvalue_ty(builder.getContext()); ++ auto T_pjlvalue = JuliaType::get_pjlvalue_ty(builder.getContext()); + auto T_size = builder.GetInsertBlock()->getModule()->getDataLayout().getIntPtrType(builder.getContext()); + const int ptls_offset = offsetof(jl_task_t, ptls); + llvm::Value *pptls = builder.CreateInBoundsGEP( +- JuliaType::get_pjlvalue_ty(builder.getContext()), current_task, ++ T_pjlvalue, current_task, + ConstantInt::get(T_size, ptls_offset / sizeof(void *)), + "ptls_field"); +- LoadInst *ptls_load = builder.CreateAlignedLoad( ++ LoadInst *ptls_load = builder.CreateAlignedLoad(T_pjlvalue, + emit_bitcast_with_builder(builder, pptls, T_ppjlvalue), Align(sizeof(void *)), "ptls_load"); + // Note: Corresponding store (`t->ptls = ptls`) happens in `ctx_switch` of tasks.c. + tbaa_decorate(tbaa, ptls_load); +@@ -148,3 +149,126 @@ static inline llvm::Value *get_current_ptls_from_task(llvm::IRBuilder<> &builder + builder.Insert(ptls); + return ptls; + } ++ ++// Compatibility shims for LLVM attribute APIs that were renamed in LLVM 14. ++// ++// Once we no longer support LLVM < 14, these can be mechanically removed by ++// translating foo(Bar, …) into Bar->foo(…) resp. Bar.foo(…). ++namespace { ++using namespace llvm; ++ ++inline void addFnAttr(CallInst *Target, Attribute::AttrKind Attr) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ Target->addFnAttr(Attr); ++#else ++ Target->addAttribute(AttributeList::FunctionIndex, Attr); ++#endif ++} ++ ++template<class T, class A> ++inline void addRetAttr(T *Target, A Attr) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ Target->addRetAttr(Attr); ++#else ++ Target->addAttribute(AttributeList::ReturnIndex, Attr); ++#endif ++} ++ ++inline void addAttributeAtIndex(Function *F, unsigned Index, Attribute Attr) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ F->addAttributeAtIndex(Index, Attr); ++#else ++ F->addAttribute(Index, Attr); ++#endif ++} ++ ++inline AttributeSet getFnAttrs(const AttributeList &Attrs) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return Attrs.getFnAttrs(); ++#else ++ return Attrs.getFnAttributes(); ++#endif ++} ++ ++inline AttributeSet getRetAttrs(const AttributeList &Attrs) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return Attrs.getRetAttrs(); ++#else ++ return Attrs.getRetAttributes(); ++#endif ++} ++ ++inline bool hasFnAttr(const AttributeList &L, Attribute::AttrKind Kind) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.hasFnAttr(Kind); ++#else ++ return L.hasAttribute(AttributeList::FunctionIndex, Kind); ++#endif ++} ++ ++inline AttributeList addAttributeAtIndex(const AttributeList &L, LLVMContext &C, ++ unsigned Index, Attribute::AttrKind Kind) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.addAttributeAtIndex(C, Index, Kind); ++#else ++ return L.addAttribute(C, Index, Kind); ++#endif ++} ++ ++inline AttributeList addAttributeAtIndex(const AttributeList &L, LLVMContext &C, ++ unsigned Index, Attribute Attr) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.addAttributeAtIndex(C, Index, Attr); ++#else ++ return L.addAttribute(C, Index, Attr); ++#endif ++} ++ ++inline AttributeList addAttributesAtIndex(const AttributeList &L, LLVMContext &C, ++ unsigned Index, const AttrBuilder &Builder) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.addAttributesAtIndex(C, Index, Builder); ++#else ++ return L.addAttributes(C, Index, Builder); ++#endif ++} ++ ++inline AttributeList addFnAttribute(const AttributeList &L, LLVMContext &C, ++ Attribute::AttrKind Kind) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.addFnAttribute(C, Kind); ++#else ++ return L.addAttribute(C, AttributeList::FunctionIndex, Kind); ++#endif ++} ++ ++inline AttributeList addRetAttribute(const AttributeList &L, LLVMContext &C, ++ Attribute::AttrKind Kind) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.addRetAttribute(C, Kind); ++#else ++ return L.addAttribute(C, AttributeList::ReturnIndex, Kind); ++#endif ++} ++ ++inline bool hasAttributesAtIndex(const AttributeList &L, unsigned Index) ++{ ++#if JL_LLVM_VERSION >= 140000 ++ return L.hasAttributesAtIndex(Index); ++#else ++ return L.hasAttributes(Index); ++#endif ++} ++ ++} +diff --git a/src/disasm.cpp b/src/disasm.cpp +index 25e7841bde85a..35918fb204908 100644 +--- a/src/disasm.cpp ++++ b/src/disasm.cpp +@@ -92,7 +92,11 @@ + #include <llvm/Support/MemoryBuffer.h> + #include <llvm/Support/NativeFormatting.h> + #include <llvm/Support/SourceMgr.h> ++#if JL_LLVM_VERSION >= 140000 ++#include <llvm/MC/TargetRegistry.h> ++#else + #include <llvm/Support/TargetRegistry.h> ++#endif + #include <llvm/Support/TargetSelect.h> + #include <llvm/Support/raw_ostream.h> + +@@ -912,7 +916,11 @@ static void jl_dump_asm_internal( + IP.release(), + std::move(CE), std::move(MAB), + /*ShowInst*/ false)); ++#if JL_LLVM_VERSION >= 140000 ++ Streamer->initSections(true, *STI); ++#else + Streamer->InitSections(true); ++#endif + + // Make the MemoryObject wrapper + ArrayRef<uint8_t> memoryObject(const_cast<uint8_t*>((const uint8_t*)Fptr),Fsize); +diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp +index 6fe51cc8b6b22..7ed02818c3ee4 100644 +--- a/src/intrinsics.cpp ++++ b/src/intrinsics.cpp +@@ -400,12 +400,12 @@ static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_va + (AllocType->isFloatingPointTy() || AllocType->isIntegerTy() || AllocType->isPointerTy()) && + (to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) && + DL.getTypeSizeInBits(AllocType) == DL.getTypeSizeInBits(to)) { +- Instruction *load = ctx.builder.CreateAlignedLoad(p, Align(alignment)); ++ Instruction *load = ctx.builder.CreateAlignedLoad(AllocType, p, Align(alignment)); + return emit_unboxed_coercion(ctx, to, tbaa_decorate(x.tbaa, load)); + } + } + p = maybe_bitcast(ctx, p, ptype); +- Instruction *load = ctx.builder.CreateAlignedLoad(p, Align(alignment)); ++ Instruction *load = ctx.builder.CreateAlignedLoad(to, p, Align(alignment)); + return tbaa_decorate(x.tbaa, load); + } + } +@@ -489,9 +489,11 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv) + // but if the v.typ is not well known, use llvmt + if (isboxed) + vxt = llvmt; ++ auto storage_type = vxt == T_int1 ? T_int8 : vxt; + vx = tbaa_decorate(v.tbaa, ctx.builder.CreateLoad( +- emit_bitcast(ctx, data_pointer(ctx, v), +- vxt == T_int1 ? T_pint8 : vxt->getPointerTo()))); ++ storage_type, ++ emit_bitcast(ctx, data_pointer(ctx, v), ++ storage_type->getPointerTo()))); + } + + vxt = vx->getType(); +@@ -595,7 +597,7 @@ static jl_cgval_t emit_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) + + if (ety == (jl_value_t*)jl_any_type) { + Value *thePtr = emit_unbox(ctx, T_pprjlvalue, e, e.typ); +- LoadInst *load = ctx.builder.CreateAlignedLoad(ctx.builder.CreateInBoundsGEP(T_prjlvalue, thePtr, im1), Align(align_nb)); ++ LoadInst *load = ctx.builder.CreateAlignedLoad(T_prjlvalue, ctx.builder.CreateInBoundsGEP(T_prjlvalue, thePtr, im1), Align(align_nb)); + tbaa_decorate(tbaa_data, load); + return mark_julia_type(ctx, load, true, ety); + } +@@ -726,7 +728,7 @@ static jl_cgval_t emit_atomic_pointerref(jl_codectx_t &ctx, jl_cgval_t *argv) + + if (ety == (jl_value_t*)jl_any_type) { + Value *thePtr = emit_unbox(ctx, T_pprjlvalue, e, e.typ); +- LoadInst *load = ctx.builder.CreateAlignedLoad(thePtr, Align(sizeof(jl_value_t*))); ++ LoadInst *load = ctx.builder.CreateAlignedLoad(T_prjlvalue, thePtr, Align(sizeof(jl_value_t*))); + tbaa_decorate(tbaa_data, load); + load->setOrdering(llvm_order); + return mark_julia_type(ctx, load, true, ety); +diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp +index 3412f596ef4b7..f4acad8b56cad 100644 +--- a/src/jitlayers.cpp ++++ b/src/jitlayers.cpp +@@ -16,7 +16,11 @@ + #include <llvm/Support/DynamicLibrary.h> + #include <llvm/Support/FormattedStream.h> + #include <llvm/Support/SmallVectorMemoryBuffer.h> ++#if JL_LLVM_VERSION >= 140000 ++#include <llvm/MC/TargetRegistry.h> ++#else + #include <llvm/Support/TargetRegistry.h> ++#endif + #include <llvm/Support/raw_ostream.h> + #include <llvm/Target/TargetMachine.h> + #include <llvm/Transforms/Utils/Cloning.h> +@@ -578,7 +582,7 @@ CompilerResultT JuliaOJIT::CompilerT::operator()(Module &M) + raw_string_ostream OS(Buf); + logAllUnhandledErrors(Obj.takeError(), OS, ""); + OS.flush(); +- llvm::report_fatal_error("FATAL: Unable to compile LLVM Module: '" + Buf + "'\n" ++ llvm::report_fatal_error(llvm::Twine("FATAL: Unable to compile LLVM Module: '") + Buf + "'\n" + "The module's content was printed above. Please file a bug report"); + } + +@@ -647,7 +651,7 @@ JuliaOJIT::JuliaOJIT(TargetMachine &TM, LLVMContext *LLVMCtx) + // tells DynamicLibrary to load the program, not a library. + std::string ErrorStr; + if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, &ErrorStr)) +- report_fatal_error("FATAL: unable to dlopen self\n" + ErrorStr); ++ report_fatal_error(llvm::Twine("FATAL: unable to dlopen self\n") + ErrorStr); + + GlobalJD.addGenerator( + cantFail(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( +diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp +index d67c6ba0ee28c..09b6502f59652 100644 +--- a/src/llvm-alloc-opt.cpp ++++ b/src/llvm-alloc-opt.cpp +@@ -44,7 +44,7 @@ static void removeGCPreserve(CallInst *call, Instruction *val) + { + auto replace = Constant::getNullValue(val->getType()); + call->replaceUsesOfWith(val, replace); +- for (auto &arg: call->arg_operands()) { ++ for (auto &arg: call->args()) { + if (!isa<Constant>(arg.get())) { + return; + } +@@ -416,7 +416,7 @@ ssize_t Optimizer::getGCAllocSize(Instruction *I) + return -1; + if (call->getCalledOperand() != pass.alloc_obj_func) + return -1; +- assert(call->getNumArgOperands() == 3); ++ assert(call->arg_size() == 3); + size_t sz = (size_t)cast<ConstantInt>(call->getArgOperand(1))->getZExtValue(); + if (sz < IntegerType::MAX_INT_BITS / 8 && sz < INT32_MAX) + return sz; +@@ -571,7 +571,7 @@ void Optimizer::checkInst(Instruction *I) + if (auto II = dyn_cast<IntrinsicInst>(call)) { + if (auto id = II->getIntrinsicID()) { + if (id == Intrinsic::memset) { +- assert(call->getNumArgOperands() == 4); ++ assert(call->arg_size() == 4); + if (cur.offset == UINT32_MAX || + !isa<ConstantInt>(call->getArgOperand(2)) || + !isa<ConstantInt>(call->getArgOperand(1)) || +@@ -870,7 +870,7 @@ void Optimizer::insertLifetime(Value *ptr, Constant *sz, Instruction *orig) + void Optimizer::replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID, + Instruction *orig_i, Instruction *new_i) + { +- auto nargs = call->getNumArgOperands(); ++ auto nargs = call->arg_size(); + SmallVector<Value*, 8> args(nargs); + SmallVector<Type*, 8> argTys(nargs); + for (unsigned i = 0; i < nargs; i++) { +@@ -904,8 +904,8 @@ void Optimizer::replaceIntrinsicUseWith(IntrinsicInst *call, Intrinsic::ID ID, + auto newCall = CallInst::Create(newF, args, "", call); + newCall->setTailCallKind(call->getTailCallKind()); + auto old_attrs = call->getAttributes(); +- newCall->setAttributes(AttributeList::get(pass.getLLVMContext(), old_attrs.getFnAttributes(), +- old_attrs.getRetAttributes(), {})); ++ newCall->setAttributes(AttributeList::get(pass.getLLVMContext(), getFnAttrs(old_attrs), ++ getRetAttrs(old_attrs), {})); + newCall->setDebugLoc(call->getDebugLoc()); + call->replaceAllUsesWith(newCall); + call->eraseFromParent(); +@@ -1422,7 +1422,7 @@ void Optimizer::splitOnStack(CallInst *orig_inst) + } + if (pass.gc_preserve_begin_func == callee) { + SmallVector<Value*,8> operands; +- for (auto &arg: call->arg_operands()) { ++ for (auto &arg: call->args()) { + if (arg.get() == orig_i || isa<Constant>(arg.get())) + continue; + operands.push_back(arg.get()); +diff --git a/src/llvm-final-gc-lowering.cpp b/src/llvm-final-gc-lowering.cpp +index c55095daab300..2f1ae2be32080 100644 +--- a/src/llvm-final-gc-lowering.cpp ++++ b/src/llvm-final-gc-lowering.cpp +@@ -64,7 +64,7 @@ struct FinalLowerGC: public FunctionPass, private JuliaPassContext { + + Value *FinalLowerGC::lowerNewGCFrame(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 1); ++ assert(target->arg_size() == 1); + unsigned nRoots = cast<ConstantInt>(target->getArgOperand(0))->getLimitedValue(INT_MAX); + + // Create the GC frame. +@@ -96,7 +96,7 @@ Value *FinalLowerGC::lowerNewGCFrame(CallInst *target, Function &F) + + void FinalLowerGC::lowerPushGCFrame(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 2); ++ assert(target->arg_size() == 2); + auto gcframe = target->getArgOperand(0); + unsigned nRoots = cast<ConstantInt>(target->getArgOperand(1))->getLimitedValue(INT_MAX); + +@@ -110,7 +110,7 @@ void FinalLowerGC::lowerPushGCFrame(CallInst *target, Function &F) + Align(sizeof(void*))); + inst->setMetadata(LLVMContext::MD_tbaa, tbaa_gcframe); + inst = builder.CreateAlignedStore( +- builder.CreateAlignedLoad(pgcstack, Align(sizeof(void*))), ++ builder.CreateAlignedLoad(T_ppjlvalue, pgcstack, Align(sizeof(void*))), + builder.CreatePointerCast( + builder.CreateConstInBoundsGEP1_32(T_prjlvalue, gcframe, 1), + PointerType::get(T_ppjlvalue, 0)), +@@ -124,14 +124,14 @@ void FinalLowerGC::lowerPushGCFrame(CallInst *target, Function &F) + + void FinalLowerGC::lowerPopGCFrame(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 1); ++ assert(target->arg_size() == 1); + auto gcframe = target->getArgOperand(0); + + IRBuilder<> builder(target->getContext()); + builder.SetInsertPoint(target); + Instruction *gcpop = + cast<Instruction>(builder.CreateConstInBoundsGEP1_32(T_prjlvalue, gcframe, 1)); +- Instruction *inst = builder.CreateAlignedLoad(gcpop, Align(sizeof(void*))); ++ Instruction *inst = builder.CreateAlignedLoad(T_prjlvalue, gcpop, Align(sizeof(void*))); + inst->setMetadata(LLVMContext::MD_tbaa, tbaa_gcframe); + inst = builder.CreateAlignedStore( + inst, +@@ -143,7 +143,7 @@ void FinalLowerGC::lowerPopGCFrame(CallInst *target, Function &F) + + Value *FinalLowerGC::lowerGetGCFrameSlot(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 2); ++ assert(target->arg_size() == 2); + auto gcframe = target->getArgOperand(0); + auto index = target->getArgOperand(1); + +@@ -162,14 +162,14 @@ Value *FinalLowerGC::lowerGetGCFrameSlot(CallInst *target, Function &F) + + Value *FinalLowerGC::lowerQueueGCRoot(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 1); ++ assert(target->arg_size() == 1); + target->setCalledFunction(queueRootFunc); + return target; + } + + Value *FinalLowerGC::lowerGCAllocBytes(CallInst *target, Function &F) + { +- assert(target->getNumArgOperands() == 2); ++ assert(target->arg_size() == 2); + auto sz = (size_t)cast<ConstantInt>(target->getArgOperand(1))->getZExtValue(); + // This is strongly architecture and OS dependent + int osize; +diff --git a/src/llvm-gc-invariant-verifier.cpp b/src/llvm-gc-invariant-verifier.cpp +index bfdca51603890..4302f9021ec2c 100644 +--- a/src/llvm-gc-invariant-verifier.cpp ++++ b/src/llvm-gc-invariant-verifier.cpp +@@ -168,7 +168,7 @@ void GCInvariantVerifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { + void GCInvariantVerifier::visitCallInst(CallInst &CI) { + CallingConv::ID CC = CI.getCallingConv(); + if (CC == JLCALL_F_CC || CC == JLCALL_F2_CC) { +- for (Value *Arg : CI.arg_operands()) { ++ for (Value *Arg : CI.args()) { + Type *Ty = Arg->getType(); + Check(Ty->isPointerTy() && cast<PointerType>(Ty)->getAddressSpace() == AddressSpace::Tracked, + "Invalid derived pointer in jlcall", &CI); +diff --git a/src/llvm-julia-licm.cpp b/src/llvm-julia-licm.cpp +index 91bdea4fea557..fa0e2e38b40a9 100644 +--- a/src/llvm-julia-licm.cpp ++++ b/src/llvm-julia-licm.cpp +@@ -81,7 +81,7 @@ struct JuliaLICMPass : public LoopPass, public JuliaPassContext { + // corresponding `end` can be moved to the loop exit. + if (callee == gc_preserve_begin_func) { + bool canhoist = true; +- for (Use &U : call->arg_operands()) { ++ for (Use &U : call->args()) { + // Check if all arguments are generated outside the loop + auto origin = dyn_cast<Instruction>(U.get()); + if (!origin) +diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp +index e8fdb24138de8..2842b964a45a7 100644 +--- a/src/llvm-late-gc-lowering.cpp ++++ b/src/llvm-late-gc-lowering.cpp +@@ -1521,7 +1521,7 @@ State LateLowerGCFrame::LocalScan(Function &F) { + if (callee) { + if (callee == gc_preserve_begin_func) { + std::vector<int> args; +- for (Use &U : CI->arg_operands()) { ++ for (Use &U : CI->args()) { + Value *V = U; + if (isa<Constant>(V)) + continue; +@@ -1566,7 +1566,7 @@ State LateLowerGCFrame::LocalScan(Function &F) { + continue; + } + std::vector<int> CalleeRoots; +- for (Use &U : CI->arg_operands()) { ++ for (Use &U : CI->args()) { + // Find all callee rooted arguments. + // Record them instead of simply remove them from live values here + // since they can be useful during refinement +@@ -2273,7 +2273,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + CI->replaceAllUsesWith(ASCI); + UpdatePtrNumbering(CI, ASCI, S); + } else if (alloc_obj_func && callee == alloc_obj_func) { +- assert(CI->getNumArgOperands() == 3); ++ assert(CI->arg_size() == 3); + + // Initialize an IR builder. + IRBuilder<> builder(CI); +@@ -2346,7 +2346,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + // Update the pointer numbering. + UpdatePtrNumbering(CI, newI, S); + } else if (typeof_func && callee == typeof_func) { +- assert(CI->getNumArgOperands() == 1); ++ assert(CI->arg_size() == 1); + IRBuilder<> builder(CI); + builder.SetCurrentDebugLocation(CI->getDebugLoc()); + auto tag = EmitLoadTag(builder, CI->getArgOperand(0)); +@@ -2359,7 +2359,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + } else if (write_barrier_func && callee == write_barrier_func) { + // The replacement for this requires creating new BasicBlocks + // which messes up the loop. Queue all of them to be replaced later. +- assert(CI->getNumArgOperands() >= 1); ++ assert(CI->arg_size() >= 1); + write_barriers.push_back(CI); + ChangesMade = true; + ++it; +@@ -2367,7 +2367,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + } else if (CC == JLCALL_F_CC || + CC == JLCALL_F2_CC) { + assert(T_prjlvalue); +- size_t nargs = CI->getNumArgOperands(); ++ size_t nargs = CI->arg_size(); + size_t nframeargs = nargs; + if (CC == JLCALL_F_CC) + nframeargs -= 1; +@@ -2409,12 +2409,12 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + NewCall->setTailCallKind(CI->getTailCallKind()); + auto old_attrs = CI->getAttributes(); + NewCall->setAttributes(AttributeList::get(CI->getContext(), +- old_attrs.getFnAttributes(), +- old_attrs.getRetAttributes(), {})); ++ getFnAttrs(old_attrs), ++ getRetAttrs(old_attrs), {})); + NewCall->copyMetadata(*CI); + CI->replaceAllUsesWith(NewCall); + UpdatePtrNumbering(CI, NewCall, S); +- } else if (CI->getNumArgOperands() == CI->getNumOperands()) { ++ } else if (CI->arg_size() == CI->getNumOperands()) { + /* No operand bundle to lower */ + ++it; + continue; +@@ -2447,7 +2447,7 @@ bool LateLowerGCFrame::CleanupIR(Function &F, State *S) { + auto mayTrigTerm = SplitBlockAndInsertIfThen(parOldMarked, CI, false); + builder.SetInsertPoint(mayTrigTerm); + Value *anyChldNotMarked = NULL; +- for (unsigned i = 1; i < CI->getNumArgOperands(); i++) { ++ for (unsigned i = 1; i < CI->arg_size(); i++) { + Value *child = CI->getArgOperand(i); + Value *chldBit = builder.CreateAnd(EmitLoadTag(builder, child), 1); + Value *chldNotMarked = builder.CreateICmpEQ(chldBit, ConstantInt::get(T_size, 0)); +diff --git a/src/llvm-pass-helpers.cpp b/src/llvm-pass-helpers.cpp +index f6708ef65ab77..54f1420e3ae36 100644 +--- a/src/llvm-pass-helpers.cpp ++++ b/src/llvm-pass-helpers.cpp +@@ -129,8 +129,8 @@ namespace jl_intrinsics { + // The allocation size is set to the first argument. + static Function *addGCAllocAttributes(Function *target, LLVMContext &context) + { +- target->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); +- target->addAttribute(AttributeList::ReturnIndex, Attribute::NonNull); ++ addRetAttr(target, Attribute::NoAlias); ++ addRetAttr(target, Attribute::NonNull); + target->addFnAttr(Attribute::getWithAllocSizeArgs(context, 1, None)); // returns %1 bytes + return target; + } +@@ -168,8 +168,8 @@ namespace jl_intrinsics { + FunctionType::get(PointerType::get(context.T_prjlvalue, 0), {context.T_int32}, false), + Function::ExternalLinkage, + NEW_GC_FRAME_NAME); +- intrinsic->addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); +- intrinsic->addAttribute(AttributeList::ReturnIndex, Attribute::NonNull); ++ addRetAttr(intrinsic, Attribute::NoAlias); ++ addRetAttr(intrinsic, Attribute::NonNull); + + return intrinsic; + }); +diff --git a/src/llvm-ptls.cpp b/src/llvm-ptls.cpp +index a573d41dae326..6f46af98d2ee4 100644 +--- a/src/llvm-ptls.cpp ++++ b/src/llvm-ptls.cpp +@@ -67,8 +67,8 @@ struct LowerPTLS: public ModulePass { + + void LowerPTLS::set_pgcstack_attrs(CallInst *pgcstack) const + { +- pgcstack->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone); +- pgcstack->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); ++ addFnAttr(pgcstack, Attribute::ReadNone); ++ addFnAttr(pgcstack, Attribute::NoUnwind); + } + + Instruction *LowerPTLS::emit_pgcstack_tp(Value *offset, Instruction *insertBefore) const +diff --git a/src/llvm-remove-addrspaces.cpp b/src/llvm-remove-addrspaces.cpp +index 6908783288940..9b3631e264124 100644 +--- a/src/llvm-remove-addrspaces.cpp ++++ b/src/llvm-remove-addrspaces.cpp +@@ -394,9 +394,19 @@ bool RemoveAddrspacesPass::runOnModule(Module &M) + for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) { + for (Attribute::AttrKind TypedAttr : + {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) { +- if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) { +- Attrs = Attrs.replaceAttributeType(C, i, TypedAttr, +- TypeRemapper.remapType(Ty)); ++#if JL_LLVM_VERSION >= 140000 ++ auto Attr = Attrs.getAttributeAtIndex(i, TypedAttr); ++#else ++ auto Attr = Attrs.getAttribute(i, TypedAttr); ++#endif ++ if (Type *Ty = Attr.getValueAsType()) { ++#if JL_LLVM_VERSION >= 140000 ++ Attrs = Attrs.replaceAttributeTypeAtIndex( ++ C, i, TypedAttr, TypeRemapper.remapType(Ty)); ++#else ++ Attrs = Attrs.replaceAttributeType( ++ C, i, TypedAttr, TypeRemapper.remapType(Ty)); ++#endif + break; + } + } Modified: PKGBUILD =================================================================== --- PKGBUILD 2022-06-22 16:48:24 UTC (rev 1238978) +++ PKGBUILD 2022-06-22 16:48:43 UTC (rev 1238979) @@ -9,7 +9,7 @@ pkgname=julia epoch=2 pkgver=1.7.3 -pkgrel=1 +pkgrel=2 arch=(x86_64) pkgdesc='High-level, high-performance, dynamic programming language' url='https://julialang.org/' @@ -26,6 +26,9 @@ https://github.com/JuliaLang/julia/commit/99d4e655.patch f8c918b0.patch 63303980.patch + ed9851b0.patch + 144ebbaf.patch + 074d761f.patch julia-libgit-1.2.patch julia-libgit-1.4.patch julia-system-cblas.patch @@ -43,6 +46,9 @@ 'c033fce112db85b02ebc1d3c8f8bac1240e0409ffdded7fd3322163834c41257' 'bc6c85cbbca489ef0b2876dbeb6ae493c11573e058507b8bcb9e01273bc3a38c' '96303f5cb520e861c7fdc5eb6d64767b597ecf2057a0aa37250af546738da63e' + '3f6f17c3cd876b110b21fbf251fb940d015526a62f27084623a93d9efb396aab' + '0ca0236d819f8b21dc6b7fd8a4e6741f89d9507bcc401cfc69008d6bf2d33fcb' + 'f38eee6270937843bb7cbcbdeb785bd9031189fb9d39a744206259160f5ee1ed' '40e1f46415a7241c1258d2e9d01890455ac728879a5cc6bb1d8f57d6e1f7a69a' 'cfe498a090d0026b92f9db4ed65ac3818c2efa5ec83bcefed728d27abff73081' '8f8c12853ce847f5d1b5a4a461ddec701decdb81dae7bb31d66560c1deaed97a' @@ -64,6 +70,10 @@ patch -p1 -i ../f8c918b0.patch patch -p1 -i ../63303980.patch patch -p1 -i ../99d4e655.patch +# Fixes for LLVM 14 + patch -p1 -i ../ed9851b0.patch + patch -p1 -i ../144ebbaf.patch + patch -p1 -i ../074d761f.patch # libgit2 1.2 compatibility patch -p1 -i ../julia-libgit-1.2.patch # libgit2 1.4 compatibility Added: ed9851b0.patch =================================================================== --- ed9851b0.patch (rev 0) +++ ed9851b0.patch 2022-06-22 16:48:43 UTC (rev 1238979) @@ -0,0 +1,96 @@ +From ed9851b020f8b6c05d604e2dd60dc2f53a62af0d Mon Sep 17 00:00:00 2001 +From: Valentin Churavy <[email protected]> +Date: Fri, 18 Feb 2022 14:37:31 -0500 +Subject: [PATCH] AttrBuilder now takes LLVMContext + +--- + src/ccall.cpp | 46 +++++++++++++++++++++++++++++----------------- + src/cgutils.cpp | 4 ++++ + src/codegen.cpp | 8 ++++++++ + 3 files changed, 41 insertions(+), 17 deletions(-) + +diff --git a/src/ccall.cpp b/src/ccall.cpp +index 332c057afa5c4..5f260d9178ffa 100644 +--- a/src/ccall.cpp ++++ b/src/ccall.cpp +@@ -1020,7 +1020,11 @@ std::string generate_func_sig(const char *fname) + abi->use_sret(jl_voidpointer_type, jl_LLVMContext); + } + else if (abi->use_sret((jl_datatype_t*)rt, jl_LLVMContext)) { ++#if JL_LLVM_VERSION >= 140000 ++ AttrBuilder retattrs(lrt->getContext()); ++#else + AttrBuilder retattrs = AttrBuilder(); ++#endif + #if !defined(_OS_WINDOWS_) // llvm used to use the old mingw ABI, skipping this marking works around that difference + #if JL_LLVM_VERSION < 120000 + retattrs.addAttribute(Attribute::StructRet); +@@ -1042,7 +1046,11 @@ std::string generate_func_sig(const char *fname) + } + + for (size_t i = 0; i < nccallargs; ++i) { ++#if JL_LLVM_VERSION >= 140000 ++ AttrBuilder ab(lrt->getContext()); ++#else + AttrBuilder ab; ++#endif + jl_value_t *tti = jl_svecref(at, i); + Type *t = NULL; + bool isboxed; +@@ -1120,7 +1128,11 @@ std::string generate_func_sig(const char *fname) + fargt.push_back(t); + fargt_isboxed.push_back(isboxed); + fargt_sig.push_back(pat); +- paramattrs.push_back(AttributeSet::get(jl_LLVMContext, ab)); ++#if JL_LLVM_VERSION >= 140000 ++ paramattrs.push_back(AttrBuilder(lrt->getContext(), AttributeSet::get(jl_LLVMContext, ab))); ++#else ++ paramattrs.push_back(AttributeSet::get(jl_LLVMContext, ab)); ++#endif + } + + for (size_t i = 0; i < nccallargs + sret; ++i) { +diff --git a/src/cgutils.cpp b/src/cgutils.cpp +index b219498315905..e04abe8c06e03 100644 +--- a/src/cgutils.cpp ++++ b/src/cgutils.cpp +@@ -340,7 +340,11 @@ static unsigned julia_alignment(jl_value_t *jt) + + static inline void maybe_mark_argument_dereferenceable(Argument *A, jl_value_t *jt) + { ++#if JL_LLVM_VERSION >= 140000 ++ AttrBuilder B(A->getContext()); ++#else + AttrBuilder B; ++#endif + B.addAttribute(Attribute::NonNull); + // The `dereferencable` below does not imply `nonnull` for non addrspace(0) pointers. + size_t size = dereferenceable_size(jt); +diff --git a/src/codegen.cpp b/src/codegen.cpp +index be6d8e2f66325..83946391e40c8 100644 +--- a/src/codegen.cpp ++++ b/src/codegen.cpp +@@ -1952,7 +1952,11 @@ static void jl_init_function(Function *F) + // upon entry to any function. This achieves compatibility + // with both MinGW-GCC (which assumes an 16-byte-aligned stack) and + // i686 Windows (which uses a 4-byte-aligned stack) ++#if JL_LLVM_VERSION >= 140000 ++ AttrBuilder attr(F->getContext()); ++#else + AttrBuilder attr; ++#endif + attr.addStackAlignmentAttr(16); + F->addAttributes(AttributeList::FunctionIndex, attr); + #endif +@@ -5311,7 +5315,11 @@ static Function* gen_cfun_wrapper( + } + + // Add the new nest attribute ++#if JL_LLVM_VERSION >= 140000 ++ AttrBuilder attrBuilder(M->getContext()); ++#else + AttrBuilder attrBuilder; ++#endif + attrBuilder.addAttribute(Attribute::Nest); + newAttributes.emplace_back(it, AttributeSet::get(M->getContext(), attrBuilder)); +
