From 85f3c33c30e720c7eb44a2582902ed5aa57e0272 Mon Sep 17 00:00:00 2001 From: "Sean T. Allen" Date: Wed, 27 May 2026 07:53:30 -0400 Subject: [PATCH] Update to LLVM 22.1.6 LLVM 22 deprecated LLVMGetMDKindID and dropped the size argument from the llvm.lifetime.start/end intrinsics; adapt codegen to both, and add a codegen test asserting the lifetime intrinsics are emitted with a single argument. The larger LLVM 22 build overflowed the OpenBSD Tier 3 CI VM's /home (~10.8G), so build that job on a dedicated 50G data disk, mirroring the DragonFly job. --- .github/workflows/ponyc-tier3.yml | 24 ++++++++++++-- .release-notes/update-llvm-to-22.md | 3 ++ lib/CMakeLists.txt | 2 +- lib/llvm/src | 2 +- src/libponyc/codegen/codegen.c | 6 ++-- src/libponyc/codegen/gencall.c | 18 +++-------- src/libponyc/codegen/gencall.h | 4 +-- src/libponyc/codegen/gencontrol.c | 3 +- test/libponyc/codegen.cc | 49 +++++++++++++++++++++++++++++ 9 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 .release-notes/update-llvm-to-22.md diff --git a/.github/workflows/ponyc-tier3.yml b/.github/workflows/ponyc-tier3.yml index 52a2261e50..5b190b19ca 100644 --- a/.github/workflows/ponyc-tier3.yml +++ b/.github/workflows/ponyc-tier3.yml @@ -201,7 +201,10 @@ jobs: run: | curl -L -o openbsd.qcow2 \ "https://github.com/hcartiaux/openbsd-cloud-image/releases/download/v7.8_2025-10-22-09-25/openbsd-generic.qcow2" - qemu-img resize openbsd.qcow2 60G + # Build-workspace disk. OpenBSD's default disklabel confines the + # build to /home (~10.8G), which the LLVM 22 build overflows, so + # build on a dedicated disk instead, mirroring the DragonFly job. + qemu-img create -f qcow2 openbsd-data.qcow2 50G - name: Prepare VM access run: | ssh-keygen -t ed25519 -f vm_key -N "" @@ -234,6 +237,7 @@ jobs: -smp 4 \ -m 6G \ -drive file=openbsd.qcow2,format=qcow2,if=virtio \ + -drive file=openbsd-data.qcow2,format=qcow2,if=virtio \ -drive file=seed.iso,media=cdrom \ -netdev user,id=net0,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=net0 \ @@ -247,6 +251,19 @@ jobs: done ' echo "SSH available" + - name: Set up build disk + run: | + ssh -o StrictHostKeyChecking=no -i vm_key -p 2222 openbsd@localhost <<'EOF' + set -e + # The image disk confines builds to /home (~10.8G). Build on the + # dedicated second disk (sd1) instead: one 4.2BSD partition spanning + # the disk, newfs'd and mounted at /build. + printf 'a a\n\n\n\nw\nq\n' | doas disklabel -E sd1 + doas newfs /dev/rsd1a + doas mkdir -p /build + doas mount /dev/sd1a /build + doas chown openbsd:wheel /build + EOF - name: Install build dependencies run: | ssh -o StrictHostKeyChecking=no -i vm_key -p 2222 openbsd@localhost \ @@ -258,12 +275,13 @@ jobs: - name: Copy source to VM run: | rsync -az -e "ssh -o StrictHostKeyChecking=no -i vm_key -p 2222" \ - "$GITHUB_WORKSPACE/" openbsd@localhost:/home/openbsd/ponyc/ + "$GITHUB_WORKSPACE/" openbsd@localhost:/build/ponyc/ - name: Build and test run: | ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -i vm_key -p 2222 openbsd@localhost <<'EOF' set -e - cd /home/openbsd/ponyc + cd /build/ponyc + df -h gmake libs build_flags=-j4 rm -rf build/build_libs gmake configure config=debug diff --git a/.release-notes/update-llvm-to-22.md b/.release-notes/update-llvm-to-22.md new file mode 100644 index 0000000000..a7c2f9089a --- /dev/null +++ b/.release-notes/update-llvm-to-22.md @@ -0,0 +1,3 @@ +## Update to LLVM 22.1.6 + +We've updated the LLVM version used to build Pony from 21.1.8 to 22.1.6. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 1de0b1b5b6..c8c5270a99 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -58,7 +58,7 @@ install(TARGETS blake2 find_package(Git) -set(LLVM_DESIRED_HASH "2078da43e25a4623cab2d0d60decddf709aaea28") +set(LLVM_DESIRED_HASH "fc4aad7b5db3fff421df9a9637605b9ca5667881") set(PATCHES_DESIRED_HASH "67e7ef4bf24f3d3e0f4d9e7959311d9ef0d966f61bdbfdeb9de6d599d573f89e") if(GIT_FOUND) diff --git a/lib/llvm/src b/lib/llvm/src index 2078da43e2..fc4aad7b5d 160000 --- a/lib/llvm/src +++ b/lib/llvm/src @@ -1 +1 @@ -Subproject commit 2078da43e25a4623cab2d0d60decddf709aaea28 +Subproject commit fc4aad7b5db3fff421df9a9637605b9ca5667881 diff --git a/src/libponyc/codegen/codegen.c b/src/libponyc/codegen/codegen.c index 62d50b9d25..e3687b6738 100644 --- a/src/libponyc/codegen/codegen.c +++ b/src/libponyc/codegen/codegen.c @@ -1080,7 +1080,7 @@ void codegen_local_lifetime_start(compile_t* c, const char* name) if(p != NULL && !p->alive) { - gencall_lifetime_start(c, p->alloca, LLVMGetAllocatedType(p->alloca)); + gencall_lifetime_start(c, p->alloca); p->alive = true; return; } @@ -1106,7 +1106,7 @@ void codegen_local_lifetime_end(compile_t* c, const char* name) if(p != NULL && p->alive) { - gencall_lifetime_end(c, p->alloca, LLVMGetAllocatedType(p->alloca)); + gencall_lifetime_end(c, p->alloca); p->alive = false; return; } @@ -1129,7 +1129,7 @@ void codegen_scope_lifetime_end(compile_t* c) while ((p = compile_locals_next(&frame->locals, &i)) != NULL) { if(p->alive) - gencall_lifetime_end(c, p->alloca, LLVMGetAllocatedType(p->alloca)); + gencall_lifetime_end(c, p->alloca); } c->frame->early_termination = true; } diff --git a/src/libponyc/codegen/gencall.c b/src/libponyc/codegen/gencall.c index 90ceecac25..1fb3d78f2e 100644 --- a/src/libponyc/codegen/gencall.c +++ b/src/libponyc/codegen/gencall.c @@ -1463,26 +1463,16 @@ void gencall_memmove(compile_t* c, LLVMValueRef dst, LLVMValueRef src, LLVMBuildCall2(c->builder, func_type, func, args, 4, ""); } -void gencall_lifetime_start(compile_t* c, LLVMValueRef ptr, LLVMTypeRef type) +void gencall_lifetime_start(compile_t* c, LLVMValueRef ptr) { LLVMValueRef func = LLVMLifetimeStart(c->module, c->ptr); LLVMTypeRef func_type = LLVMGlobalGetValueType(func); - size_t size = (size_t)LLVMABISizeOfType(c->target_data, type); - - LLVMValueRef args[2]; - args[0] = LLVMConstInt(c->i64, size, false); - args[1] = ptr; - LLVMBuildCall2(c->builder, func_type, func, args, 2, ""); + LLVMBuildCall2(c->builder, func_type, func, &ptr, 1, ""); } -void gencall_lifetime_end(compile_t* c, LLVMValueRef ptr, LLVMTypeRef type) +void gencall_lifetime_end(compile_t* c, LLVMValueRef ptr) { LLVMValueRef func = LLVMLifetimeEnd(c->module, c->ptr); LLVMTypeRef func_type = LLVMGlobalGetValueType(func); - size_t size = (size_t)LLVMABISizeOfType(c->target_data, type); - - LLVMValueRef args[2]; - args[0] = LLVMConstInt(c->i64, size, false); - args[1] = ptr; - LLVMBuildCall2(c->builder, func_type, func, args, 2, ""); + LLVMBuildCall2(c->builder, func_type, func, &ptr, 1, ""); } diff --git a/src/libponyc/codegen/gencall.h b/src/libponyc/codegen/gencall.h index 7db5d77075..c4a8f7b8d5 100644 --- a/src/libponyc/codegen/gencall.h +++ b/src/libponyc/codegen/gencall.h @@ -35,9 +35,9 @@ void gencall_memcpy(compile_t* c, LLVMValueRef dst, LLVMValueRef src, void gencall_memmove(compile_t* c, LLVMValueRef dst, LLVMValueRef src, LLVMValueRef n); -void gencall_lifetime_start(compile_t* c, LLVMValueRef ptr, LLVMTypeRef type); +void gencall_lifetime_start(compile_t* c, LLVMValueRef ptr); -void gencall_lifetime_end(compile_t* c, LLVMValueRef ptr, LLVMTypeRef type); +void gencall_lifetime_end(compile_t* c, LLVMValueRef ptr); PONY_EXTERN_C_END diff --git a/src/libponyc/codegen/gencontrol.c b/src/libponyc/codegen/gencontrol.c index 2d7e7b12c5..6580da8de1 100644 --- a/src/libponyc/codegen/gencontrol.c +++ b/src/libponyc/codegen/gencontrol.c @@ -963,7 +963,8 @@ void attach_branchweights_metadata(LLVMContextRef ctx, LLVMValueRef branch, LLVMValueRef metadata = LLVMMDNodeInContext(ctx, params, count + 1); const char id[] = "prof"; - LLVMSetMetadata(branch, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); + LLVMSetMetadata(branch, + LLVMGetMDKindIDInContext(ctx, id, sizeof(id) - 1), metadata); ponyint_pool_free(alloc_index, params); } diff --git a/test/libponyc/codegen.cc b/test/libponyc/codegen.cc index 53f729454c..dfed1734bc 100644 --- a/test/libponyc/codegen.cc +++ b/test/libponyc/codegen.cc @@ -9,6 +9,8 @@ #include "llvm_config_begin.h" #include +#include +#include #include #include "llvm_config_end.h" @@ -367,3 +369,50 @@ TEST_F(CodegenTest, RepeatLoopBreakOnlyInBranches) TEST_COMPILE(src); } + + +TEST_F(CodegenTest, LifetimeIntrinsicsHaveSinglePointerArgument) +{ + // LLVM 22 dropped the leading size argument from llvm.lifetime.start and + // llvm.lifetime.end; they now take a single pointer. A two-argument call + // is rejected by the module verifier, so confirm codegen emits exactly one + // argument. The union plus match capture below forces scoped locals, which + // is what makes codegen emit lifetime markers. + const char* src = + "actor Main\n" + " new create(env: Env) =>\n" + " let x: (U64 | None) = U64(1)\n" + " match x\n" + " | let n: U64 => None\n" + " end"; + + TEST_COMPILE(src); + + auto module = llvm::unwrap(compile->module); + + size_t lifetime_calls = 0; + for(auto& function : *module) + { + for(auto& block : function) + { + for(auto& inst : block) + { + auto intrinsic = llvm::dyn_cast(&inst); + if(intrinsic == nullptr) + continue; + + auto id = intrinsic->getIntrinsicID(); + if((id == llvm::Intrinsic::lifetime_start) || + (id == llvm::Intrinsic::lifetime_end)) + { + lifetime_calls++; + ASSERT_EQ(intrinsic->arg_size(), 1u); + } + } + } + } + + // Guard against a vacuous pass: the program above must actually emit + // lifetime markers, or the per-call assertion never runs. + ASSERT_GT(lifetime_calls, 0u); +}