From 12051e75440f65bc4cabf88ca2178085c38c4f87 Mon Sep 17 00:00:00 2001 From: Christian Buttner Date: Thu, 4 Jul 2024 00:44:32 +0200 Subject: [PATCH] Fix `$$unaligned_store` arg check and add test. (#1224) Fix `$$unaligned_store` arg check and add test. --- lib/std/core/mem.c3 | 16 +++++--- src/compiler/sema_builtins.c | 3 +- .../builtins/unaligned_load_store.c3t | 40 +++++++++++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 test/test_suite/builtins/unaligned_load_store.c3t diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index c604c8125..11ebb887f 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -162,9 +162,9 @@ macro @scatter_aligned(ptrvec, value, bool[<*>] mask, usz $alignment) } /** - * @param [in] x "the variable or dereferenced pointer to load." - * @param $alignment "the alignment to assume for the load" - * @return "returns the value of x" + * @param [in] x "The variable or dereferenced pointer to load." + * @param $alignment "The alignment to assume for the load" + * @return "The value of x" * * @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" **/ @@ -174,13 +174,17 @@ macro @unaligned_load(&x, usz $alignment) @builtin } /** - * @require $assignable(y, $typeof(*x)) : "The value doesn't match the variable" + * @param [out] x "The variable or dereferenced pointer to store to." + * @param value "The value to store." + * @param $alignment "The alignment to assume for the store" + * @return "The value of x" * + * @require $assignable(value, $typeof(*x)) : "The value doesn't match the variable" * @require @constant_is_power_of_2($alignment) : "The alignment must be a power of two" **/ -macro @unaligned_store(&x, y, usz $alignment) @builtin +macro @unaligned_store(&x, value, usz $alignment) @builtin { - return $$unaligned_store(x, ($typeof(*x))y, $alignment); + return $$unaligned_store(x, ($typeof(*x))value, $alignment); } macro @volatile_load(&x) @builtin diff --git a/src/compiler/sema_builtins.c b/src/compiler/sema_builtins.c index 93a9d162b..e5395306e 100644 --- a/src/compiler/sema_builtins.c +++ b/src/compiler/sema_builtins.c @@ -838,7 +838,8 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr) case BUILTIN_UNALIGNED_STORE: { assert(arg_count == 3); - if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_POINTER, BA_INTEGER }, 2)) return false; + if (!sema_check_builtin_args(context, args, (BuiltinArg[]) {BA_POINTER}, 1)) return false; + if (!sema_check_builtin_args(context, &args[2], (BuiltinArg[]) {BA_INTEGER}, 1)) return false; Type *original = type_flatten(args[0]->type); if (!sema_check_alignment_expression(context, args[2])) return false; if (original != type_voidptr) diff --git a/test/test_suite/builtins/unaligned_load_store.c3t b/test/test_suite/builtins/unaligned_load_store.c3t new file mode 100644 index 000000000..58b3d10c4 --- /dev/null +++ b/test/test_suite/builtins/unaligned_load_store.c3t @@ -0,0 +1,40 @@ +module test; + +struct Foo +{ + float[4] a; +} + +fn void main() +{ + Foo* foo; + float[<4>] a @align(1) @noinit; + + a = *(float[<4>]*)&foo.a; + *(float[<4>]*)&foo.a = a; + + a = $$unaligned_load((float[<4>]*)&foo.a, 1); + $$unaligned_store((float[<4>]*)&foo.a, a, 1); +} + +/* #expect: test.ll + +define void @test.main() #0 { +entry: + %foo = alloca ptr, align 8 + %a = alloca <4 x float>, align 1 + store ptr null, ptr %foo, align 8 + %0 = load ptr, ptr %foo, align 8 + %1 = load <4 x float>, ptr %0, align 16 + store <4 x float> %1, ptr %a, align 1 + %2 = load ptr, ptr %foo, align 8 + %3 = load <4 x float>, ptr %a, align 1 + store <4 x float> %3, ptr %2, align 16 + %4 = load ptr, ptr %foo, align 8 + %5 = load <4 x float>, ptr %4, align 1 + store <4 x float> %5, ptr %a, align 1 + %6 = load ptr, ptr %foo, align 8 + %7 = load <4 x float>, ptr %a, align 1 + store <4 x float> %7, ptr %6, align 1 + ret void +}