Skip to content

Commit 36eb53a

Browse files
Make non-natural alignment on atomic memroy operations a validation error
1 parent 9dce77b commit 36eb53a

2 files changed

Lines changed: 420 additions & 135 deletions

File tree

interpreter/valid/valid.ml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ let check_vec_binop binop at =
189189
error at "invalid lane index"
190190
| _ -> ()
191191

192-
let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at =
192+
let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at ~(isAtomic : bool) =
193193
let _mt = memory c (0l @@ at) in
194194
let size =
195195
match get_sz memop.pack with
@@ -199,7 +199,9 @@ let check_memop (c : context) (memop : ('t, 's) memop) ty_size get_sz at =
199199
packed_size sz
200200
in
201201
require (1 lsl memop.align <= size) at
202-
"alignment must not be larger than natural"
202+
"alignment must not be larger than natural";
203+
if isAtomic then
204+
require (1 lsl memop.align == size) at "atomic memory instruction's alignment must equal the instruction's natural alignment"
203205

204206

205207
(*
@@ -354,29 +356,29 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type
354356
[] --> []
355357

356358
| Load memop ->
357-
check_memop c memop num_size (Lib.Option.map fst) e.at;
359+
check_memop ~isAtomic:false c memop num_size (Lib.Option.map fst) e.at;
358360
[NumType I32Type] --> [NumType memop.ty]
359361

360362
| Store memop ->
361-
check_memop c memop num_size (fun sz -> sz) e.at;
363+
check_memop ~isAtomic:false c memop num_size (fun sz -> sz) e.at;
362364
[NumType I32Type; NumType memop.ty] --> []
363365

364366
| VecLoad memop ->
365-
check_memop c memop vec_size (Lib.Option.map fst) e.at;
367+
check_memop ~isAtomic:false c memop vec_size (Lib.Option.map fst) e.at;
366368
[NumType I32Type] --> [VecType memop.ty]
367369

368370
| VecStore memop ->
369-
check_memop c memop vec_size (fun _ -> None) e.at;
371+
check_memop ~isAtomic:false c memop vec_size (fun _ -> None) e.at;
370372
[NumType I32Type; VecType memop.ty] --> []
371373

372374
| VecLoadLane (memop, i) ->
373-
check_memop c memop vec_size (fun sz -> Some sz) e.at;
375+
check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at;
374376
require (i < vec_size memop.ty / packed_size memop.pack) e.at
375377
"invalid lane index";
376378
[NumType I32Type; VecType memop.ty] --> [VecType memop.ty]
377379

378380
| VecStoreLane (memop, i) ->
379-
check_memop c memop vec_size (fun sz -> Some sz) e.at;
381+
check_memop ~isAtomic:false c memop vec_size (fun sz -> Some sz) e.at;
380382
require (i < vec_size memop.ty / packed_size memop.pack) e.at
381383
"invalid lane index";
382384
[NumType I32Type; VecType memop.ty] --> []
@@ -514,23 +516,23 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type
514516
"invalid lane index";
515517
[t; NumType t2] --> [t]
516518
| MemoryAtomicWait atomicop ->
517-
check_memop c atomicop num_size (fun sz -> sz) e.at;
519+
check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at;
518520
[NumType I32Type; NumType atomicop.ty; NumType I64Type] --> [NumType I32Type]
519521
| MemoryAtomicNotify atomicop ->
520-
check_memop c atomicop num_size (fun sz -> sz) e.at;
522+
check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at;
521523
[NumType I32Type; NumType I32Type] --> [NumType I32Type]
522524
| AtomicFence -> [] --> []
523525
| AtomicLoad atomicop ->
524-
check_memop c atomicop num_size (fun sz -> sz) e.at;
526+
check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at;
525527
[NumType I32Type] --> [NumType atomicop.ty]
526528
| AtomicStore atomicop ->
527-
check_memop c atomicop num_size (fun sz -> sz) e.at;
529+
check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at;
528530
[NumType I32Type; NumType atomicop.ty] --> []
529531
| AtomicRmw (rmwop, atomicop) ->
530-
check_memop c atomicop num_size (fun sz -> sz) e.at;
532+
check_memop ~isAtomic:true c atomicop num_size (fun sz -> sz) e.at;
531533
[NumType I32Type; NumType atomicop.ty] --> [NumType atomicop.ty]
532534
| AtomicRmwCmpXchg atomicop ->
533-
check_memop c atomicop num_size (fun sz -> sz) e.at;
535+
check_memop ~isAtomic: true c atomicop num_size (fun sz -> sz) e.at;
534536
[NumType I32Type; NumType atomicop.ty; NumType atomicop.ty] --> [NumType atomicop.ty]
535537

536538
and check_seq (c : context) (s : infer_result_type) (es : instr list)

0 commit comments

Comments
 (0)