From 9dce77bc47cf9abc17313b49a36a7ac88bc77a23 Mon Sep 17 00:00:00 2001 From: stevenfontanella Date: Thu, 29 Jan 2026 18:17:50 +0000 Subject: [PATCH 1/6] Add tests for alignment hint less than natural alignment --- test/core/threads/atomic.wast | 137 ++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 6 deletions(-) diff --git a/test/core/threads/atomic.wast b/test/core/threads/atomic.wast index 3ddbdc6a..ceea831a 100644 --- a/test/core/threads/atomic.wast +++ b/test/core/threads/atomic.wast @@ -70,12 +70,12 @@ (func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u (local.get $addr) (local.get $value))) (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i32.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i32.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value))) ) @@ -437,6 +437,131 @@ (assert_trap (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic") (assert_trap (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic") +;; Alignment hint is lower than the natural alignment. Execution will trap even if the address being read is aligned. + +(module + (memory 1 1 shared) + + (func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load align=1 (local.get $addr))) + (func (export "i64.atomic.load") (param $addr i32) (result i64) (i64.atomic.load align=1 (local.get $addr))) + (func (export "i32.atomic.load8_u") (param $addr i32) (result i32) (i32.atomic.load8_u align=1 (local.get $addr))) + (func (export "i32.atomic.load16_u") (param $addr i32) (result i32) (i32.atomic.load16_u align=1 (local.get $addr))) + (func (export "i64.atomic.load8_u") (param $addr i32) (result i64) (i64.atomic.load8_u align=1 (local.get $addr))) + (func (export "i64.atomic.load16_u") (param $addr i32) (result i64) (i64.atomic.load16_u align=1 (local.get $addr))) + (func (export "i64.atomic.load32_u") (param $addr i32) (result i64) (i64.atomic.load32_u align=1 (local.get $addr))) + + (func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.store") (param $addr i32) (param $value i64) (i64.atomic.store align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.store8") (param $addr i32) (param $value i32) (i32.atomic.store8 align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.store16") (param $addr i32) (param $value i32) (i32.atomic.store16 align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.store8") (param $addr i32) (param $value i64) (i64.atomic.store8 align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.store16") (param $addr i32) (param $value i64) (i64.atomic.store16 align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.store32") (param $addr i32) (param $value i64) (i64.atomic.store32 align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.add") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.add_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.add_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.add_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.sub") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.sub") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.sub_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.sub_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.sub_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.and") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.and") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.and_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.and_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.and_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.or") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.or") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.or_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.or_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.or_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.xor") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.xor") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xor_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xor_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xor_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.xchg") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw.xchg") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw8.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xchg_u align=1 (local.get $addr) (local.get $value))) + (func (export "i32.atomic.rmw16.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw8.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xchg_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw16.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) + (func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u align=1 (local.get $addr) (local.get $value))) + + (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i32.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw8.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw8.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) +) + +(assert_trap (invoke "i32.atomic.load" (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.load" (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.load16_u" (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.load16_u" (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.load32_u" (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.store" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.store" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.store16" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.store16" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.store32" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.add" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.add" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.add_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.add_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.add_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.sub" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.sub" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.sub_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.sub_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.sub_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.and" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.and" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.and_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.and_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.and_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.or" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.or" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.or_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.or_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.or_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.xor" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.xor" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.xor_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.xor_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.xor_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.xchg" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.xchg" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.xchg_u" (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.xchg_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.xchg_u" (i32.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw.cmpxchg" (i32.const 0) (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw.cmpxchg" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i32.atomic.rmw16.cmpxchg_u" (i32.const 0) (i32.const 0) (i32.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") +(assert_trap (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") + + ;; wait/notify (module (memory 1 1 shared) From 36eb53ad939379e39c52cb63689d16786cb35cc0 Mon Sep 17 00:00:00 2001 From: stevenfontanella Date: Tue, 3 Feb 2026 00:26:30 +0000 Subject: [PATCH 2/6] Make non-natural alignment on atomic memroy operations a validation error --- interpreter/valid/valid.ml | 30 +- test/core/threads/atomic.wast | 525 ++++++++++++++++++++++++++-------- 2 files changed, 420 insertions(+), 135 deletions(-) diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 259d3cd7..15dd28e5 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -189,7 +189,7 @@ let check_vec_binop binop at = error at "invalid lane index" | _ -> () -let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at = +let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at ~(isAtomic : bool) = let _mt = memory c (0l @@ at) in let size = match get_sz memop.pack with @@ -199,7 +199,9 @@ let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at = packed_size sz in require (1 lsl memop.align <= size) at - "alignment must not be larger than natural" + "alignment must not be larger than natural"; + if isAtomic then + require (1 lsl memop.align == size) at "atomic memory instruction's alignment must equal the instruction's natural alignment" (* @@ -354,29 +356,29 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type [] --> [] | Load memop -> - check_memop c memop num_size (Lib.Option.map fst) e.at; + check_memop ~isAtomic:false c memop num_size (Lib.Option.map fst) e.at; [NumType I32Type] --> [NumType memop.ty] | Store memop -> - check_memop c memop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:false c memop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType memop.ty] --> [] | VecLoad memop -> - check_memop c memop vec_size (Lib.Option.map fst) e.at; + check_memop ~isAtomic:false c memop vec_size (Lib.Option.map fst) e.at; [NumType I32Type] --> [VecType memop.ty] | VecStore memop -> - check_memop c memop vec_size (fun _ -> None) e.at; + check_memop ~isAtomic:false c memop vec_size (fun _ -> None) e.at; [NumType I32Type; VecType memop.ty] --> [] | VecLoadLane (memop, i) -> - check_memop c memop vec_size (fun sz -> Some sz) e.at; + check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at; require (i < vec_size memop.ty / packed_size memop.pack) e.at "invalid lane index"; [NumType I32Type; VecType memop.ty] --> [VecType memop.ty] | VecStoreLane (memop, i) -> - check_memop c memop vec_size (fun sz -> Some sz) e.at; + check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at; require (i < vec_size memop.ty / packed_size memop.pack) e.at "invalid lane index"; [NumType I32Type; VecType memop.ty] --> [] @@ -514,23 +516,23 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type "invalid lane index"; [t; NumType t2] --> [t] | MemoryAtomicWait atomicop -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty; NumType I64Type] --> [NumType I32Type] | MemoryAtomicNotify atomicop -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType I32Type] --> [NumType I32Type] | AtomicFence -> [] --> [] | AtomicLoad atomicop -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type] --> [NumType atomicop.ty] | AtomicStore atomicop -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty] --> [] | AtomicRmw (rmwop, atomicop) -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty] --> [NumType atomicop.ty] | AtomicRmwCmpXchg atomicop -> - check_memop c atomicop num_size (fun sz -> sz) e.at; + check_memop ~isAtomic: true c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty; NumType atomicop.ty] --> [NumType atomicop.ty] and check_seq (c : context) (s : infer_result_type) (es : instr list) diff --git a/test/core/threads/atomic.wast b/test/core/threads/atomic.wast index ceea831a..8a0f61e9 100644 --- a/test/core/threads/atomic.wast +++ b/test/core/threads/atomic.wast @@ -437,129 +437,412 @@ (assert_trap (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic") (assert_trap (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic") -;; Alignment hint is lower than the natural alignment. Execution will trap even if the address being read is aligned. +;; non-natural alignment -(module - (memory 1 1 shared) +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load align=1 (local.get $addr))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.load") (param $addr i32) (result i64) (i64.atomic.load align=1 (local.get $addr))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.load16_u") (param $addr i32) (result i32) (i32.atomic.load16_u align=1 (local.get $addr))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.load16_u") (param $addr i32) (result i64) (i64.atomic.load16_u align=1 (local.get $addr))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.load32_u") (param $addr i32) (result i64) (i64.atomic.load32_u align=1 (local.get $addr))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.store") (param $addr i32) (param $value i64) (i64.atomic.store align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.store16") (param $addr i32) (param $value i32) (i32.atomic.store16 align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.store16") (param $addr i32) (param $value i64) (i64.atomic.store16 align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.store32") (param $addr i32) (param $value i64) (i64.atomic.store32 align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.add") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.add_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.sub") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.sub") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.sub_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.and") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.and") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) - (func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load align=1 (local.get $addr))) - (func (export "i64.atomic.load") (param $addr i32) (result i64) (i64.atomic.load align=1 (local.get $addr))) - (func (export "i32.atomic.load8_u") (param $addr i32) (result i32) (i32.atomic.load8_u align=1 (local.get $addr))) - (func (export "i32.atomic.load16_u") (param $addr i32) (result i32) (i32.atomic.load16_u align=1 (local.get $addr))) - (func (export "i64.atomic.load8_u") (param $addr i32) (result i64) (i64.atomic.load8_u align=1 (local.get $addr))) - (func (export "i64.atomic.load16_u") (param $addr i32) (result i64) (i64.atomic.load16_u align=1 (local.get $addr))) - (func (export "i64.atomic.load32_u") (param $addr i32) (result i64) (i64.atomic.load32_u align=1 (local.get $addr))) - - (func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.store") (param $addr i32) (param $value i64) (i64.atomic.store align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.store8") (param $addr i32) (param $value i32) (i32.atomic.store8 align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.store16") (param $addr i32) (param $value i32) (i32.atomic.store16 align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.store8") (param $addr i32) (param $value i64) (i64.atomic.store8 align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.store16") (param $addr i32) (param $value i64) (i64.atomic.store16 align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.store32") (param $addr i32) (param $value i64) (i64.atomic.store32 align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.add") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.add_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.add_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.add_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.sub") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.sub") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.sub_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.sub_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.sub_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.and") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.and") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.and_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.and_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.and_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.or") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.or") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.or_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.or_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.or_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.xor") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.xor") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xor_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xor_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xor_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.xchg") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw.xchg") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw8.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xchg_u align=1 (local.get $addr) (local.get $value))) - (func (export "i32.atomic.rmw16.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw8.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xchg_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw16.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) - (func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u align=1 (local.get $addr) (local.get $value))) - - (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i32.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw8.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw8.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) - (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) -) - -(assert_trap (invoke "i32.atomic.load" (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.load" (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.load16_u" (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.load16_u" (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.load32_u" (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.store" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.store" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.store16" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.store16" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.store32" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.add" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.add" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.add_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.add_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.add_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.sub" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.sub" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.sub_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.sub_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.sub_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.and" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.and" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.and_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.and_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.and_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.or" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.or" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.or_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.or_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.or_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.xor" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.xor" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.xor_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.xor_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.xor_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.xchg" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.xchg" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.xchg_u" (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.xchg_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.xchg_u" (i32.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw.cmpxchg" (i32.const 0) (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw.cmpxchg" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i32.atomic.rmw16.cmpxchg_u" (i32.const 0) (i32.const 0) (i32.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") -(assert_trap (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0)) "unaligned atomic") + (func (export "i32.atomic.rmw16.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.and_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.or") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.or") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.or_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.xor") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.xor") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xor_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.xchg") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.xchg") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u align=1 (local.get $addr) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) + +(assert_invalid + (module + (memory 1 1 shared) + + (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) + ) + "atomic memory instruction's alignment must equal the instruction's natural alignment" +) ;; wait/notify From 88fc19941fdace5443c64af419e0c8892d3df453 Mon Sep 17 00:00:00 2001 From: stevenfontanella Date: Wed, 4 Feb 2026 21:22:42 +0000 Subject: [PATCH 3/6] PR updates --- interpreter/valid/valid.ml | 39 ++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 15dd28e5..a685a475 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -189,7 +189,9 @@ let check_vec_binop binop at = error at "invalid lane index" | _ -> () -let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at ~(isAtomic : bool) = +type mem_mode = NonAtomic | Atomic + +let check_memop (mode : mem_mode) (c : context) (memop : ('t, 's) memop) ty_size get_sz at = let _mt = memory c (0l @@ at) in let size = match get_sz memop.pack with @@ -197,11 +199,12 @@ let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at ~(isAto | Some sz -> check_pack sz (ty_size memop.ty) at; packed_size sz - in - require (1 lsl memop.align <= size) at - "alignment must not be larger than natural"; - if isAtomic then - require (1 lsl memop.align == size) at "atomic memory instruction's alignment must equal the instruction's natural alignment" + in match mode with + | NonAtomic -> + require (1 lsl memop.align <= size) at + "alignment must not be larger than natural"; + | Atomic -> + require (1 lsl memop.align == size) at "atomic memory instruction's alignment must equal the instruction's natural alignment" (* @@ -356,29 +359,29 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type [] --> [] | Load memop -> - check_memop ~isAtomic:false c memop num_size (Lib.Option.map fst) e.at; + check_memop NonAtomic c memop num_size (Lib.Option.map fst) e.at; [NumType I32Type] --> [NumType memop.ty] | Store memop -> - check_memop ~isAtomic:false c memop num_size (fun sz -> sz) e.at; + check_memop NonAtomic c memop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType memop.ty] --> [] | VecLoad memop -> - check_memop ~isAtomic:false c memop vec_size (Lib.Option.map fst) e.at; + check_memop NonAtomic c memop vec_size (Lib.Option.map fst) e.at; [NumType I32Type] --> [VecType memop.ty] | VecStore memop -> - check_memop ~isAtomic:false c memop vec_size (fun _ -> None) e.at; + check_memop NonAtomic c memop vec_size (fun _ -> None) e.at; [NumType I32Type; VecType memop.ty] --> [] | VecLoadLane (memop, i) -> - check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at; + check_memop NonAtomic c memop vec_size (fun sz -> Some sz) e.at; require (i < vec_size memop.ty / packed_size memop.pack) e.at "invalid lane index"; [NumType I32Type; VecType memop.ty] --> [VecType memop.ty] | VecStoreLane (memop, i) -> - check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at; + check_memop NonAtomic c memop vec_size (fun sz -> Some sz) e.at; require (i < vec_size memop.ty / packed_size memop.pack) e.at "invalid lane index"; [NumType I32Type; VecType memop.ty] --> [] @@ -516,23 +519,23 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type "invalid lane index"; [t; NumType t2] --> [t] | MemoryAtomicWait atomicop -> - check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty; NumType I64Type] --> [NumType I32Type] | MemoryAtomicNotify atomicop -> - check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType I32Type] --> [NumType I32Type] | AtomicFence -> [] --> [] | AtomicLoad atomicop -> - check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type] --> [NumType atomicop.ty] | AtomicStore atomicop -> - check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty] --> [] | AtomicRmw (rmwop, atomicop) -> - check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty] --> [NumType atomicop.ty] | AtomicRmwCmpXchg atomicop -> - check_memop ~isAtomic: true c atomicop num_size (fun sz -> sz) e.at; + check_memop Atomic c atomicop num_size (fun sz -> sz) e.at; [NumType I32Type; NumType atomicop.ty; NumType atomicop.ty] --> [NumType atomicop.ty] and check_seq (c : context) (s : infer_result_type) (es : instr list) From ba213446a40d517edeb33df219437fb9f4c52ef3 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 6 Feb 2026 12:33:30 +0100 Subject: [PATCH 4/6] Update interpreter/valid/valid.ml --- interpreter/valid/valid.ml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index a685a475..4385daff 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -199,12 +199,14 @@ let check_memop (mode : mem_mode) (c : context) (memop : ('t, 's) memop) ty_size | Some sz -> check_pack sz (ty_size memop.ty) at; packed_size sz - in match mode with - | NonAtomic -> - require (1 lsl memop.align <= size) at - "alignment must not be larger than natural"; - | Atomic -> - require (1 lsl memop.align == size) at "atomic memory instruction's alignment must equal the instruction's natural alignment" + in + match mode with + | NonAtomic -> + require (1 lsl memop.align <= size) at + "alignment must not be larger than natural"; + | Atomic -> + require (1 lsl memop.align = size) at + "atomic alignment must be natural" (* From 052c6c1707c707d3bcfbf7dd6d86b85101410da4 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Fri, 6 Feb 2026 12:37:46 +0100 Subject: [PATCH 5/6] Update atomic.wast --- test/core/threads/atomic.wast | 90 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/test/core/threads/atomic.wast b/test/core/threads/atomic.wast index 8a0f61e9..7c340f98 100644 --- a/test/core/threads/atomic.wast +++ b/test/core/threads/atomic.wast @@ -445,7 +445,7 @@ (func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load align=1 (local.get $addr))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -454,7 +454,7 @@ (func (export "i64.atomic.load") (param $addr i32) (result i64) (i64.atomic.load align=1 (local.get $addr))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -463,7 +463,7 @@ (func (export "i32.atomic.load16_u") (param $addr i32) (result i32) (i32.atomic.load16_u align=1 (local.get $addr))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -472,7 +472,7 @@ (func (export "i64.atomic.load16_u") (param $addr i32) (result i64) (i64.atomic.load16_u align=1 (local.get $addr))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -481,7 +481,7 @@ (func (export "i64.atomic.load32_u") (param $addr i32) (result i64) (i64.atomic.load32_u align=1 (local.get $addr))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -490,7 +490,7 @@ (func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -499,7 +499,7 @@ (func (export "i64.atomic.store") (param $addr i32) (param $value i64) (i64.atomic.store align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -508,7 +508,7 @@ (func (export "i32.atomic.store16") (param $addr i32) (param $value i32) (i32.atomic.store16 align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -517,7 +517,7 @@ (func (export "i64.atomic.store16") (param $addr i32) (param $value i64) (i64.atomic.store16 align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -526,7 +526,7 @@ (func (export "i64.atomic.store32") (param $addr i32) (param $value i64) (i64.atomic.store32 align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -535,7 +535,7 @@ (func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -544,7 +544,7 @@ (func (export "i64.atomic.rmw.add") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.add align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -553,7 +553,7 @@ (func (export "i32.atomic.rmw16.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -562,7 +562,7 @@ (func (export "i64.atomic.rmw16.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.add_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -571,7 +571,7 @@ (func (export "i64.atomic.rmw32.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.add_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -580,7 +580,7 @@ (func (export "i32.atomic.rmw.sub") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -589,7 +589,7 @@ (func (export "i64.atomic.rmw.sub") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.sub align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -598,7 +598,7 @@ (func (export "i32.atomic.rmw16.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -607,7 +607,7 @@ (func (export "i64.atomic.rmw16.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.sub_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -616,7 +616,7 @@ (func (export "i64.atomic.rmw32.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.sub_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -625,7 +625,7 @@ (func (export "i32.atomic.rmw.and") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -634,7 +634,7 @@ (func (export "i64.atomic.rmw.and") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.and align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -643,7 +643,7 @@ (func (export "i32.atomic.rmw16.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -652,7 +652,7 @@ (func (export "i64.atomic.rmw16.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.and_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -661,7 +661,7 @@ (func (export "i64.atomic.rmw32.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.and_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -670,7 +670,7 @@ (func (export "i32.atomic.rmw.or") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -679,7 +679,7 @@ (func (export "i64.atomic.rmw.or") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.or align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -688,7 +688,7 @@ (func (export "i32.atomic.rmw16.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -697,7 +697,7 @@ (func (export "i64.atomic.rmw16.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.or_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -706,7 +706,7 @@ (func (export "i64.atomic.rmw32.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.or_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -715,7 +715,7 @@ (func (export "i32.atomic.rmw.xor") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -724,7 +724,7 @@ (func (export "i64.atomic.rmw.xor") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xor align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -733,7 +733,7 @@ (func (export "i32.atomic.rmw16.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -742,7 +742,7 @@ (func (export "i64.atomic.rmw16.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xor_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -751,7 +751,7 @@ (func (export "i64.atomic.rmw32.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xor_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -760,7 +760,7 @@ (func (export "i32.atomic.rmw.xchg") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -769,7 +769,7 @@ (func (export "i64.atomic.rmw.xchg") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xchg align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -778,7 +778,7 @@ (func (export "i32.atomic.rmw16.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -787,7 +787,7 @@ (func (export "i64.atomic.rmw16.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xchg_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -796,7 +796,7 @@ (func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u align=1 (local.get $addr) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -805,7 +805,7 @@ (func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -814,7 +814,7 @@ (func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg align=1 (local.get $addr) (local.get $expected) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -823,7 +823,7 @@ (func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -832,7 +832,7 @@ (func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) (assert_invalid @@ -841,7 +841,7 @@ (func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u align=1 (local.get $addr) (local.get $expected) (local.get $value))) ) - "atomic memory instruction's alignment must equal the instruction's natural alignment" + "atomic alignment must be natural" ) From 90a44b9f47267bcf45abcffe0301dd6a39036283 Mon Sep 17 00:00:00 2001 From: stevenfontanella Date: Fri, 6 Feb 2026 17:25:27 +0000 Subject: [PATCH 6/6] Try setup-ocaml@v3 --- .github/workflows/ci-interpreter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-interpreter.yml b/.github/workflows/ci-interpreter.yml index 6edfa0c4..fe481a7a 100644 --- a/.github/workflows/ci-interpreter.yml +++ b/.github/workflows/ci-interpreter.yml @@ -19,7 +19,7 @@ jobs: - name: Checkout repo uses: actions/checkout@v2 - name: Setup OCaml - uses: ocaml/setup-ocaml@v2 + uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.12.x - name: Setup OCaml tools