From 3caaf0a3e81758535b289b95099032d60d5da46a Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 9 Sep 2025 00:07:45 +0200 Subject: [PATCH] Compiler hang with unaligned load-store pair. #2470 --- releasenotes.md | 1 + src/compiler/llvm_codegen_builtins.c | 5 ++-- .../builtins/unaligned_load_store.c3t | 1 + .../builtins/unaligned_load_store_chain.c3t | 23 +++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 test/test_suite/builtins/unaligned_load_store_chain.c3t diff --git a/releasenotes.md b/releasenotes.md index 2c331618d..16687dfb6 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -18,6 +18,7 @@ - Overloading &[] should be enough for foreach. #2466 - Any register allowed in X86_64 inline asm address. #2463 - int val = some_int + some_distinct_inline_int errors that int cannot be cast to DistinctInt #2468 +- Compiler hang with unaligned load-store pair. #2470 ### Stdlib changes - Added generic `InterfaceList` to store a list of values that implement a specific interface diff --git a/src/compiler/llvm_codegen_builtins.c b/src/compiler/llvm_codegen_builtins.c index 99184bba4..4c8d2a92f 100644 --- a/src/compiler/llvm_codegen_builtins.c +++ b/src/compiler/llvm_codegen_builtins.c @@ -169,10 +169,9 @@ INLINE void llvm_emit_unaligned_store(GenContext *c, BEValue *result_value, Expr c->emitting_load_store_check = true; BEValue value; llvm_emit_expr(c, &value, expr->call_expr.arguments[0]); + llvm_value_rvalue(c, &value); llvm_emit_expr(c, result_value, expr->call_expr.arguments[1]); - llvm_value_deref(c, &value); - value.alignment = expr->call_expr.arguments[2]->const_expr.ixx.i.low; - llvm_store(c, &value, result_value); + llvm_store_to_ptr_aligned(c, value.value, result_value, expr->call_expr.arguments[2]->const_expr.ixx.i.low); c->emitting_load_store_check = emit_check; } diff --git a/test/test_suite/builtins/unaligned_load_store.c3t b/test/test_suite/builtins/unaligned_load_store.c3t index c4aa12992..bcd1144f5 100644 --- a/test/test_suite/builtins/unaligned_load_store.c3t +++ b/test/test_suite/builtins/unaligned_load_store.c3t @@ -1,3 +1,4 @@ +// #target: macos-x64 module test; struct Foo diff --git a/test/test_suite/builtins/unaligned_load_store_chain.c3t b/test/test_suite/builtins/unaligned_load_store_chain.c3t new file mode 100644 index 000000000..2a03bf43e --- /dev/null +++ b/test/test_suite/builtins/unaligned_load_store_chain.c3t @@ -0,0 +1,23 @@ +// #target: macos-x64 +module test; +module test; +import std, libc; + +fn void unaligned_load_store(void* dst, void* src) @nostrip +{ + $$unaligned_store(dst, $$unaligned_load((char*)src, 2), 2); +} + +fn int main() +{ + return 0; +} + +/* #expect: test.ll + +define void @test.unaligned_load_store(ptr %0, ptr %1) #0 { +entry: + %2 = load i8, ptr %1, align 2 + store i8 %2, ptr %0, align 2 + ret void +}