From c0b587ac5f3eb0ae5a4f3e762be9a15eec9733b8 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 14 Dec 2022 16:26:45 -0800 Subject: [PATCH] Remove heaps from core Cranelift, push them into `cranelift-wasm` (#5386) * cranelift-wasm: translate Wasm loads into lower-level CLIF operations Rather than using `heap_{load,store,addr}`. * cranelift: Remove the `heap_{addr,load,store}` instructions These are now legalized in the `cranelift-wasm` frontend. * cranelift: Remove the `ir::Heap` entity from CLIF * Port basic memory operation tests to .wat filetests * Remove test for verifying CLIF heaps * Remove `heap_addr` from replace_branching_instructions_and_cfg_predecessors.clif test * Remove `heap_addr` from readonly.clif test * Remove `heap_addr` from `table_addr.clif` test * Remove `heap_addr` from the simd-fvpromote_low.clif test * Remove `heap_addr` from simd-fvdemote.clif test * Remove `heap_addr` from the load-op-store.clif test * Remove the CLIF heap runtest * Remove `heap_addr` from the global_value.clif test * Remove `heap_addr` from fpromote.clif runtests * Remove `heap_addr` from fdemote.clif runtests * Remove `heap_addr` from memory.clif parser test * Remove `heap_addr` from reject_load_readonly.clif test * Remove `heap_addr` from reject_load_notrap.clif test * Remove `heap_addr` from load_readonly_notrap.clif test * Remove `static-heap-without-guard-pages.clif` test Will be subsumed when we port `make-heap-load-store-tests.sh` to generating `.wat` tests. * Remove `static-heap-with-guard-pages.clif` test Will be subsumed when we port `make-heap-load-store-tests.sh` over to `.wat` tests. * Remove more heap tests These will be subsumed by porting `make-heap-load-store-tests.sh` over to `.wat` tests. * Remove `heap_addr` from `simple-alias.clif` test * Remove `heap_addr` from partial-redundancy.clif test * Remove `heap_addr` from multiple-blocks.clif test * Remove `heap_addr` from fence.clif test * Remove `heap_addr` from extends.clif test * Remove runtests that rely on heaps Heaps are not a thing in CLIF or the interpreter anymore * Add generated load/store `.wat` tests * Enable memory-related wasm features in `.wat` tests * Remove CLIF heap from fcmp-mem-bug.clif test * Add a mode for compiling `.wat` all the way to assembly in filetests * Also generate WAT to assembly tests in `make-load-store-tests.sh` * cargo fmt * Reinstate `f{de,pro}mote.clif` tests without the heap bits * Remove undefined doc link * Remove outdated SVG and dot file from docs * Add docs about `None` returns for base address computation helpers * Factor out `env.heap_access_spectre_mitigation()` to a local * Expand docs for `FuncEnvironment::heaps` trait method * Restore f{de,pro}mote+load clif runtests with stack memory --- Cargo.lock | 1 + cranelift/codegen/Cargo.toml | 1 + cranelift/codegen/meta/src/cdsl/formats.rs | 9 - cranelift/codegen/meta/src/shared/entities.rs | 5 - cranelift/codegen/meta/src/shared/formats.rs | 22 - .../codegen/meta/src/shared/immediates.rs | 17 - .../codegen/meta/src/shared/instructions.rs | 83 ---- cranelift/codegen/meta/src/shared/settings.rs | 15 - cranelift/codegen/src/ir/dfg.rs | 9 +- cranelift/codegen/src/ir/entities.rs | 63 --- cranelift/codegen/src/ir/function.rs | 14 +- cranelift/codegen/src/ir/heap.rs | 67 --- cranelift/codegen/src/ir/immediates.rs | 13 - cranelift/codegen/src/ir/mod.rs | 6 +- cranelift/codegen/src/legalizer/mod.rs | 19 - cranelift/codegen/src/opts.rs | 4 +- cranelift/codegen/src/settings.rs | 17 +- cranelift/codegen/src/verifier/mod.rs | 79 ---- cranelift/codegen/src/write.rs | 56 --- cranelift/docs/heap.dot | 8 - cranelift/docs/heap.svg | 26 -- cranelift/docs/ir.md | 144 +------ cranelift/docs/testing.md | 76 ---- .../filetests/filetests/alias/extends.clif | 3 +- .../filetests/filetests/alias/fence.clif | 3 +- .../filetests/alias/multiple-blocks.clif | 4 +- .../filetests/alias/partial-redundancy.clif | 7 +- .../filetests/alias/simple-alias.clif | 10 +- .../filetests/isa/aarch64/heap_addr.clif | 88 ---- .../filetests/isa/riscv64/heap-addr.clif | 86 ---- .../filetests/isa/s390x/heap_addr.clif | 81 ---- .../filetests/isa/x64/fcmp-mem-bug.clif | 1 - .../filetests/isa/x64/heap-no-spectre.clif | 86 ---- .../filetests/filetests/isa/x64/heap.clif | 147 ------- .../filetests/legalizer/bounds-checks.clif | 33 -- .../static-heap-with-guard-pages.clif | 22 - .../static-heap-without-guard-pages.clif | 28 -- .../filetests/licm/load_readonly_notrap.clif | 6 +- .../filetests/licm/reject_load_notrap.clif | 6 +- .../filetests/licm/reject_load_readonly.clif | 6 +- .../filetests/filetests/parser/memory.clif | 31 -- .../filetests/filetests/runtests/fdemote.clif | 11 +- .../filetests/runtests/fpromote.clif | 12 +- .../filetests/runtests/global_value.clif | 24 -- .../filetests/filetests/runtests/heap.clif | 223 ---------- .../filetests/runtests/load-op-store.clif | 98 ----- .../filetests/runtests/simd-fvdemote.clif | 25 -- .../runtests/simd-fvpromote_low.clif | 26 -- .../filetests/runtests/table_addr.clif | 144 ------- .../filetests/simple_gvn/readonly.clif | 7 +- ...ing_instructions_and_cfg_predecessors.clif | 6 +- .../filetests/filetests/verifier/heap.clif | 45 -- .../filetests/wasm/basic-wat-test.wat | 19 +- .../filetests/filetests/wasm/f32-load.wat | 22 + .../filetests/wasm/f32-memory64.clif | 27 -- .../filetests/filetests/wasm/f32-store.wat | 25 ++ .../filetests/filetests/wasm/f64-load.wat | 24 ++ .../filetests/wasm/f64-memory64.clif | 27 -- .../filetests/filetests/wasm/f64-store.wat | 25 ++ .../filetests/filetests/wasm/i32-load.wat | 24 ++ .../filetests/filetests/wasm/i32-load16-s.wat | 24 ++ .../filetests/filetests/wasm/i32-load16-u.wat | 24 ++ .../filetests/filetests/wasm/i32-load8-s.wat | 24 ++ .../filetests/filetests/wasm/i32-load8-u.wat | 24 ++ .../filetests/wasm/i32-memory64.clif | 87 ---- .../filetests/filetests/wasm/i32-store.wat | 25 ++ .../filetests/filetests/wasm/i32-store16.wat | 25 ++ .../filetests/filetests/wasm/i32-store8.wat | 25 ++ .../filetests/filetests/wasm/i64-load.wat | 24 ++ .../filetests/filetests/wasm/i64-load16-s.wat | 24 ++ .../filetests/filetests/wasm/i64-load16-u.wat | 24 ++ .../filetests/filetests/wasm/i64-load8-s.wat | 24 ++ .../filetests/filetests/wasm/i64-load8-u.wat | 24 ++ .../filetests/wasm/i64-memory64.clif | 117 ------ .../filetests/filetests/wasm/i64-store.wat | 25 ++ .../filetests/filetests/wasm/i64-store16.wat | 25 ++ .../filetests/filetests/wasm/i64-store32.wat | 25 ++ .../filetests/filetests/wasm/i64-store8.wat | 25 ++ ...0_guard_no_spectre_i32_access_0_offset.wat | 24 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 26 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 28 +- ..._0_guard_no_spectre_i8_access_0_offset.wat | 22 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 26 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 28 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 26 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 28 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 30 +- ...0_guard_yes_spectre_i8_access_0_offset.wat | 24 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 28 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 30 +- ...f_guard_no_spectre_i32_access_0_offset.wat | 24 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 26 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 28 +- ...ff_guard_no_spectre_i8_access_0_offset.wat | 22 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 26 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 28 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 26 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 28 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 30 +- ...f_guard_yes_spectre_i8_access_0_offset.wat | 24 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 28 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 30 +- ...0_guard_no_spectre_i32_access_0_offset.wat | 22 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 24 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 26 +- ..._0_guard_no_spectre_i8_access_0_offset.wat | 20 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 24 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 26 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 24 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 26 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 28 +- ...0_guard_yes_spectre_i8_access_0_offset.wat | 22 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 26 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 28 +- ...f_guard_no_spectre_i32_access_0_offset.wat | 22 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 24 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 26 +- ...ff_guard_no_spectre_i8_access_0_offset.wat | 20 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 24 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 26 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 24 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 26 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 28 +- ...f_guard_yes_spectre_i8_access_0_offset.wat | 22 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 26 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 28 +- ...0_guard_no_spectre_i32_access_0_offset.wat | 20 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 22 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 18 +- ..._0_guard_no_spectre_i8_access_0_offset.wat | 20 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 22 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 18 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 24 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 26 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 18 +- ...0_guard_yes_spectre_i8_access_0_offset.wat | 24 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 26 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 18 +- ...f_guard_no_spectre_i32_access_0_offset.wat | 16 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 18 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 18 +- ...ff_guard_no_spectre_i8_access_0_offset.wat | 16 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 18 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 18 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 16 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 18 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 18 +- ...f_guard_yes_spectre_i8_access_0_offset.wat | 16 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 18 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 18 +- ...0_guard_no_spectre_i32_access_0_offset.wat | 18 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 20 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 16 +- ..._0_guard_no_spectre_i8_access_0_offset.wat | 18 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 20 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 16 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 22 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 24 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 16 +- ...0_guard_yes_spectre_i8_access_0_offset.wat | 22 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 24 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 16 +- ...f_guard_no_spectre_i32_access_0_offset.wat | 18 +- ...rd_no_spectre_i32_access_0x1000_offset.wat | 20 +- ...o_spectre_i32_access_0xffff0000_offset.wat | 16 +- ...ff_guard_no_spectre_i8_access_0_offset.wat | 18 +- ...ard_no_spectre_i8_access_0x1000_offset.wat | 20 +- ...no_spectre_i8_access_0xffff0000_offset.wat | 16 +- ..._guard_yes_spectre_i32_access_0_offset.wat | 22 +- ...d_yes_spectre_i32_access_0x1000_offset.wat | 24 +- ...s_spectre_i32_access_0xffff0000_offset.wat | 16 +- ...f_guard_yes_spectre_i8_access_0_offset.wat | 22 +- ...rd_yes_spectre_i8_access_0x1000_offset.wat | 24 +- ...es_spectre_i8_access_0xffff0000_offset.wat | 16 +- cranelift/filetests/src/lib.rs | 1 - .../filetests/src/runtest_environment.rs | 50 +-- cranelift/filetests/src/test_interpret.rs | 57 +-- cranelift/filetests/src/test_run.rs | 26 +- cranelift/filetests/src/test_wasm/config.rs | 16 +- cranelift/filetests/src/test_wasm/env.rs | 35 +- cranelift/frontend/src/frontend.rs | 13 +- cranelift/fuzzgen/src/function_generator.rs | 4 +- cranelift/interpreter/src/interpreter.rs | 184 +-------- cranelift/interpreter/src/state.rs | 18 +- cranelift/interpreter/src/step.rs | 84 ---- cranelift/reader/src/heap_command.rs | 71 ---- cranelift/reader/src/lexer.rs | 2 - cranelift/reader/src/lib.rs | 6 +- cranelift/reader/src/parser.rs | 346 +--------------- cranelift/reader/src/sourcemap.rs | 21 +- cranelift/wasm/src/code_translator.rs | 186 ++++++--- .../src/code_translator/bounds_checks.rs} | 388 +++++++----------- cranelift/wasm/src/environ/dummy.rs | 48 ++- cranelift/wasm/src/environ/spec.rs | 36 +- cranelift/wasm/src/heap.rs | 99 +++++ cranelift/wasm/src/lib.rs | 2 + cranelift/wasm/src/state.rs | 12 +- crates/cranelift/src/func_environ.rs | 50 ++- 198 files changed, 2494 insertions(+), 4232 deletions(-) delete mode 100644 cranelift/codegen/src/ir/heap.rs delete mode 100644 cranelift/docs/heap.dot delete mode 100644 cranelift/docs/heap.svg delete mode 100644 cranelift/filetests/filetests/isa/aarch64/heap_addr.clif delete mode 100644 cranelift/filetests/filetests/isa/riscv64/heap-addr.clif delete mode 100644 cranelift/filetests/filetests/isa/s390x/heap_addr.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/heap-no-spectre.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/heap.clif delete mode 100644 cranelift/filetests/filetests/legalizer/bounds-checks.clif delete mode 100644 cranelift/filetests/filetests/legalizer/static-heap-with-guard-pages.clif delete mode 100644 cranelift/filetests/filetests/legalizer/static-heap-without-guard-pages.clif delete mode 100644 cranelift/filetests/filetests/runtests/global_value.clif delete mode 100644 cranelift/filetests/filetests/runtests/heap.clif delete mode 100644 cranelift/filetests/filetests/runtests/load-op-store.clif delete mode 100644 cranelift/filetests/filetests/runtests/simd-fvdemote.clif delete mode 100644 cranelift/filetests/filetests/runtests/simd-fvpromote_low.clif delete mode 100644 cranelift/filetests/filetests/runtests/table_addr.clif delete mode 100644 cranelift/filetests/filetests/verifier/heap.clif create mode 100644 cranelift/filetests/filetests/wasm/f32-load.wat delete mode 100644 cranelift/filetests/filetests/wasm/f32-memory64.clif create mode 100644 cranelift/filetests/filetests/wasm/f32-store.wat create mode 100644 cranelift/filetests/filetests/wasm/f64-load.wat delete mode 100644 cranelift/filetests/filetests/wasm/f64-memory64.clif create mode 100644 cranelift/filetests/filetests/wasm/f64-store.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-load.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-load16-s.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-load16-u.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-load8-s.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-load8-u.wat delete mode 100644 cranelift/filetests/filetests/wasm/i32-memory64.clif create mode 100644 cranelift/filetests/filetests/wasm/i32-store.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-store16.wat create mode 100644 cranelift/filetests/filetests/wasm/i32-store8.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-load.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-load16-s.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-load16-u.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-load8-s.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-load8-u.wat delete mode 100644 cranelift/filetests/filetests/wasm/i64-memory64.clif create mode 100644 cranelift/filetests/filetests/wasm/i64-store.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-store16.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-store32.wat create mode 100644 cranelift/filetests/filetests/wasm/i64-store8.wat delete mode 100644 cranelift/reader/src/heap_command.rs rename cranelift/{codegen/src/legalizer/heap.rs => wasm/src/code_translator/bounds_checks.rs} (52%) create mode 100644 cranelift/wasm/src/heap.rs diff --git a/Cargo.lock b/Cargo.lock index 29e6ee8d02d4..c95dc916e04c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -563,6 +563,7 @@ dependencies = [ "regalloc2", "serde", "sha2 0.10.2", + "similar", "smallvec", "souper-ir", "target-lexicon", diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index 476034a6ed91..e9e33bed84e4 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -35,6 +35,7 @@ sha2 = { version = "0.10.2", optional = true } [dev-dependencies] criterion = "0.3" +similar = "2.1.0" [build-dependencies] cranelift-codegen-meta = { path = "meta", version = "0.92.0" } diff --git a/cranelift/codegen/meta/src/cdsl/formats.rs b/cranelift/codegen/meta/src/cdsl/formats.rs index c627e0269bd6..876fb7702f3f 100644 --- a/cranelift/codegen/meta/src/cdsl/formats.rs +++ b/cranelift/codegen/meta/src/cdsl/formats.rs @@ -116,15 +116,6 @@ impl InstructionFormatBuilder { self } - pub fn imm_with_name(mut self, name: &'static str, operand_kind: &OperandKind) -> Self { - let field = FormatField { - kind: operand_kind.clone(), - member: name, - }; - self.0.imm_fields.push(field); - self - } - pub fn typevar_operand(mut self, operand_index: usize) -> Self { assert!(self.0.typevar_operand.is_none()); assert!(operand_index < self.0.num_value_operands); diff --git a/cranelift/codegen/meta/src/shared/entities.rs b/cranelift/codegen/meta/src/shared/entities.rs index f612d3507d0b..6a3ae9b0fd1d 100644 --- a/cranelift/codegen/meta/src/shared/entities.rs +++ b/cranelift/codegen/meta/src/shared/entities.rs @@ -35,9 +35,6 @@ pub(crate) struct EntityRefs { /// A reference to a jump table declared in the function preamble. pub(crate) jump_table: OperandKind, - /// A reference to a heap declared in the function preamble. - pub(crate) heap: OperandKind, - /// A reference to a table declared in the function preamble. pub(crate) table: OperandKind, @@ -69,8 +66,6 @@ impl EntityRefs { jump_table: new("table", "ir::JumpTable", "A jump table."), - heap: new("heap", "ir::Heap", "A heap."), - table: new("table", "ir::Table", "A table."), varargs: OperandKind::new( diff --git a/cranelift/codegen/meta/src/shared/formats.rs b/cranelift/codegen/meta/src/shared/formats.rs index e9d5175618be..ad3bdd7e3198 100644 --- a/cranelift/codegen/meta/src/shared/formats.rs +++ b/cranelift/codegen/meta/src/shared/formats.rs @@ -15,9 +15,6 @@ pub(crate) struct Formats { pub(crate) cond_trap: Rc, pub(crate) float_compare: Rc, pub(crate) func_addr: Rc, - pub(crate) heap_addr: Rc, - pub(crate) heap_load: Rc, - pub(crate) heap_store: Rc, pub(crate) int_compare: Rc, pub(crate) int_compare_imm: Rc, pub(crate) int_add_trap: Rc, @@ -200,25 +197,6 @@ impl Formats { .imm(&entities.dynamic_stack_slot) .build(), - // Accessing a WebAssembly heap. - heap_addr: Builder::new("HeapAddr") - .imm(&entities.heap) - .value() - .imm_with_name("offset", &imm.uimm32) - .imm_with_name("size", &imm.uimm8) - .build(), - - heap_load: Builder::new("HeapLoad").imm(&imm.heap_imm).value().build(), - - heap_store: Builder::new("HeapStore") - // We have more fields for this instruction than - // `InstructionData` can hold without growing in size, so we - // push the immediates out into a side table. - .imm(&imm.heap_imm) - .value() - .value() - .build(), - // Accessing a WebAssembly table. table_addr: Builder::new("TableAddr") .imm(&entities.table) diff --git a/cranelift/codegen/meta/src/shared/immediates.rs b/cranelift/codegen/meta/src/shared/immediates.rs index 9e9cdb196519..9f908c93da48 100644 --- a/cranelift/codegen/meta/src/shared/immediates.rs +++ b/cranelift/codegen/meta/src/shared/immediates.rs @@ -14,9 +14,6 @@ pub(crate) struct Immediates { /// counts on shift instructions. pub uimm8: OperandKind, - /// An unsigned 32-bit immediate integer operand. - pub uimm32: OperandKind, - /// An unsigned 128-bit immediate integer operand. /// /// This operand is used to pass entire 128-bit vectors as immediates to instructions like @@ -59,9 +56,6 @@ pub(crate) struct Immediates { /// Flags for memory operations like `load` and `store`. pub memflags: OperandKind, - /// A reference to out-of-line immediates for heap accesses. - pub heap_imm: OperandKind, - /// A trap code indicating the reason for trapping. /// /// The Rust enum type also has a `User(u16)` variant for user-provided trap codes. @@ -110,11 +104,6 @@ impl Immediates { "ir::immediates::Uimm8", "An 8-bit immediate unsigned integer.", ), - uimm32: new_imm( - "imm", - "ir::immediates::Uimm32", - "A 32-bit immediate unsigned integer.", - ), uimm128: new_imm( "imm", "ir::Immediate", @@ -186,12 +175,6 @@ impl Immediates { memflags: new_imm("flags", "ir::MemFlags", "Memory operation flags"), - heap_imm: new_imm( - "heap_imm", - "ir::HeapImm", - "Reference to out-of-line heap access immediates", - ), - trapcode: { let mut trapcode_values = HashMap::new(); trapcode_values.insert("stk_ovf", "StackOverflow"); diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index 3ff997c18cb9..447c586f24d0 100755 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -1118,89 +1118,6 @@ pub(crate) fn define( .operands_out(vec![a]), ); - let HeapOffset = &TypeVar::new( - "HeapOffset", - "An unsigned heap offset", - TypeSetBuilder::new().ints(32..64).build(), - ); - - let H = &Operand::new("H", &entities.heap); - let index = &Operand::new("index", HeapOffset); - let Offset = &Operand::new("Offset", &imm.uimm32).with_doc("Static offset immediate in bytes"); - let Size = &Operand::new("Size", &imm.uimm8).with_doc("Static size immediate in bytes"); - - ig.push( - Inst::new( - "heap_addr", - r#" - Bounds check and compute absolute address of ``index + Offset`` in heap memory. - - Verify that the range ``index .. index + Offset + Size`` is in bounds for the - heap ``H``, and generate an absolute address that is safe to dereference. - - 1. If ``index + Offset + Size`` is less than or equal ot the heap bound, return an - absolute address corresponding to a byte offset of ``index + Offset`` from the - heap's base address. - - 2. If ``index + Offset + Size`` is greater than the heap bound, return the - ``NULL`` pointer or any other address that is guaranteed to generate a trap - when accessed. - "#, - &formats.heap_addr, - ) - .operands_in(vec![H, index, Offset, Size]) - .operands_out(vec![addr]), - ); - - let heap_imm = &Operand::new("heap_imm", &imm.heap_imm); - let index = - &Operand::new("index", HeapOffset).with_doc("Dynamic index (in bytes) into the heap"); - let a = &Operand::new("a", Mem).with_doc("The value loaded from the heap"); - - ig.push( - Inst::new( - "heap_load", - r#" - Load a value from the given heap at address ``index + offset``, - trapping on out-of-bounds accesses. - - Checks that ``index + offset .. index + offset + sizeof(a)`` is - within the heap's bounds, trapping if it is not. Otherwise, when - that range is in bounds, loads the value from the heap. - - Traps on ``index + offset + sizeof(a)`` overflow. - "#, - &formats.heap_load, - ) - .operands_in(vec![heap_imm, index]) - .operands_out(vec![a]) - .can_load(true) - .can_trap(true), - ); - - let a = &Operand::new("a", Mem).with_doc("The value stored into the heap"); - - ig.push( - Inst::new( - "heap_store", - r#" - Store ``a`` into the given heap at address ``index + offset``, - trapping on out-of-bounds accesses. - - Checks that ``index + offset .. index + offset + sizeof(a)`` is - within the heap's bounds, trapping if it is not. Otherwise, when - that range is in bounds, stores the value into the heap. - - Traps on ``index + offset + sizeof(a)`` overflow. - "#, - &formats.heap_store, - ) - .operands_in(vec![heap_imm, index, a]) - .operands_out(vec![]) - .can_store(true) - .can_trap(true), - ); - // Note this instruction is marked as having other side-effects, so GVN won't try to hoist it, // which would result in it being subject to spilling. While not hoisting would generally hurt // performance, since a computed value used many times may need to be regenerated before each diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs index b9fbef55c9e2..e51cd5a5ac56 100644 --- a/cranelift/codegen/meta/src/shared/settings.rs +++ b/cranelift/codegen/meta/src/shared/settings.rs @@ -139,21 +139,6 @@ pub(crate) fn define() -> SettingGroup { false, ); - settings.add_bool( - "use_pinned_reg_as_heap_base", - "Use the pinned register as the heap base.", - r#" - Enabling this requires the enable_pinned_reg setting to be set to true. It enables a custom - legalization of the `heap_addr` instruction so it will use the pinned register as the heap - base, instead of fetching it from a global value. - - Warning! Enabling this means that the pinned register *must* be maintained to contain the - heap base address at all times, during the lifetime of a function. Using the pinned - register for other purposes when this is set is very likely to cause crashes. - "#, - false, - ); - settings.add_bool( "enable_simd", "Enable the use of SIMD instructions.", diff --git a/cranelift/codegen/src/ir/dfg.rs b/cranelift/codegen/src/ir/dfg.rs index 6776e3a2cfaf..b83ffbb7ea59 100644 --- a/cranelift/codegen/src/ir/dfg.rs +++ b/cranelift/codegen/src/ir/dfg.rs @@ -4,12 +4,11 @@ use crate::entity::{self, PrimaryMap, SecondaryMap}; use crate::ir; use crate::ir::builder::ReplaceBuilder; use crate::ir::dynamic_type::{DynamicTypeData, DynamicTypes}; -use crate::ir::immediates::HeapImmData; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionData}; use crate::ir::{types, ConstantData, ConstantPool, Immediate}; use crate::ir::{ - Block, DynamicType, FuncRef, HeapImm, Inst, SigRef, Signature, Type, Value, - ValueLabelAssignments, ValueList, ValueListPool, + Block, DynamicType, FuncRef, Inst, SigRef, Signature, Type, Value, ValueLabelAssignments, + ValueList, ValueListPool, }; use crate::ir::{ExtFuncData, RelSourceLoc}; use crate::packed_option::ReservedValue; @@ -84,9 +83,6 @@ pub struct DataFlowGraph { /// Stores large immediates that otherwise will not fit on InstructionData pub immediates: PrimaryMap, - - /// Out-of-line heap access immediates that don't fit in `InstructionData`. - pub heap_imms: PrimaryMap, } impl DataFlowGraph { @@ -105,7 +101,6 @@ impl DataFlowGraph { values_labels: None, constants: ConstantPool::new(), immediates: PrimaryMap::new(), - heap_imms: PrimaryMap::new(), } } diff --git a/cranelift/codegen/src/ir/entities.rs b/cranelift/codegen/src/ir/entities.rs index dc63d0ec37d6..8573b4cd7d9d 100644 --- a/cranelift/codegen/src/ir/entities.rs +++ b/cranelift/codegen/src/ir/entities.rs @@ -368,60 +368,6 @@ impl SigRef { } } -/// An opaque reference to a [heap](https://en.wikipedia.org/wiki/Memory_management#DYNAMIC). -/// -/// Heaps are used to access dynamically allocated memory through -/// [`heap_addr`](super::InstBuilder::heap_addr). -/// -/// To create a heap, use [`FunctionBuilder::create_heap`](https://docs.rs/cranelift-frontend/*/cranelift_frontend/struct.FunctionBuilder.html#method.create_heap). -/// -/// While the order is stable, it is arbitrary. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct Heap(u32); -entity_impl!(Heap, "heap"); - -impl Heap { - /// Create a new heap reference from its number. - /// - /// This method is for use by the parser. - pub fn with_number(n: u32) -> Option { - if n < u32::MAX { - Some(Self(n)) - } else { - None - } - } -} - -/// An opaque reference to some out-of-line immediates for `heap_{load,store}` -/// instructions. -/// -/// These immediates are too large to store in -/// [`InstructionData`](super::instructions::InstructionData) and therefore must -/// be tracked separately in -/// [`DataFlowGraph::heap_imms`](super::dfg::DataFlowGraph). `HeapImm` provides -/// a way to reference values stored there. -/// -/// While the order is stable, it is arbitrary. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct HeapImm(u32); -entity_impl!(HeapImm, "heap_imm"); - -impl HeapImm { - /// Create a new `HeapImm` reference from its number. - /// - /// This method is for use by the parser. - pub fn with_number(n: u32) -> Option { - if n < u32::MAX { - Some(Self(n)) - } else { - None - } - } -} - /// An opaque reference to a [WebAssembly /// table](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format#WebAssembly_tables). /// @@ -477,8 +423,6 @@ pub enum AnyEntity { FuncRef(FuncRef), /// A function call signature. SigRef(SigRef), - /// A heap. - Heap(Heap), /// A table. Table(Table), /// A function's stack limit @@ -500,7 +444,6 @@ impl fmt::Display for AnyEntity { Self::Constant(r) => r.fmt(f), Self::FuncRef(r) => r.fmt(f), Self::SigRef(r) => r.fmt(f), - Self::Heap(r) => r.fmt(f), Self::Table(r) => r.fmt(f), Self::StackLimit => write!(f, "stack_limit"), } @@ -579,12 +522,6 @@ impl From for AnyEntity { } } -impl From for AnyEntity { - fn from(r: Heap) -> Self { - Self::Heap(r) - } -} - impl From for AnyEntity { fn from(r: Table) -> Self { Self::Table(r) diff --git a/cranelift/codegen/src/ir/function.rs b/cranelift/codegen/src/ir/function.rs index 06f0bcd7567b..39a0ab4dd7cb 100644 --- a/cranelift/codegen/src/ir/function.rs +++ b/cranelift/codegen/src/ir/function.rs @@ -8,8 +8,8 @@ use crate::ir; use crate::ir::JumpTables; use crate::ir::{ instructions::BranchInfo, Block, DynamicStackSlot, DynamicStackSlotData, DynamicType, - ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap, HeapData, Inst, InstructionData, - JumpTable, JumpTableData, Opcode, SigRef, StackSlot, StackSlotData, Table, TableData, Type, + ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Inst, InstructionData, JumpTable, + JumpTableData, Opcode, SigRef, StackSlot, StackSlotData, Table, TableData, Type, }; use crate::ir::{DataFlowGraph, Layout, Signature}; use crate::ir::{DynamicStackSlots, SourceLocs, StackSlots}; @@ -170,9 +170,6 @@ pub struct FunctionStencil { /// Global values referenced. pub global_values: PrimaryMap, - /// Heaps referenced. - pub heaps: PrimaryMap, - /// Tables referenced. pub tables: PrimaryMap, @@ -205,7 +202,6 @@ impl FunctionStencil { self.sized_stack_slots.clear(); self.dynamic_stack_slots.clear(); self.global_values.clear(); - self.heaps.clear(); self.tables.clear(); self.jump_tables.clear(); self.dfg.clear(); @@ -261,11 +257,6 @@ impl FunctionStencil { .concrete() } - /// Declares a heap accessible to the function. - pub fn create_heap(&mut self, data: HeapData) -> Heap { - self.heaps.push(data) - } - /// Declares a table accessible to the function. pub fn create_table(&mut self, data: TableData) -> Table { self.tables.push(data) @@ -447,7 +438,6 @@ impl Function { sized_stack_slots: StackSlots::new(), dynamic_stack_slots: DynamicStackSlots::new(), global_values: PrimaryMap::new(), - heaps: PrimaryMap::new(), tables: PrimaryMap::new(), jump_tables: PrimaryMap::new(), dfg: DataFlowGraph::new(), diff --git a/cranelift/codegen/src/ir/heap.rs b/cranelift/codegen/src/ir/heap.rs deleted file mode 100644 index 7d62915af54d..000000000000 --- a/cranelift/codegen/src/ir/heap.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! Heaps. - -use crate::ir::immediates::Uimm64; -use crate::ir::{GlobalValue, Type}; -use core::fmt; - -#[cfg(feature = "enable-serde")] -use serde::{Deserialize, Serialize}; - -/// Information about a heap declaration. -#[derive(Clone, PartialEq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct HeapData { - /// The address of the start of the heap's storage. - pub base: GlobalValue, - - /// Guaranteed minimum heap size in bytes. Heap accesses before `min_size` don't need bounds - /// checking. - pub min_size: Uimm64, - - /// Size in bytes of the offset-guard pages following the heap. - pub offset_guard_size: Uimm64, - - /// Heap style, with additional style-specific info. - pub style: HeapStyle, - - /// The index type for the heap. - pub index_type: Type, -} - -/// Style of heap including style-specific information. -#[derive(Clone, PartialEq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub enum HeapStyle { - /// A dynamic heap can be relocated to a different base address when it is grown. - Dynamic { - /// Global value providing the current bound of the heap in bytes. - bound_gv: GlobalValue, - }, - - /// A static heap has a fixed base address and a number of not-yet-allocated pages before the - /// offset-guard pages. - Static { - /// Heap bound in bytes. The offset-guard pages are allocated after the bound. - bound: Uimm64, - }, -} - -impl fmt::Display for HeapData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(match self.style { - HeapStyle::Dynamic { .. } => "dynamic", - HeapStyle::Static { .. } => "static", - })?; - - write!(f, " {}, min {}", self.base, self.min_size)?; - match self.style { - HeapStyle::Dynamic { bound_gv } => write!(f, ", bound {}", bound_gv)?, - HeapStyle::Static { bound } => write!(f, ", bound {}", bound)?, - } - write!( - f, - ", offset_guard {}, index_type {}", - self.offset_guard_size, self.index_type - ) - } -} diff --git a/cranelift/codegen/src/ir/immediates.rs b/cranelift/codegen/src/ir/immediates.rs index 54f737b19d1b..3b3f7032353b 100644 --- a/cranelift/codegen/src/ir/immediates.rs +++ b/cranelift/codegen/src/ir/immediates.rs @@ -4,7 +4,6 @@ //! Each type here should have a corresponding definition in the //! `cranelift-codegen/meta/src/shared/immediates` crate in the meta language. -use crate::ir; use alloc::vec::Vec; use core::cmp::Ordering; use core::convert::TryFrom; @@ -1178,18 +1177,6 @@ impl Not for Ieee64 { } } -/// Out-of-line heap access immediates. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -pub struct HeapImmData { - /// The memory flags for the heap access. - pub flags: ir::MemFlags, - /// The heap being accessed. - pub heap: ir::Heap, - /// The static offset added to the heap access's index. - pub offset: Uimm32, -} - #[cfg(test)] mod tests { use super::*; diff --git a/cranelift/codegen/src/ir/mod.rs b/cranelift/codegen/src/ir/mod.rs index 3858a56917d1..0457308b0f84 100644 --- a/cranelift/codegen/src/ir/mod.rs +++ b/cranelift/codegen/src/ir/mod.rs @@ -11,7 +11,6 @@ mod extfunc; mod extname; pub mod function; mod globalvalue; -mod heap; pub mod immediates; pub mod instructions; pub mod jumptable; @@ -37,8 +36,8 @@ pub use crate::ir::constant::{ConstantData, ConstantPool}; pub use crate::ir::dfg::{DataFlowGraph, ValueDef}; pub use crate::ir::dynamic_type::{dynamic_to_fixed, DynamicTypeData, DynamicTypes}; pub use crate::ir::entities::{ - Block, Constant, DynamicStackSlot, DynamicType, FuncRef, GlobalValue, Heap, HeapImm, Immediate, - Inst, JumpTable, SigRef, StackSlot, Table, UserExternalNameRef, Value, + Block, Constant, DynamicStackSlot, DynamicType, FuncRef, GlobalValue, Immediate, Inst, + JumpTable, SigRef, StackSlot, Table, UserExternalNameRef, Value, }; pub use crate::ir::extfunc::{ AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature, @@ -46,7 +45,6 @@ pub use crate::ir::extfunc::{ pub use crate::ir::extname::{ExternalName, UserExternalName, UserFuncName}; pub use crate::ir::function::{DisplayFunctionAnnotations, Function}; pub use crate::ir::globalvalue::GlobalValueData; -pub use crate::ir::heap::{HeapData, HeapStyle}; pub use crate::ir::instructions::{ InstructionData, Opcode, ValueList, ValueListPool, VariableArgs, }; diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index e82189cec188..0716b440d907 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -22,11 +22,9 @@ use crate::isa::TargetIsa; use crate::trace; mod globalvalue; -mod heap; mod table; use self::globalvalue::expand_global_value; -use self::heap::{expand_heap_addr, expand_heap_load, expand_heap_store}; use self::table::expand_table_addr; fn imm_const(pos: &mut FuncCursor, arg: Value, imm: Imm64, is_signed: bool) -> Value { @@ -71,23 +69,6 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa: opcode: ir::Opcode::GlobalValue, global_value, } => expand_global_value(inst, &mut pos.func, isa, global_value), - InstructionData::HeapAddr { - opcode: ir::Opcode::HeapAddr, - heap, - arg, - offset, - size, - } => expand_heap_addr(inst, &mut pos.func, cfg, isa, heap, arg, offset, size), - InstructionData::HeapLoad { - opcode: ir::Opcode::HeapLoad, - heap_imm, - arg, - } => expand_heap_load(inst, &mut pos.func, cfg, isa, heap_imm, arg), - InstructionData::HeapStore { - opcode: ir::Opcode::HeapStore, - heap_imm, - args, - } => expand_heap_store(inst, &mut pos.func, cfg, isa, heap_imm, args[0], args[1]), InstructionData::StackLoad { opcode: ir::Opcode::StackLoad, stack_slot, diff --git a/cranelift/codegen/src/opts.rs b/cranelift/codegen/src/opts.rs index 17da7aff578e..62146c78541f 100644 --- a/cranelift/codegen/src/opts.rs +++ b/cranelift/codegen/src/opts.rs @@ -8,8 +8,8 @@ pub use crate::ir::immediates::{Ieee32, Ieee64, Imm64, Offset32, Uimm32, Uimm64, pub use crate::ir::types::*; pub use crate::ir::{ dynamic_to_fixed, AtomicRmwOp, Block, Constant, DataFlowGraph, DynamicStackSlot, FuncRef, - GlobalValue, Heap, HeapImm, Immediate, InstructionData, JumpTable, MemFlags, Opcode, StackSlot, - Table, TrapCode, Type, Value, + GlobalValue, Immediate, InstructionData, JumpTable, MemFlags, Opcode, StackSlot, Table, + TrapCode, Type, Value, }; use crate::isle_common_prelude_methods; use crate::machinst::isle::*; diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 4418f990a178..27be5c17f65b 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -518,9 +518,8 @@ mod tests { fn display_default() { let b = builder(); let f = Flags::new(b); - assert_eq!( - f.to_string(), - r#"[shared] + let actual = f.to_string(); + let expected = r#"[shared] opt_level = "none" tls_model = "none" libcall_call_conv = "isa_default" @@ -537,7 +536,6 @@ avoid_div_traps = false enable_float = true enable_nan_canonicalization = false enable_pinned_reg = false -use_pinned_reg_as_heap_base = false enable_simd = false enable_atomics = true enable_safepoints = false @@ -551,8 +549,15 @@ enable_jump_tables = true enable_heap_access_spectre_mitigation = true enable_table_access_spectre_mitigation = true enable_incremental_compilation_cache_checks = false -"# - ); +"#; + if actual != expected { + panic!( + "Default settings do not match expectations:\n\n{}", + similar::TextDiff::from_lines(expected, &actual) + .unified_diff() + .header("expected", "actual") + ); + } assert_eq!(f.opt_level(), super::OptLevel::None); assert_eq!(f.enable_simd(), false); } diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 162d909c632e..7382ea31e786 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -63,7 +63,6 @@ use crate::entity::SparseSet; use crate::flowgraph::{BlockPredecessor, ControlFlowGraph}; use crate::ir; use crate::ir::entities::AnyEntity; -use crate::ir::immediates::HeapImmData; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint}; use crate::ir::{ types, ArgumentPurpose, Block, Constant, DynamicStackSlot, FuncRef, Function, GlobalValue, @@ -404,49 +403,6 @@ impl<'a> Verifier<'a> { Ok(()) } - fn verify_heaps(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> { - if let Some(isa) = self.isa { - for (heap, heap_data) in &self.func.heaps { - let base = heap_data.base; - if !self.func.global_values.is_valid(base) { - return errors.nonfatal((heap, format!("invalid base global value {}", base))); - } - - let pointer_type = isa.pointer_type(); - let base_type = self.func.global_values[base].global_type(isa); - if base_type != pointer_type { - errors.report(( - heap, - format!( - "heap base has type {}, which is not the pointer type {}", - base_type, pointer_type - ), - )); - } - - if let ir::HeapStyle::Dynamic { bound_gv, .. } = heap_data.style { - if !self.func.global_values.is_valid(bound_gv) { - return errors - .nonfatal((heap, format!("invalid bound global value {}", bound_gv))); - } - - let bound_type = self.func.global_values[bound_gv].global_type(isa); - if pointer_type != bound_type { - errors.report(( - heap, - format!( - "heap pointer type {} differs from the type of its bound, {}", - pointer_type, bound_type - ), - )); - } - } - } - } - - Ok(()) - } - fn verify_tables(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> { if let Some(isa) = self.isa { for (table, table_data) in &self.func.tables { @@ -676,13 +632,6 @@ impl<'a> Verifier<'a> { UnaryGlobalValue { global_value, .. } => { self.verify_global_value(inst, global_value, errors)?; } - HeapLoad { heap_imm, .. } | HeapStore { heap_imm, .. } => { - let HeapImmData { heap, .. } = self.func.dfg.heap_imms[heap_imm]; - self.verify_heap(inst, heap, errors)?; - } - HeapAddr { heap, .. } => { - self.verify_heap(inst, heap, errors)?; - } TableAddr { table, .. } => { self.verify_table(inst, table, errors)?; } @@ -878,19 +827,6 @@ impl<'a> Verifier<'a> { } } - fn verify_heap( - &self, - inst: Inst, - heap: ir::Heap, - errors: &mut VerifierErrors, - ) -> VerifierStepResult<()> { - if !self.func.heaps.is_valid(heap) { - errors.nonfatal((inst, self.context(inst), format!("invalid heap {}", heap))) - } else { - Ok(()) - } - } - fn verify_table( &self, inst: Inst, @@ -1557,20 +1493,6 @@ impl<'a> Verifier<'a> { _ => {} } } - ir::InstructionData::HeapAddr { heap, arg, .. } => { - let index_type = self.func.dfg.value_type(arg); - let heap_index_type = self.func.heaps[heap].index_type; - if index_type != heap_index_type { - return errors.nonfatal(( - inst, - self.context(inst), - format!( - "index type {} differs from heap index type {}", - index_type, heap_index_type, - ), - )); - } - } ir::InstructionData::TableAddr { table, arg, .. } => { let index_type = self.func.dfg.value_type(arg); let table_index_type = self.func.tables[table].index_type; @@ -1775,7 +1697,6 @@ impl<'a> Verifier<'a> { pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> { self.verify_global_values(errors)?; - self.verify_heaps(errors)?; self.verify_tables(errors)?; self.verify_jump_tables(errors)?; self.typecheck_entry_block_params(errors)?; diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs index 552cc8549b9c..8e80edc68d8f 100644 --- a/cranelift/codegen/src/write.rs +++ b/cranelift/codegen/src/write.rs @@ -5,7 +5,6 @@ use crate::entity::SecondaryMap; use crate::ir::entities::AnyEntity; -use crate::ir::immediates::{HeapImmData, Uimm32}; use crate::ir::{Block, DataFlowGraph, Function, Inst, SigRef, Type, Value, ValueDef}; use crate::packed_option::ReservedValue; use alloc::string::{String, ToString}; @@ -57,13 +56,6 @@ pub trait FuncWriter { self.write_entity_definition(w, func, gv.into(), gv_data)?; } - for (heap, heap_data) in &func.heaps { - if !heap_data.index_type.is_invalid() { - any = true; - self.write_entity_definition(w, func, heap.into(), heap_data)?; - } - } - for (table, table_data) in &func.tables { if !table_data.index_type.is_invalid() { any = true; @@ -478,54 +470,6 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt dynamic_stack_slot, .. } => write!(w, " {}, {}", arg, dynamic_stack_slot), - HeapLoad { - opcode: _, - heap_imm, - arg, - } => { - let HeapImmData { - flags, - heap, - offset, - } = dfg.heap_imms[heap_imm]; - write!( - w, - " {heap} {flags} {arg}{optional_offset}", - optional_offset = if offset == Uimm32::from(0) { - "".to_string() - } else { - format!("+{offset}") - } - ) - } - HeapStore { - opcode: _, - heap_imm, - args, - } => { - let HeapImmData { - flags, - heap, - offset, - } = dfg.heap_imms[heap_imm]; - let [index, value] = args; - write!( - w, - " {heap} {flags} {index}{optional_offset}, {value}", - optional_offset = if offset == Uimm32::from(0) { - "".to_string() - } else { - format!("+{offset}") - } - ) - } - HeapAddr { - heap, - arg, - offset, - size, - .. - } => write!(w, " {}, {}, {}, {}", heap, arg, offset, size), TableAddr { table, arg, .. } => write!(w, " {}, {}", table, arg), Load { flags, arg, offset, .. diff --git a/cranelift/docs/heap.dot b/cranelift/docs/heap.dot deleted file mode 100644 index 1c46f22b321d..000000000000 --- a/cranelift/docs/heap.dot +++ /dev/null @@ -1,8 +0,0 @@ -digraph { - node [ - shape=record, - fontsize=10, - fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans" - ] - "static" [label="mapped\npages|unmapped\npages|offset_guard\npages"] -} diff --git a/cranelift/docs/heap.svg b/cranelift/docs/heap.svg deleted file mode 100644 index e668f3e8deae..000000000000 --- a/cranelift/docs/heap.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%3 - - - -static - -mapped -pages - -unmapped -pages - -offset_guard -pages - - - diff --git a/cranelift/docs/ir.md b/cranelift/docs/ir.md index 6ad6d5fc73c9..625fd899fca4 100644 --- a/cranelift/docs/ir.md +++ b/cranelift/docs/ir.md @@ -559,148 +559,6 @@ GV = [colocated] symbol Name :arg Name: External name. :result GV: Global value. -### Heaps - -Code compiled from WebAssembly or asm.js runs in a sandbox where it can't access -all process memory. Instead, it is given a small set of memory areas to work -in, and all accesses are bounds checked. Cranelift models this through the -concept of *heaps*. - -A heap is declared in the function preamble and can be accessed with the -`heap_addr` instruction that [traps] on out-of-bounds accesses or -returns a pointer that is guaranteed to trap. Heap addresses can be smaller than -the native pointer size, for example unsigned `i32` offsets on a 64-bit -architecture. - -![Heap address space layout](./heap.svg) - -A heap appears as three consecutive ranges of address space: - -1. The *mapped pages* are the [accessible] memory range in the heap. A - heap may have a minimum guaranteed size which means that some mapped pages - are always present. -2. The *unmapped pages* is a possibly empty range of address space that may be - mapped in the future when the heap is grown. They are [addressable] but - not [accessible]. -3. The *offset-guard pages* is a range of address space that is guaranteed to - always cause a trap when accessed. It is used to optimize bounds checking for - heap accesses with a shared base pointer. They are [addressable] but - not [accessible]. - -The *heap bound* is the total size of the mapped and unmapped pages. This is -the bound that `heap_addr` checks against. Memory accesses inside the -heap bounds can trap if they hit an unmapped page (which is not -[accessible]). - -Two styles of heaps are supported, *static* and *dynamic*. They behave -differently when resized. - -#### Static heaps - -A *static heap* starts out with all the address space it will ever need, so it -never moves to a different address. At the base address is a number of mapped -pages corresponding to the heap's current size. Then follows a number of -unmapped pages where the heap can grow up to its maximum size. After the -unmapped pages follow the offset-guard pages which are also guaranteed to -generate a trap when accessed. - -H = static Base, min MinBytes, bound BoundBytes, offset_guard OffsetGuardBytes - Declare a static heap in the preamble. - - :arg Base: Global value holding the heap's base address. - :arg MinBytes: Guaranteed minimum heap size in bytes. Accesses below this - size will never trap. - :arg BoundBytes: Fixed heap bound in bytes. This defines the amount of - address space reserved for the heap, not including the offset-guard - pages. - :arg OffsetGuardBytes: Size of the offset-guard pages in bytes. - -#### Dynamic heaps - -A *dynamic heap* can be relocated to a different base address when it is -resized, and its bound can move dynamically. The offset-guard pages move when -the heap is resized. The bound of a dynamic heap is stored in a global value. - -H = dynamic Base, min MinBytes, bound BoundGV, offset_guard OffsetGuardBytes - Declare a dynamic heap in the preamble. - - :arg Base: Global value holding the heap's base address. - :arg MinBytes: Guaranteed minimum heap size in bytes. Accesses below this - size will never trap. - :arg BoundGV: Global value containing the current heap bound in bytes. - :arg OffsetGuardBytes: Size of the offset-guard pages in bytes. - -#### Heap examples - -Some Wasm VMs prefer to use fixed heaps with a 4 GB bound and 2 GB of -offset-guard pages when running WebAssembly code on 64-bit CPUs. The combination -of a 4 GB fixed bound and 1-byte bounds checks means that no code needs to be -generated for bounds checks at all: - -``` -test verifier - -function %add_members(i32, i64 vmctx) -> f32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+64 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v5: i64): - v1 = heap_addr.i64 heap0, v0, 1 - v2 = load.f32 v1+16 - v3 = load.f32 v1+20 - v4 = fadd v2, v3 - return v4 -} -``` - -A static heap can also be used for 32-bit code when the WebAssembly module -declares a small upper bound on its memory. A 1 MB static bound with a single 4 -KB offset-guard page still has opportunities for sharing bounds checking code: - -``` -test verifier - -function %add_members(i32, i32 vmctx) -> f32 { - gv0 = vmctx - gv1 = load.i32 notrap aligned gv0+64 - heap0 = static gv1, min 0x1000, bound 0x10_0000, offset_guard 0x1000 - -block0(v0: i32, v5: i32): - v1 = heap_addr.i32 heap0, v0, 1 - v2 = load.f32 v1+16 - v3 = load.f32 v1+20 - v4 = fadd v2, v3 - return v4 -} -``` - -If the upper bound on the heap size is too large, a dynamic heap is required -instead. - -Finally, a runtime environment that simply allocates a heap with -`malloc()` may not have any offset-guard pages at all. In that case, -full bounds checking is required for each access: - -``` -test verifier - -function %add_members(i32, i64 vmctx) -> f32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+64 - gv2 = load.i32 notrap aligned gv0+72 - heap0 = dynamic gv1, min 0x1000, bound gv2, offset_guard 0 - -block0(v0: i32, v6: i64): - v1 = heap_addr.i64 heap0, v0, 20 - v2 = load.f32 v1+16 - v3 = heap_addr.i64 heap0, v0, 24 - v4 = load.f32 v3+20 - v5 = fadd v2, v4 - return v5 -} -``` - ### Tables Code compiled from WebAssembly often needs access to objects outside of its @@ -728,7 +586,7 @@ T = dynamic Base, min MinElements, bound BoundGV, element_size ElementSize :arg Base: Global value holding the table's base address. :arg MinElements: Guaranteed minimum table size in elements. - :arg BoundGV: Global value containing the current heap bound in elements. + :arg BoundGV: Global value containing the current table bound in elements. :arg ElementSize: Size of each element. ### Constant materialization diff --git a/cranelift/docs/testing.md b/cranelift/docs/testing.md index 4dc60548084c..ce3cd6361d74 100644 --- a/cranelift/docs/testing.md +++ b/cranelift/docs/testing.md @@ -374,79 +374,3 @@ pointers are always 8 bytes, and laid out sequentially in memory. Even for 32 bi Currently, we only support requesting heaps, however this is a generic mechanism that should be able to introduce any sort of environment support that we may need later. (e.g. tables, global values, external functions) - -##### `heap` directive - -The `heap` directive allows a test to request a heap to be allocated and passed to the test via the environment struct. - - -A sample heap annotation is the following: -``` -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -``` - -This indicates the following: -* `static`: We have requested a non-resizable and non-movable static heap. -* `size=0x1000`: It has to have a size of 4096 bytes. -* `ptr=vmctx+0`: The pointer to the address to the start of this heap is placed at offset 0 in the `vmctx` struct -* `bound=vmctx+8`: The pointer to the address to the end of this heap is placed at offset 8 in the `vmctx` struct - -The `ptr` and `bound` arguments make explicit the placement of the pointers to the start and end of the heap memory in -the environment struct. `vmctx+0` means that at offset 0 of the environment struct there will be the pointer to the start -similarly, at offset 8 the pointer to the end. - - -You can combine multiple heap annotations, in which case, their pointers are laid out sequentially in memory in -the order that the annotations appear in the source file. - -``` -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; heap: dynamic, size=0x1000, ptr=vmctx+16, bound=vmctx+24 -``` - -An invalid or unexpected offset will raise an error when the test is run. - -See the diagram below, on how the `vmctx` struct ends up if with multiple heaps: - -``` - ┌─────────────────────┐ vmctx+0 - │heap0: start address │ - ├─────────────────────┤ vmctx+8 - │heap0: end address │ - ├─────────────────────┤ vmctx+16 - │heap1: start address │ - ├─────────────────────┤ vmctx+24 - │heap1: end address │ - ├─────────────────────┤ vmctx+32 - │etc... │ - └─────────────────────┘ -``` - -With this setup, you can now use the global values to load heaps, and load / store to them. - -Example: - -``` -function %heap_load_store(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+8 - heap0 = dynamic gv1, bound gv2, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %heap_load_store(0, 1) == 1 -``` - - -### `test interpret` - -Test the CLIF interpreter - -This test supports the same commands as `test run`, but runs the code in the cranelift -interpreter instead of the host machine. diff --git a/cranelift/filetests/filetests/alias/extends.clif b/cranelift/filetests/filetests/alias/extends.clif index 30d5cc03553f..9c04047e18c4 100644 --- a/cranelift/filetests/filetests/alias/extends.clif +++ b/cranelift/filetests/filetests/alias/extends.clif @@ -8,10 +8,9 @@ target aarch64 function %f0(i64 vmctx, i32) -> i32, i32, i32, i64, i64, i64 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 12, 0 + v2 = global_value.i64 gv1 ;; Initial load. This will not be reused by anything below, even ;; though it does access the same address. diff --git a/cranelift/filetests/filetests/alias/fence.clif b/cranelift/filetests/filetests/alias/fence.clif index c5b55ccc63b1..b279e384dc30 100644 --- a/cranelift/filetests/filetests/alias/fence.clif +++ b/cranelift/filetests/filetests/alias/fence.clif @@ -8,10 +8,9 @@ target aarch64 function %f0(i64 vmctx, i32) -> i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 12, 0 + v2 = global_value.i64 gv1 v3 = load.i32 v2+8 v4 = load.i32 vmctx v0+16 diff --git a/cranelift/filetests/filetests/alias/multiple-blocks.clif b/cranelift/filetests/filetests/alias/multiple-blocks.clif index 4ce7488b0a31..458e8f00fa07 100644 --- a/cranelift/filetests/filetests/alias/multiple-blocks.clif +++ b/cranelift/filetests/filetests/alias/multiple-blocks.clif @@ -7,11 +7,9 @@ target aarch64 function %f0(i64 vmctx, i32) -> i32 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 - block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 12, 0 + v2 = global_value.i64 gv1 v3 = load.i32 v2+8 brz v2, block1 jump block2 diff --git a/cranelift/filetests/filetests/alias/partial-redundancy.clif b/cranelift/filetests/filetests/alias/partial-redundancy.clif index 3c2926ed617b..85177ab39f90 100644 --- a/cranelift/filetests/filetests/alias/partial-redundancy.clif +++ b/cranelift/filetests/filetests/alias/partial-redundancy.clif @@ -8,7 +8,6 @@ target aarch64 function %f0(i64 vmctx, i32) -> i32, i32 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 fn0 = %g(i64 vmctx) block0(v0: i64, v1: i32): @@ -16,17 +15,17 @@ block0(v0: i64, v1: i32): jump block2 block1: - v2 = heap_addr.i64 heap0, v1, 68, 0 + v2 = global_value.i64 gv1 v3 = load.i32 v2+64 jump block3(v3) block2: - v4 = heap_addr.i64 heap0, v1, 132, 0 + v4 = global_value.i64 gv1 v5 = load.i32 v4+128 jump block3(v5) block3(v6: i32): - v7 = heap_addr.i64 heap0, v1, 68, 0 + v7 = global_value.i64 gv1 v8 = load.i32 v7+64 ;; load should survive: ; check: v8 = load.i32 v7+64 diff --git a/cranelift/filetests/filetests/alias/simple-alias.clif b/cranelift/filetests/filetests/alias/simple-alias.clif index f1109c8379e8..ba3722bdf7d5 100644 --- a/cranelift/filetests/filetests/alias/simple-alias.clif +++ b/cranelift/filetests/filetests/alias/simple-alias.clif @@ -9,14 +9,13 @@ target aarch64 function %f0(i64 vmctx, i32) -> i32, i32, i32, i32 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 fn0 = %g(i64 vmctx) block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 12, 0 + v2 = global_value.i64 gv1 v3 = load.i32 v2+8 ;; This should reuse the load above. - v4 = heap_addr.i64 heap0, v1, 12, 0 + v4 = global_value.i64 gv1 v5 = load.i32 v4+8 ; check: v5 -> v3 @@ -38,15 +37,14 @@ block0(v0: i64, v1: i32): function %f1(i64 vmctx, i32) -> i32 { gv0 = vmctx gv1 = load.i64 notrap readonly aligned gv0+8 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 fn0 = %g(i64 vmctx) block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 12, 0 + v2 = global_value.i64 gv1 store.i32 v1, v2+8 ;; This load should pick up the store above. - v3 = heap_addr.i64 heap0, v1, 12, 0 + v3 = global_value.i64 gv1 v4 = load.i32 v3+8 ; check: v4 -> v1 diff --git a/cranelift/filetests/filetests/isa/aarch64/heap_addr.clif b/cranelift/filetests/filetests/isa/aarch64/heap_addr.clif deleted file mode 100644 index 5cfdd522a64c..000000000000 --- a/cranelift/filetests/filetests/isa/aarch64/heap_addr.clif +++ /dev/null @@ -1,88 +0,0 @@ -test compile precise-output -set unwind_info=false -set enable_heap_access_spectre_mitigation=true -target aarch64 - -function %dynamic_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; mov w8, w1 -; ldr x9, [x0] -; mov x9, x9 -; add x10, x0, x1, UXTW -; movz x7, #0 -; subs xzr, x8, x9 -; csel x0, x7, x10, hi -; csdb -; ret - -function %static_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; mov w6, w1 -; add x7, x0, x1, UXTW -; movz x5, #0 -; subs xzr, x6, #65536 -; csel x0, x5, x7, hi -; csdb -; ret - -function %dynamic_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; mov w10, w1 -; movz x9, #24 -; adds x11, x10, x9 -; b.lo 8 ; udf -; ldr x12, [x0] -; add x13, x0, x1, UXTW -; add x13, x13, #16 -; movz x10, #0 -; subs xzr, x11, x12 -; csel x0, x10, x13, hi -; csdb -; ret - -function %static_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; mov w8, w1 -; add x9, x0, x1, UXTW -; add x9, x9, #16 -; movz x6, #65512 -; movz x10, #0 -; subs xzr, x8, x6 -; csel x0, x10, x9, hi -; csdb -; ret - diff --git a/cranelift/filetests/filetests/isa/riscv64/heap-addr.clif b/cranelift/filetests/filetests/isa/riscv64/heap-addr.clif deleted file mode 100644 index 360854faafd0..000000000000 --- a/cranelift/filetests/filetests/isa/riscv64/heap-addr.clif +++ /dev/null @@ -1,86 +0,0 @@ -test compile precise-output -set unwind_info=false -target riscv64 - -function %dynamic_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; uext.w a6,a1 -; ld a7,0(a0) -; addi t3,a7,0 -; add a7,a0,a6 -; ugt a5,a6,t3##ty=i64 -; li t3,0 -; selectif_spectre_guard a0,t3,a7##test=a5 -; ret - -function %static_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; uext.w a6,a1 -; add a5,a0,a6 -; lui a3,16 -; ugt a6,a6,a3##ty=i64 -; li a7,0 -; selectif_spectre_guard a0,a7,a5##test=a6 -; ret - -function %dynamic_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; uext.w t4,a1 -; li a7,24 -; add t0,t4,a7 -; ult t1,t0,t4##ty=i64 -; trap_if t1,heap_oob -; ld t1,0(a0) -; add t2,a0,t4 -; addi t2,t2,16 -; ugt t4,t0,t1##ty=i64 -; li t1,0 -; selectif_spectre_guard a0,t1,t2##test=t4 -; ret - -function %static_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; uext.w a7,a1 -; add t3,a0,a7 -; addi t3,t3,16 -; lui a5,16 -; addi a5,a5,4072 -; ugt t4,a7,a5##ty=i64 -; li t0,0 -; selectif_spectre_guard a0,t0,t3##test=t4 -; ret - diff --git a/cranelift/filetests/filetests/isa/s390x/heap_addr.clif b/cranelift/filetests/filetests/isa/s390x/heap_addr.clif deleted file mode 100644 index cafac223a37f..000000000000 --- a/cranelift/filetests/filetests/isa/s390x/heap_addr.clif +++ /dev/null @@ -1,81 +0,0 @@ -test compile precise-output -target s390x - -function %dynamic_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; llgfr %r4, %r3 -; lghi %r3, 0 -; ag %r3, 0(%r2) -; agr %r2, %r4 -; lghi %r5, 0 -; clgr %r4, %r3 -; locgrh %r2, %r5 -; br %r14 - -function %static_heap_check(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 0 - return v2 -} - -; block0: -; llgfr %r4, %r3 -; agr %r2, %r4 -; lghi %r3, 0 -; clgfi %r4, 65536 -; locgrh %r2, %r3 -; br %r14 - -function %dynamic_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; llgfr %r5, %r3 -; lghi %r4, 24 -; algfr %r4, %r3 -; jle 6 ; trap -; lg %r3, 0(%r2) -; agrk %r5, %r2, %r5 -; aghik %r2, %r5, 16 -; lghi %r5, 0 -; clgr %r4, %r3 -; locgrh %r2, %r5 -; br %r14 - -function %static_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; block0: -; llgfr %r5, %r3 -; agr %r2, %r5 -; aghi %r2, 16 -; lghi %r4, 0 -; clgfi %r5, 65512 -; locgrh %r2, %r4 -; br %r14 - diff --git a/cranelift/filetests/filetests/isa/x64/fcmp-mem-bug.clif b/cranelift/filetests/filetests/isa/x64/fcmp-mem-bug.clif index 7c72e89dee99..b38619f4d71d 100644 --- a/cranelift/filetests/filetests/isa/x64/fcmp-mem-bug.clif +++ b/cranelift/filetests/filetests/isa/x64/fcmp-mem-bug.clif @@ -7,7 +7,6 @@ function u0:11335(i64 vmctx, i64, i32, i32, i32, i32, i32, i32, i32, i32) fast { gv2 = load.i64 notrap aligned gv1 gv3 = vmctx gv4 = load.i64 notrap aligned readonly gv3+504 - heap0 = static gv4, min 0, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32 sig0 = (i64 vmctx, i64, i32, i32, i32) -> i32 fast sig1 = (i64 vmctx, i64, i32, i32, i32) -> i32 fast sig2 = (i64 vmctx, i64, i32, i32, i32, i32, i32, i32, i32, i32) fast diff --git a/cranelift/filetests/filetests/isa/x64/heap-no-spectre.clif b/cranelift/filetests/filetests/isa/x64/heap-no-spectre.clif deleted file mode 100644 index a0bc223a91d4..000000000000 --- a/cranelift/filetests/filetests/isa/x64/heap-no-spectre.clif +++ /dev/null @@ -1,86 +0,0 @@ -test compile precise-output -set enable_heap_access_spectre_mitigation=false -target x86_64 - -;; Calculate a heap address on a dynamically-allocated memory with Spectre -;; mitigations disabled. This is a 7-instruction sequence with loads, ignoring -;; intermediate `mov`s. -function %f(i32, i64 vmctx) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+8 - heap0 = dynamic gv1, bound gv2, offset_guard 0x1000, index_type i32 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0x8000, 0 - return v2 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %edi, %eax -; movq %rax, %r10 -; addq %r10, $32768, %r10 -; jnb ; ud2 heap_oob ; -; movq 8(%rsi), %r11 -; cmpq %r11, %r10 -; jbe label1; j label2 -; block1: -; addq %rax, 0(%rsi), %rax -; addq %rax, $32768, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; block2: -; ud2 heap_oob - -;; For a static memory with no Spectre mitigations, we observe a smaller amount -;; of bounds checking: the offset check (`cmp + jbe + j`) and the offset -;; calculation (`add`)--4 instructions. -function %f(i64 vmctx, i32) -> i64 system_v { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, bound 0x1000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v10 = heap_addr.i64 heap0, v1, 0, 0 - return v10 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %eax -; cmpq $4096, %rax -; jbe label1; j label2 -; block1: -; addq %rax, 0(%rdi), %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; block2: -; ud2 heap_oob - -;; For a static memory with no Spectre mitigations and the "right" size (4GB -;; memory, 2GB guard regions), Cranelift emits no bounds checking, simply -;; `add`--a single instruction. -function %f(i64 vmctx, i32) -> i64 system_v { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 - -block0(v0: i64, v1: i32): - v10 = heap_addr.i64 heap0, v1, 0, 0 - return v10 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %eax -; addq %rax, 0(%rdi), %rax -; movq %rbp, %rsp -; popq %rbp -; ret - diff --git a/cranelift/filetests/filetests/isa/x64/heap.clif b/cranelift/filetests/filetests/isa/x64/heap.clif deleted file mode 100644 index 75e32b073b78..000000000000 --- a/cranelift/filetests/filetests/isa/x64/heap.clif +++ /dev/null @@ -1,147 +0,0 @@ -test compile precise-output -target x86_64 - -;; Calculate a heap address on a dynamically-allocated memory. Because the -;; Spectre mitigations are on by default (i.e., -;; `set enable_heap_access_spectre_mitigation=true`), this code not only does -;; the dynamic bounds check (`add + jnb + cmp + jbe + j`) but also re-compares -;; the address to the upper bound (`add + xor + cmp + cmov`)--Cranelift's -;; Spectre mitigation. With loads and ignoring intermediate `mov`s, this amounts -;; to a 10-instruction sequence. -;; -;; And it uses quite a few registers; see this breakdown of what each register -;; generally contains: -;; - %rax holds the passed-in heap offset (argument #1) and ends up holding the -;; final address -;; - %rcx also holds the passed-in heap offset; checked for overflow when added -;; to the `0x8000` immediate -;; - %rsi holds the VM context pointer (argument #2) -;; - %rdi holds the heap limit (computed from argument #2) -;; - %rdx holds the null pointer -function %f(i32, i64 vmctx) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+8 - heap0 = dynamic gv1, bound gv2, offset_guard 0x1000, index_type i32 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0x8000, 0 - return v2 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %edi, %eax -; movq %rax, %rdi -; addq %rdi, $32768, %rdi -; jnb ; ud2 heap_oob ; -; movq 8(%rsi), %rcx -; addq %rax, 0(%rsi), %rax -; addq %rax, $32768, %rax -; xorq %rsi, %rsi, %rsi -; cmpq %rcx, %rdi -; cmovnbeq %rsi, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret - -;; The heap address calculation for this statically-allocated memory checks that -;; the passed offset (%r11) is within bounds (`cmp + jbe + j`) and then includes -;; the same Spectre mitigation as above. This results in a 7-instruction -;; sequence (ignoring `mov`s). -function %f(i64 vmctx, i32) -> i64 system_v { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, bound 0x1000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v10 = heap_addr.i64 heap0, v1, 0, 0 - return v10 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %r9d -; movq %r9, %rax -; addq %rax, 0(%rdi), %rax -; xorq %r8, %r8, %r8 -; cmpq $4096, %r9 -; cmovnbeq %r8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret - -;; When a static memory is the "right" size (4GB memory, 2GB guard regions), the -;; Spectre mitigation is not present. Cranelift relies on the memory permissions -;; and emits no bounds checking, simply `add`--a single instruction. -function %f(i64 vmctx, i32) -> i64 system_v { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 - -block0(v0: i64, v1: i32): - v10 = heap_addr.i64 heap0, v1, 0, 0 - return v10 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %eax -; addq %rax, 0(%rdi), %rax -; movq %rbp, %rsp -; popq %rbp -; ret - -function %dynamic_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %esi -; movq %rsi, %r11 -; addq %r11, $24, %r11 -; jnb ; ud2 heap_oob ; -; movq %rdi, %rax -; addq %rax, %rsi, %rax -; addq %rax, $16, %rax -; xorq %rsi, %rsi, %rsi -; cmpq 0(%rdi), %r11 -; cmovnbeq %rsi, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret - -function %static_heap_check_with_offset(i64 vmctx, i32) -> i64 { - gv0 = vmctx - heap0 = static gv0, bound 0x1_0000, offset_guard 0x1000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 16, 8 - return v2 -} - -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl %esi, %r10d -; movq %rdi, %rax -; addq %rax, %r10, %rax -; addq %rax, $16, %rax -; xorq %r9, %r9, %r9 -; cmpq $65512, %r10 -; cmovnbeq %r9, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret - diff --git a/cranelift/filetests/filetests/legalizer/bounds-checks.clif b/cranelift/filetests/filetests/legalizer/bounds-checks.clif deleted file mode 100644 index 8e6f9c8e2010..000000000000 --- a/cranelift/filetests/filetests/legalizer/bounds-checks.clif +++ /dev/null @@ -1,33 +0,0 @@ -test legalizer -set enable_heap_access_spectre_mitigation=true -target aarch64 -target x86_64 - -;; Test that when both (1) dynamic memories and (2) heap access spectre -;; mitigations are enabled, we deduplicate the bounds check between the two. - -function %wasm_load(i64 vmctx, i32) -> i32 wasmtime_system_v { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+88 - gv2 = load.i64 notrap aligned gv0+80 - heap0 = dynamic gv2, min 0, bound gv1, offset_guard 0x8000_0000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 4 - v3 = load.i32 little heap v2 - return v3 -} - -; check: block0(v0: i64, v1: i32): -; nextln: v4 = uextend.i64 v1 -; nextln: v5 = iconst.i64 4 -; nextln: v6 = uadd_overflow_trap v4, v5, heap_oob ; v5 = 4 -; nextln: v7 = load.i64 notrap aligned v0+88 -; nextln: v8 = load.i64 notrap aligned v0+80 -; nextln: v9 = iadd v8, v4 -; nextln: v10 = iconst.i64 0 -; nextln: v11 = icmp ugt v6, v7 -; nextln: v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 -; nextln: v2 -> v12 -; nextln: v3 = load.i32 little heap v2 -; nextln: return v3 diff --git a/cranelift/filetests/filetests/legalizer/static-heap-with-guard-pages.clif b/cranelift/filetests/filetests/legalizer/static-heap-with-guard-pages.clif deleted file mode 100644 index 4ef284b3e975..000000000000 --- a/cranelift/filetests/filetests/legalizer/static-heap-with-guard-pages.clif +++ /dev/null @@ -1,22 +0,0 @@ -test legalizer -set enable_heap_access_spectre_mitigation=true -target x86_64 - -;; The offset guard is large enough that we don't need explicit bounds checks. - -function %test(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1000, offset_guard 0xffff_ffff, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 4 - return v2 -} - -; check: block0(v0: i64, v1: i32): -; nextln: v3 = uextend.i64 v1 -; nextln: v4 = load.i64 notrap aligned v0 -; nextln: v5 = iadd v4, v3 -; nextln: v2 -> v5 -; nextln: return v2 diff --git a/cranelift/filetests/filetests/legalizer/static-heap-without-guard-pages.clif b/cranelift/filetests/filetests/legalizer/static-heap-without-guard-pages.clif deleted file mode 100644 index d5fff83f6793..000000000000 --- a/cranelift/filetests/filetests/legalizer/static-heap-without-guard-pages.clif +++ /dev/null @@ -1,28 +0,0 @@ -test legalizer -set enable_heap_access_spectre_mitigation=true -target x86_64 - -;; The offset guard is not large enough to avoid explicit bounds checks. -;; Additionally, the explicit bounds check gets deduped with the Spectre -;; mitigation. - -function %test(i64 vmctx, i32) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1000, offset_guard 0xffff_0000, index_type i32 - -block0(v0: i64, v1: i32): - v2 = heap_addr.i64 heap0, v1, 0, 4 - return v2 -} - -; check: block0(v0: i64, v1: i32): -; nextln: v3 = uextend.i64 v1 -; nextln: v4 = iconst.i64 4092 -; nextln: v5 = load.i64 notrap aligned v0 -; nextln: v6 = iadd v5, v3 -; nextln: v7 = iconst.i64 0 -; nextln: v8 = icmp ugt v3, v4 ; v4 = 4092 -; nextln: v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 -; nextln: v2 -> v9 -; nextln: return v2 diff --git a/cranelift/filetests/filetests/licm/load_readonly_notrap.clif b/cranelift/filetests/filetests/licm/load_readonly_notrap.clif index 27b72cfda922..a244cd6b27e5 100644 --- a/cranelift/filetests/filetests/licm/load_readonly_notrap.clif +++ b/cranelift/filetests/filetests/licm/load_readonly_notrap.clif @@ -9,14 +9,13 @@ target x86_64 function %hoist_load(i32, i64 vmctx) -> i32 { gv0 = vmctx gv1 = load.i64 notrap aligned readonly gv0 - heap0 = static gv1, min 0x1_0000, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i32, v1: i64): jump block1(v0, v1) block1(v2: i32, v3: i64): v4 = iconst.i32 1 - v5 = heap_addr.i64 heap0, v4, 0, 4 + v5 = global_value.i64 gv1 v6 = load.i32 notrap aligned readonly v5 v7 = iadd v2, v6 brz v2, block3(v2) @@ -33,11 +32,10 @@ block3(v9: i32): ; sameln: function %hoist_load(i32, i64 vmctx) -> i32 fast { ; nextln: gv0 = vmctx ; nextln: gv1 = load.i64 notrap aligned readonly gv0 -; nextln: heap0 = static gv1, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32 ; nextln: ; nextln: block0(v0: i32, v1: i64): ; nextln: v4 = iconst.i32 1 -; nextln: v5 = heap_addr.i64 heap0, v4, 0, 4 +; nextln: v5 = global_value.i64 gv1 ; nextln: v6 = load.i32 notrap aligned readonly v5 ; nextln: jump block1(v0, v1) ; nextln: diff --git a/cranelift/filetests/filetests/licm/reject_load_notrap.clif b/cranelift/filetests/filetests/licm/reject_load_notrap.clif index 3ca5b1c5df8d..c1f52dac2854 100644 --- a/cranelift/filetests/filetests/licm/reject_load_notrap.clif +++ b/cranelift/filetests/filetests/licm/reject_load_notrap.clif @@ -10,11 +10,10 @@ target x86_64 function %hoist_load(i32, i64 vmctx) -> i32 { gv0 = vmctx gv1 = load.i64 notrap aligned readonly gv0 - heap0 = static gv1, min 0x1_0000, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i32, v1: i64): v4 = iconst.i32 1 - v5 = heap_addr.i64 heap0, v4, 0, 4 + v5 = global_value.i64 gv1 jump block1(v0, v1) block1(v2: i32, v3: i64): @@ -34,11 +33,10 @@ block3(v9: i32): ; sameln: function %hoist_load(i32, i64 vmctx) -> i32 fast { ; nextln: gv0 = vmctx ; nextln: gv1 = load.i64 notrap aligned readonly gv0 -; nextln: heap0 = static gv1, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32 ; nextln: ; nextln: block0(v0: i32, v1: i64): ; nextln: v4 = iconst.i32 1 -; nextln: v5 = heap_addr.i64 heap0, v4, 0, 4 ; v4 = 1 +; nextln: v5 = global_value.i64 gv1 ; nextln: jump block1(v0, v1) ; nextln: ; nextln: block1(v2: i32, v3: i64): diff --git a/cranelift/filetests/filetests/licm/reject_load_readonly.clif b/cranelift/filetests/filetests/licm/reject_load_readonly.clif index a180847cd779..bc9030862648 100644 --- a/cranelift/filetests/filetests/licm/reject_load_readonly.clif +++ b/cranelift/filetests/filetests/licm/reject_load_readonly.clif @@ -10,14 +10,13 @@ target x86_64 function %hoist_load(i32, i64 vmctx) -> i32 { gv0 = vmctx gv1 = load.i64 notrap aligned readonly gv0 - heap0 = static gv1, min 0x1_0000, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i32, v1: i64): jump block1(v0, v1) block1(v2: i32, v3: i64): v4 = iconst.i32 1 - v5 = heap_addr.i64 heap0, v4, 0, 4 + v5 = global_value.i64 gv1 v6 = load.i32 aligned readonly v5 v7 = iadd v2, v6 brz v2, block3(v2) @@ -34,11 +33,10 @@ block3(v9: i32): ; sameln: function %hoist_load(i32, i64 vmctx) -> i32 fast { ; nextln: gv0 = vmctx ; nextln: gv1 = load.i64 notrap aligned readonly gv0 -; nextln: heap0 = static gv1, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32 ; nextln: ; nextln: block0(v0: i32, v1: i64): ; nextln: v4 = iconst.i32 1 -; nextln: v5 = heap_addr.i64 heap0, v4, 0, 4 +; nextln: v5 = global_value.i64 gv1 ; nextln: jump block1(v0, v1) ; nextln: ; nextln: block1(v2: i32, v3: i64): diff --git a/cranelift/filetests/filetests/parser/memory.clif b/cranelift/filetests/filetests/parser/memory.clif index 31f8589bea8f..7ef85c07f6f5 100644 --- a/cranelift/filetests/filetests/parser/memory.clif +++ b/cranelift/filetests/filetests/parser/memory.clif @@ -49,34 +49,3 @@ block0: v2 = bxor v0, v1 return v2 } - -; Declare static heaps. -function %sheap(i32, i64 vmctx) -> i64 { - heap1 = static gv5, min 0x1_0000, bound 0x1_0000_0000, offset_guard 0x8000_0000 - heap2 = static gv5, offset_guard 0x1000, bound 0x1_0000 - gv4 = vmctx - gv5 = iadd_imm.i64 gv4, 64 - - ; check: heap1 = static gv5, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - ; check: heap2 = static gv5, min 0, bound 0x0001_0000, offset_guard 4096 -block0(v1: i32, v2: i64): - v3 = heap_addr.i64 heap1, v1, 0, 0 - ; check: v3 = heap_addr.i64 heap1, v1, 0, 0 - return v3 -} - -; Declare dynamic heaps. -function %dheap(i32, i64 vmctx) -> i64 { - heap1 = dynamic gv5, min 0x1_0000, bound gv6, offset_guard 0x8000_0000 - heap2 = dynamic gv5, bound gv6, offset_guard 0x1000 - gv4 = vmctx - gv5 = iadd_imm.i64 gv4, 64 - gv6 = iadd_imm.i64 gv4, 72 - - ; check: heap1 = dynamic gv5, min 0x0001_0000, bound gv6, offset_guard 0x8000_0000 - ; check: heap2 = dynamic gv5, min 0, bound gv6, offset_guard 4096 -block0(v1: i32, v2: i64): - v3 = heap_addr.i64 heap2, v1, 0, 0 - ; check: v3 = heap_addr.i64 heap2, v1, 0, 0 - return v3 -} diff --git a/cranelift/filetests/filetests/runtests/fdemote.clif b/cranelift/filetests/filetests/runtests/fdemote.clif index 7923cca5ed85..240f9978f475 100644 --- a/cranelift/filetests/filetests/runtests/fdemote.clif +++ b/cranelift/filetests/filetests/runtests/fdemote.clif @@ -71,19 +71,16 @@ block0(v0: f64): ;; Tests a fdemote+load combo which some backends may optimize -function %fdemote_load(i64 vmctx, i64, f64) -> f32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x10, bound 0x10, offset_guard 0x0, index_type i64 +function %fdemote_load(i64, f64) -> f32 { + ss0 = explicit_slot 16 -block0(v0: i64, v1: i64, v2: f64): - v3 = heap_addr.i64 heap0, v1, 0, 8 +block0(v1: i64, v2: f64): + v3 = stack_addr.i64 ss0 store.f64 v2, v3 v4 = load.f64 v3 v5 = fdemote.f32 v4 return v5 } -; heap: static, size=0x10, ptr=vmctx+0, bound=vmctx+8 ; run: %fdemote_load(0, 0x0.0) == 0x0.0 ; run: %fdemote_load(1, 0x0.1) == 0x0.1 ; run: %fdemote_load(2, 0x0.2) == 0x0.2 diff --git a/cranelift/filetests/filetests/runtests/fpromote.clif b/cranelift/filetests/filetests/runtests/fpromote.clif index 7a6170e1c8f2..941cb733e0d7 100644 --- a/cranelift/filetests/filetests/runtests/fpromote.clif +++ b/cranelift/filetests/filetests/runtests/fpromote.clif @@ -79,20 +79,16 @@ block0(v0: f32): ;; Tests a fpromote+load combo which some backends may optimize -function %fpromote_load(i64 vmctx, i64, f32) -> f64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x10, bound 0x10, offset_guard 0x0, index_type i64 +function %fpromote_load(i64, f32) -> f64 { + ss0 = explicit_slot 16 -block0(v0: i64, v1: i64, v2: f32): - v3 = heap_addr.i64 heap0, v1, 0, 4 +block0(v1: i64, v2: f32): + v3 = stack_addr.i64 ss0 store.f32 v2, v3 v4 = load.f32 v3 v5 = fpromote.f64 v4 return v5 } - -; heap: static, size=0x10, ptr=vmctx+0, bound=vmctx+8 ; run: %fpromote_load(0, 0x0.0) == 0x0.0 ; run: %fpromote_load(1, 0x0.1) == 0x0.1 ; run: %fpromote_load(2, 0x0.2) == 0x0.2 diff --git a/cranelift/filetests/filetests/runtests/global_value.clif b/cranelift/filetests/filetests/runtests/global_value.clif deleted file mode 100644 index e8caf14805f6..000000000000 --- a/cranelift/filetests/filetests/runtests/global_value.clif +++ /dev/null @@ -1,24 +0,0 @@ -test interpret -test run -target x86_64 -target s390x -target aarch64 -target riscv64 - -; Store a value in the heap using `heap_addr` and load it using `global_value` -function %store_load(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 0 - store.i32 v2, v3 - - v4 = global_value.i64 gv1 - v5 = load.i32 v4 - return v5 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %store_load(0, 1) == 1 -; run: %store_load(0, -1) == -1 diff --git a/cranelift/filetests/filetests/runtests/heap.clif b/cranelift/filetests/filetests/runtests/heap.clif deleted file mode 100644 index 3e7bd41649ac..000000000000 --- a/cranelift/filetests/filetests/runtests/heap.clif +++ /dev/null @@ -1,223 +0,0 @@ -test interpret -test run -target x86_64 -target s390x -target aarch64 -target riscv64 - -function %static_heap_i64(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i64(0, 1) == 1 -; run: %static_heap_i64(0, -1) == -1 -; run: %static_heap_i64(16, 1) == 1 -; run: %static_heap_i64(16, -1) == -1 - - -function %static_heap_i32(i64 vmctx, i32, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i32 - -block0(v0: i64, v1: i32, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i32(0, 1) == 1 -; run: %static_heap_i32(0, -1) == -1 -; run: %static_heap_i32(16, 1) == 1 -; run: %static_heap_i32(16, -1) == -1 - - -function %heap_no_min(i64 vmctx, i32, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, bound 0x1_0000_0000, offset_guard 0, index_type i32 - -block0(v0: i64, v1: i32, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %heap_no_min(0, 1) == 1 -; run: %heap_no_min(0, -1) == -1 -; run: %heap_no_min(16, 1) == 1 -; run: %heap_no_min(16, -1) == -1 - - -function %dynamic_i64(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+8 - heap0 = dynamic gv1, bound gv2, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: dynamic, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %dynamic_i64(0, 1) == 1 -; run: %dynamic_i64(0, -1) == -1 -; run: %dynamic_i64(16, 1) == 1 -; run: %dynamic_i64(16, -1) == -1 - - -function %dynamic_i32(i64 vmctx, i32, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+8 - heap0 = dynamic gv1, bound gv2, offset_guard 0, index_type i32 - -block0(v0: i64, v1: i32, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: dynamic, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %dynamic_i32(0, 1) == 1 -; run: %dynamic_i32(0, -1) == -1 -; run: %dynamic_i32(16, 1) == 1 -; run: %dynamic_i32(16, -1) == -1 - - -function %multi_load_store(i64 vmctx, i32, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+16 - gv3 = load.i64 notrap aligned gv0+24 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - heap1 = dynamic gv2, bound gv3, offset_guard 0, index_type i32 - -block0(v0: i64, v1: i32, v2: i32): - v3 = iconst.i64 0 - v4 = iconst.i32 0 - - ; Store lhs in heap0 - v5 = heap_addr.i64 heap0, v3, 0, 4 - store.i32 v1, v5 - - ; Store rhs in heap1 - v6 = heap_addr.i64 heap1, v4, 0, 4 - store.i32 v2, v6 - - - v7 = load.i32 v5 - v8 = load.i32 v6 - - v9 = iadd.i32 v7, v8 - return v9 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; heap: dynamic, size=0x1000, ptr=vmctx+16, bound=vmctx+24 -; run: %multi_load_store(1, 2) == 3 -; run: %multi_load_store(4, 5) == 9 - - - -; Uses multiple heaps, but heap0 refers to the second heap, and heap1 refers to the first heap -; This is a regression test for the interpreter -function %out_of_order(i64 vmctx, i32, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - gv2 = load.i64 notrap aligned gv0+16 - gv3 = load.i64 notrap aligned gv0+24 - heap0 = dynamic gv2, bound gv3, offset_guard 0, index_type i32 - heap1 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i32, v2: i32): - v3 = iconst.i32 0 - v4 = iconst.i64 0 - - ; Store lhs in heap0 - v5 = heap_addr.i64 heap0, v3, 0, 4 - store.i32 v1, v5 - - ; Store rhs in heap1 - v6 = heap_addr.i64 heap1, v4, 0, 4 - store.i32 v2, v6 - - - v7 = load.i32 v5 - v8 = load.i32 v6 - - v9 = iadd.i32 v7, v8 - return v9 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; heap: dynamic, size=0x1000, ptr=vmctx+16, bound=vmctx+24 -; run: %out_of_order(1, 2) == 3 -; run: %out_of_order(4, 5) == 9 - - -function %unaligned_access(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %unaligned_access(0, 1) == 1 -; run: %unaligned_access(0, -1) == -1 -; run: %unaligned_access(1, 1) == 1 -; run: %unaligned_access(1, -1) == -1 -; run: %unaligned_access(2, 1) == 1 -; run: %unaligned_access(2, -1) == -1 -; run: %unaligned_access(3, 1) == 1 -; run: %unaligned_access(3, -1) == -1 - - -; This stores data in the place of the pointer in the vmctx struct, not in the heap itself. -function %iadd_imm(i64 vmctx, i32) -> i32 { - gv0 = vmctx - gv1 = iadd_imm.i64 gv0, 0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i64 - -block0(v0: i64, v1: i32): - v2 = iconst.i64 0 - v3 = heap_addr.i64 heap0, v2, 0, 4 - store.i32 v1, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %iadd_imm(1) == 1 -; run: %iadd_imm(-1) == -1 - -function %heap_limit_i64(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0, bound 0x8, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x8, ptr=vmctx+0, bound=vmctx+8 -; run: %heap_limit_i64(0, 1) == 1 -; run: %heap_limit_i64(0, -1) == -1 -; run: %heap_limit_i64(4, 1) == 1 -; run: %heap_limit_i64(4, -1) == -1 diff --git a/cranelift/filetests/filetests/runtests/load-op-store.clif b/cranelift/filetests/filetests/runtests/load-op-store.clif deleted file mode 100644 index d2dfb12a4130..000000000000 --- a/cranelift/filetests/filetests/runtests/load-op-store.clif +++ /dev/null @@ -1,98 +0,0 @@ -test run -target x86_64 -target s390x -target aarch64 -target riscv64 - - -function %load_op_store_iadd_i64(i64 vmctx, i64, i64) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 8 - v4 = iconst.i64 42 - store.i64 v4, v3 - v5 = load.i64 v3 - v6 = iadd.i64 v5, v2 - store.i64 v6, v3 - v7 = load.i64 v3 - return v7 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i64_load_store(0, 1) == 43 -; run: %static_heap_i64_load_store(0, -1) == 41 - -function %load_op_store_iadd_i32(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - v3 = heap_addr.i64 heap0, v1, 0, 4 - v4 = iconst.i32 42 - store.i32 v4, v3 - v5 = load.i32 v3 - v6 = iadd.i32 v5, v2 - store.i32 v6, v3 - v7 = load.i32 v3 - return v7 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i64_load_store(0, 1) == 43 -; run: %static_heap_i64_load_store(0, -1) == 41 - -function %load_op_store_iadd_i8(i64 vmctx, i64, i8) -> i8 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i8): - v3 = heap_addr.i64 heap0, v1, 0, 4 - v4 = iconst.i8 42 - store.i8 v4, v3 - v5 = load.i8 v3 - v6 = iadd.i8 v5, v2 - store.i8 v6, v3 - v7 = load.i8 v3 - return v7 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i64_load_store(0, 1) == 43 -; run: %static_heap_i64_load_store(0, -1) == 41 - -function %load_op_store_iadd_isub_iand_ior_ixor_i64(i64 vmctx, i64, i64) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 8 - store.i64 v2, v3 - v4 = load.i64 v3 - v5 = iconst.i64 1 - v6 = iadd.i64 v5, v4 - store.i64 v6, v3 - v7 = load.i64 v3 - v8 = iconst.i64 2 - v9 = load.i64 v3 - v10 = isub.i64 v9, v8 - store.i64 v10, v3 - v11 = load.i64 v3 - v12 = iconst.i64 0xf - v13 = band.i64 v12, v11 - store.i64 v13, v3 - v14 = iconst.i64 0x10 - v15 = load.i64 v3 - v16 = bor.i64 v15, v14 - store.i64 v16, v3 - v17 = load.i64 v3 - v18 = iconst.i64 0xff - v19 = bxor.i64 v17, v18 - store.i64 v19, v3 - v20 = load.i64 v3 - return v20 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %static_heap_i64_load_store(0, 0x1234) == 236 diff --git a/cranelift/filetests/filetests/runtests/simd-fvdemote.clif b/cranelift/filetests/filetests/runtests/simd-fvdemote.clif deleted file mode 100644 index 558a3461611b..000000000000 --- a/cranelift/filetests/filetests/runtests/simd-fvdemote.clif +++ /dev/null @@ -1,25 +0,0 @@ -test interpret -test run -target x86_64 -target s390x -target aarch64 - -function %fvdemote_test(i64 vmctx, i64, f64x2) -> f32x4 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x20, bound 0x20, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: f64x2): - v3 = heap_addr.i64 heap0, v1, 0, 16 - store.f64x2 v2, v3 - v4 = load.f64x2 v3 - v5 = fvdemote v4 - return v5 -} - -; heap: static, size=0x20, ptr=vmctx+0, bound=vmctx+8 -; run: %fvdemote_test(0, [0x0.0 0x0.0]) == [0x0.0 0x0.0 0x0.0 0x0.0] -; run: %fvdemote_test(1, [0x0.1 0x0.2]) == [0x0.1 0x0.2 0x0.0 0x0.0] -; run: %fvdemote_test(2, [0x2.1 0x1.2]) == [0x2.1 0x1.2 0x0.0 0x0.0] -; run: %fvdemote_test(8, [0x2.1 0x1.2]) == [0x2.1 0x1.2 0x0.0 0x0.0] -; run: %fvdemote_test(16, [0x2.1 0x1.2]) == [0x2.1 0x1.2 0x0.0 0x0.0] diff --git a/cranelift/filetests/filetests/runtests/simd-fvpromote_low.clif b/cranelift/filetests/filetests/runtests/simd-fvpromote_low.clif deleted file mode 100644 index 79dd27949215..000000000000 --- a/cranelift/filetests/filetests/runtests/simd-fvpromote_low.clif +++ /dev/null @@ -1,26 +0,0 @@ -test interpret -test run -target x86_64 -target s390x -target aarch64 - - -function %fvpromote_low_test(i64 vmctx, i64, f32x4) -> f64x2 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - heap0 = static gv1, min 0x20, bound 0x20, offset_guard 0, index_type i64 - -block0(v0: i64, v1: i64, v2: f32x4): - v3 = heap_addr.i64 heap0, v1, 0, 16 - store.f32x4 v2, v3 - v4 = load.f32x4 v3 - v5 = fvpromote_low v4 - return v5 -} - -; heap: static, size=0x20, ptr=vmctx+0, bound=vmctx+8 -; run: %fvpromote_low_test(0, [0x0.0 0x0.0 0x0.0 0x0.0]) == [0x0.0 0x0.0] -; run: %fvpromote_low_test(1, [0x0.1 0x0.2 0x0.0 0x0.0]) == [0x0.1 0x0.2] -; run: %fvpromote_low_test(2, [0x2.1 0x1.2 0x0.0 0x0.0]) == [0x2.1 0x1.2] -; run: %fvpromote_low_test(5, [0x0.0 0x0.0 0x2.1 0x1.2]) == [0x0.0 0x0.0] -; run: %fvpromote_low_test(16, [0x0.0 0x0.0 0x2.1 0x1.2]) == [0x0.0 0x0.0] diff --git a/cranelift/filetests/filetests/runtests/table_addr.clif b/cranelift/filetests/filetests/runtests/table_addr.clif deleted file mode 100644 index 186dcb1a89c0..000000000000 --- a/cranelift/filetests/filetests/runtests/table_addr.clif +++ /dev/null @@ -1,144 +0,0 @@ -test interpret -test run -target x86_64 -target s390x -target aarch64 -target riscv64 - -function %set_get_i64(i64 vmctx, i64, i64) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - table0 = dynamic gv1, element_size 8, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i64): - v3 = table_addr.i64 table0, v1, +0 - store.i64 v2, v3 - v4 = load.i64 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %set_get_i64(0, 1) == 1 -; run: %set_get_i64(0, 10) == 10 -; run: %set_get_i64(1, 1) == 1 -; run: %set_get_i64(1, 0xC0FFEEEE_DECAFFFF) == 0xC0FFEEEE_DECAFFFF -; run: %set_get_i64(10, 1) == 1 -; run: %set_get_i64(10, 0xC0FFEEEE_DECAFFFF) == 0xC0FFEEEE_DECAFFFF - - -function %set_get_i32(i64 vmctx, i64, i32) -> i32 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - table0 = dynamic gv1, element_size 8, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i32): - ;; Note here the offset +4 - v3 = table_addr.i64 table0, v1, +4 - store.i32 v2, v3 - v4 = load.i32 v3 - return v4 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %set_get_i32(0, 1) == 1 -; run: %set_get_i32(0, 10) == 10 -; run: %set_get_i32(1, 1) == 1 -; run: %set_get_i32(1, 0xC0FFEEEE) == 0xC0FFEEEE -; run: %set_get_i32(10, 1) == 1 -; run: %set_get_i32(10, 0xC0FFEEEE) == 0xC0FFEEEE - - -function %set_get_i8(i64 vmctx, i64, i8) -> i8 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - table0 = dynamic gv1, element_size 1, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i8): - v3 = table_addr.i64 table0, v1, +0 - store.i8 v2, v3 - v4 = load.i8 v3 - return v4 -} -; heap: static, size=2, ptr=vmctx+0, bound=vmctx+8 -; run: %set_get_i8(0, 1) == 1 -; run: %set_get_i8(0, 0xC0) == 0xC0 -; run: %set_get_i8(1, 1) == 1 -; run: %set_get_i8(1, 0xFF) == 0xFF - - - -function %large_elm_size(i64 vmctx, i64, i64, i8) -> i8 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - table0 = dynamic gv1, element_size 10240, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i64, v3: i8): - v4 = table_addr.i64 table0, v1, +0 - v5 = iadd.i64 v4, v2 - store.i8 v3, v5 - v6 = load.i8 v5 - return v6 -} -; heap: static, size=0xC800, ptr=vmctx+0, bound=vmctx+8 -; run: %large_elm_size(0, 0, 1) == 1 -; run: %large_elm_size(1, 0, 0xC0) == 0xC0 -; run: %large_elm_size(0, 1, 1) == 1 -; run: %large_elm_size(1, 1, 0xFF) == 0xFF -; run: %large_elm_size(0, 127, 1) == 1 -; run: %large_elm_size(1, 127, 0xFF) == 0xFF -; run: %large_elm_size(0, 10239, 1) == 1 -; run: %large_elm_size(1, 10239, 0xBB) == 0xBB - - -; Tests writing a i64 which covers 8 table entries at once -; Loads the first byte and the last to confirm that the slots were written -function %multi_elm_write(i64 vmctx, i64, i64) -> i8, i8 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - table0 = dynamic gv1, element_size 1, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i64): - v3 = table_addr.i64 table0, v1, +0 - v4 = table_addr.i64 table0, v1, +7 - store.i64 v2, v3 - v5 = load.i8 v3 - v6 = load.i8 v4 - return v5, v6 -} -; heap: static, size=16, ptr=vmctx+0, bound=vmctx+8 - -;; When writing these test cases keep in mind that s390x is big endian! -;; We just make sure that the first and last byte are the same to deal with that. -; run: %multi_elm_write(0, 0xC0FFEEEE_FFEEEEC0) == [0xC0, 0xC0] -; run: %multi_elm_write(1, 0xAABBCCDD_EEFF00AA) == [0xAA, 0xAA] - - - -function %heap_table(i64 vmctx, i64, i64, i64) -> i64 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0 - gv2 = load.i64 notrap aligned gv0 +8 - heap0 = dynamic gv1, bound gv2, offset_guard 0, index_type i64 - table0 = dynamic gv1, element_size 9, bound gv2, index_type i64 - -block0(v0: i64, v1: i64, v2: i64, v3: i64): - ; v1 - heap offset (bytes) - ; v2 - table offset (elements) - ; v3 - store/load value - v4 = heap_addr.i64 heap0, v1, 0, 0 - v5 = table_addr.i64 table0, v2, +2 - - ; Store via heap, load via table - store.i64 v3, v4 - v6 = load.i64 v5 - - return v6 -} -; heap: static, size=0x1000, ptr=vmctx+0, bound=vmctx+8 -; run: %heap_table(2, 0, 0xAABBCCDD_EEFF0011) == 0xAABBCCDD_EEFF0011 -; run: %heap_table(11, 1, 0xC0FFEEEE_DECAFFFF) == 0xC0FFEEEE_DECAFFFF -; run: %heap_table(20, 2, 1) == 1 -; run: %heap_table(29, 3, -10) == -10 diff --git a/cranelift/filetests/filetests/simple_gvn/readonly.clif b/cranelift/filetests/filetests/simple_gvn/readonly.clif index b28da609a7b0..322ea275d64d 100644 --- a/cranelift/filetests/filetests/simple_gvn/readonly.clif +++ b/cranelift/filetests/filetests/simple_gvn/readonly.clif @@ -6,11 +6,10 @@ target x86_64 function %eliminate_redundant_global_loads(i32, i64 vmctx) { gv0 = vmctx gv1 = load.i64 notrap aligned readonly gv0 - heap0 = static gv1, min 0x1_0000, bound 0x1_0000_0000, offset_guard 0x8000_0000, index_type i32 block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = heap_addr.i64 heap0, v0, 0, 1 + v2 = global_value.i64 gv1 + v3 = global_value.i64 gv1 v4 = iconst.i32 0 store.i32 notrap aligned v4, v2 @@ -18,7 +17,7 @@ block0(v0: i32, v1: i64): return } -; check: v2 = heap_addr.i64 heap0, v0, 0, 1 +; check: v2 = global_value.i64 gv1 ; check: v3 -> v2 ; check: v4 = iconst.i32 0 ; check: store notrap aligned v4, v2 diff --git a/cranelift/filetests/filetests/simple_preopt/replace_branching_instructions_and_cfg_predecessors.clif b/cranelift/filetests/filetests/simple_preopt/replace_branching_instructions_and_cfg_predecessors.clif index e5adefca0015..84aa0f1d6ccc 100644 --- a/cranelift/filetests/filetests/simple_preopt/replace_branching_instructions_and_cfg_predecessors.clif +++ b/cranelift/filetests/filetests/simple_preopt/replace_branching_instructions_and_cfg_predecessors.clif @@ -3,12 +3,8 @@ target aarch64 target x86_64 function u0:2(i64 , i64) { - gv1 = load.i64 notrap aligned gv0 - heap0 = static gv1 block0(v0: i64, v1: i64): - v16 = iconst.i32 6 - v17 = heap_addr.i64 heap0, v16, 0, 1 - v18 = load.i32 v17 + v18 = load.i32 v0 v19 = iconst.i32 4 v20 = icmp ne v18, v19 v21 = uextend.i32 v20 diff --git a/cranelift/filetests/filetests/verifier/heap.clif b/cranelift/filetests/filetests/verifier/heap.clif deleted file mode 100644 index b46779e23359..000000000000 --- a/cranelift/filetests/filetests/verifier/heap.clif +++ /dev/null @@ -1,45 +0,0 @@ -test verifier -target x86_64 - -function %heap_base_type(i64 vmctx) { - gv0 = vmctx - gv1 = load.i32 notrap aligned gv0 - heap0 = static gv1, offset_guard 0x1000, bound 0x1_0000, index_type i32 ; error: heap base has type i32, which is not the pointer type i64 - -block0(v0: i64): - return -} - -function %invalid_base(i64 vmctx) { - gv0 = vmctx - heap0 = dynamic gv1, bound gv0, offset_guard 0x1000, index_type i64 ; error: invalid base global value gv1 - -block0(v0: i64): - return -} - -function %invalid_bound(i64 vmctx) { - gv0 = vmctx - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i64 ; error: invalid bound global value gv1 - -block0(v0: i64): - return -} - -function %heap_bound_type(i64 vmctx) { - gv0 = vmctx - gv1 = load.i16 notrap aligned gv0 - heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 ; error: heap pointer type i64 differs from the type of its bound, i16 - -block0(v0: i64): - return -} - -function %heap_addr_index_type(i64 vmctx, i64) { - gv0 = vmctx - heap0 = static gv0, offset_guard 0x1000, bound 0x1_0000, index_type i32 - -block0(v0: i64, v1: i64): - v2 = heap_addr.i64 heap0, v1, 0, 0; error: index type i64 differs from heap index type i32 - return -} diff --git a/cranelift/filetests/filetests/wasm/basic-wat-test.wat b/cranelift/filetests/filetests/wasm/basic-wat-test.wat index d9dd38e0ada6..f42bc37bf720 100644 --- a/cranelift/filetests/filetests/wasm/basic-wat-test.wat +++ b/cranelift/filetests/filetests/wasm/basic-wat-test.wat @@ -27,16 +27,19 @@ ;; function u0:0(i32, i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0, bound 4096, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0021 v4 = heap_addr.i64 heap0, v0, 0, 4 -;; @0021 v5 = load.i32 little heap v4 -;; @0026 v6 = heap_addr.i64 heap0, v1, 0, 4 -;; @0026 v7 = load.i32 little heap v6 -;; @0029 v8 = iadd v5, v7 -;; @002a jump block1(v8) +;; @0021 v4 = uextend.i64 v0 +;; @0021 v5 = global_value.i64 gv1 +;; @0021 v6 = iadd v5, v4 +;; @0021 v7 = load.i32 little heap v6 +;; @0026 v8 = uextend.i64 v1 +;; @0026 v9 = global_value.i64 gv1 +;; @0026 v10 = iadd v9, v8 +;; @0026 v11 = load.i32 little heap v10 +;; @0029 v12 = iadd v7, v11 +;; @002a jump block1(v12) ;; ;; block1(v3: i32): ;; @002a return v3 -;; } +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/f32-load.wat b/cranelift/filetests/filetests/wasm/f32-load.wat new file mode 100644 index 000000000000..e568cd9e2910 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/f32-load.wat @@ -0,0 +1,22 @@ +;;! target = "x86_64" + +(module + (memory 1) + (func (export "f32.load") (param i32) (result f32) + local.get 0 + f32.load)) + +;; function u0:0(i32, i64 vmctx) -> f32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @002e v3 = uextend.i64 v0 +;; @002e v4 = global_value.i64 gv1 +;; @002e v5 = iadd v4, v3 +;; @002e v6 = load.f32 little heap v5 +;; @0031 jump block1(v6) +;; +;; block1(v2: f32): +;; @0031 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/f32-memory64.clif b/cranelift/filetests/filetests/wasm/f32-memory64.clif deleted file mode 100644 index 8f6d5e44322c..000000000000 --- a/cranelift/filetests/filetests/wasm/f32-memory64.clif +++ /dev/null @@ -1,27 +0,0 @@ -; Test basic code generation for f32 memory WebAssembly instructions. -test compile - -; We only test on 64-bit since the heap_addr instructions and vmctx parameters -; explicitly mention the pointer width. -target aarch64 -target x86_64 haswell - -function %f32_load(i32, i64 vmctx) -> f32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = load.f32 v2 - return v3 -} - -function %f32_store(f32, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: f32, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - store v0, v3 - return -} diff --git a/cranelift/filetests/filetests/wasm/f32-store.wat b/cranelift/filetests/filetests/wasm/f32-store.wat new file mode 100644 index 000000000000..48526a18cfb5 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/f32-store.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for f32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "f32.store") (param i32 f32) + local.get 0 + local.get 1 + f32.store)) + +;; function u0:0(i32, f32, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: f32, v2: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 store little heap v1, v5 +;; @0034 jump block1 +;; +;; block1: +;; @0034 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/f64-load.wat b/cranelift/filetests/filetests/wasm/f64-load.wat new file mode 100644 index 000000000000..ce9cc37f569c --- /dev/null +++ b/cranelift/filetests/filetests/wasm/f64-load.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for f64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "f64.load") (param i32) (result f64) + local.get 0 + f64.load)) + +;; function u0:0(i32, i64 vmctx) -> f64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @002e v3 = uextend.i64 v0 +;; @002e v4 = global_value.i64 gv1 +;; @002e v5 = iadd v4, v3 +;; @002e v6 = load.f64 little heap v5 +;; @0031 jump block1(v6) +;; +;; block1(v2: f64): +;; @0031 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/f64-memory64.clif b/cranelift/filetests/filetests/wasm/f64-memory64.clif deleted file mode 100644 index 2805be18ef07..000000000000 --- a/cranelift/filetests/filetests/wasm/f64-memory64.clif +++ /dev/null @@ -1,27 +0,0 @@ -; Test basic code generation for f64 memory WebAssembly instructions. -test compile - -; We only test on 64-bit since the heap_addr instructions and vmctx parameters -; explicitly mention the pointer width. -target aarch64 -target x86_64 haswell - -function %f64_load(i32, i64 vmctx) -> f64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = load.f64 v2 - return v3 -} - -function %f64_store(f64, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: f64, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - store v0, v3 - return -} diff --git a/cranelift/filetests/filetests/wasm/f64-store.wat b/cranelift/filetests/filetests/wasm/f64-store.wat new file mode 100644 index 000000000000..f23e3a89b593 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/f64-store.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for f64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "f64.store") (param i32 f64) + local.get 0 + local.get 1 + f64.store)) + +;; function u0:0(i32, f64, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: f64, v2: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 store little heap v1, v5 +;; @0034 jump block1 +;; +;; block1: +;; @0034 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-load.wat b/cranelift/filetests/filetests/wasm/i32-load.wat new file mode 100644 index 000000000000..d0005d3c9894 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-load.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.load") (param i32) (result i32) + local.get 0 + i32.load)) + +;; function u0:0(i32, i64 vmctx) -> i32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @002e v3 = uextend.i64 v0 +;; @002e v4 = global_value.i64 gv1 +;; @002e v5 = iadd v4, v3 +;; @002e v6 = load.i32 little heap v5 +;; @0031 jump block1(v6) +;; +;; block1(v2: i32): +;; @0031 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-load16-s.wat b/cranelift/filetests/filetests/wasm/i32-load16-s.wat new file mode 100644 index 000000000000..a944b0615882 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-load16-s.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.load16_s") (param i32) (result i32) + local.get 0 + i32.load16_s)) + +;; function u0:0(i32, i64 vmctx) -> i32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 v6 = sload16.i32 little heap v5 +;; @0035 jump block1(v6) +;; +;; block1(v2: i32): +;; @0035 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-load16-u.wat b/cranelift/filetests/filetests/wasm/i32-load16-u.wat new file mode 100644 index 000000000000..0c2ab9fde762 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-load16-u.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.load16_u") (param i32) (result i32) + local.get 0 + i32.load16_u)) + +;; function u0:0(i32, i64 vmctx) -> i32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 v6 = uload16.i32 little heap v5 +;; @0035 jump block1(v6) +;; +;; block1(v2: i32): +;; @0035 return v2 +;; } diff --git a/cranelift/filetests/filetests/wasm/i32-load8-s.wat b/cranelift/filetests/filetests/wasm/i32-load8-s.wat new file mode 100644 index 000000000000..82802355e313 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-load8-s.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.load8_s") (param i32) (result i32) + local.get 0 + i32.load8_s)) + +;; function u0:0(i32, i64 vmctx) -> i32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 v6 = sload8.i32 little heap v5 +;; @0034 jump block1(v6) +;; +;; block1(v2: i32): +;; @0034 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-load8-u.wat b/cranelift/filetests/filetests/wasm/i32-load8-u.wat new file mode 100644 index 000000000000..1c19fe37bab8 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-load8-u.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.load8_u") (param i32) (result i32) + local.get 0 + i32.load8_u)) + +;; function u0:0(i32, i64 vmctx) -> i32 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 v6 = uload8.i32 little heap v5 +;; @0034 jump block1(v6) +;; +;; block1(v2: i32): +;; @0034 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-memory64.clif b/cranelift/filetests/filetests/wasm/i32-memory64.clif deleted file mode 100644 index f4a89f1da2f1..000000000000 --- a/cranelift/filetests/filetests/wasm/i32-memory64.clif +++ /dev/null @@ -1,87 +0,0 @@ -; Test basic code generation for i32 memory WebAssembly instructions. -test compile - -; We only test on 64-bit since the heap_addr instructions and vmctx parameters -; explicitly mention the pointer width. -target aarch64 -target x86_64 haswell - -function %i32_load(i32, i64 vmctx) -> i32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = load.i32 v2 - return v3 -} - -function %i32_store(i32, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - store v0, v3 - return -} - -function %i32_load8_s(i32, i64 vmctx) -> i32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = sload8.i32 v2 - return v3 -} - -function %i32_load8_u(i32, i64 vmctx) -> i32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = uload8.i32 v2 - return v3 -} - -function %i32_store8(i32, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - istore8 v0, v3 - return -} - -function %i32_load16_s(i32, i64 vmctx) -> i32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = sload16.i32 v2 - return v3 -} - -function %i32_load16_u(i32, i64 vmctx) -> i32 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = uload16.i32 v2 - return v3 -} - -function %i32_store16(i32, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - istore16 v0, v3 - return -} diff --git a/cranelift/filetests/filetests/wasm/i32-store.wat b/cranelift/filetests/filetests/wasm/i32-store.wat new file mode 100644 index 000000000000..5f9d77287367 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-store.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.store") (param i32 i32) + local.get 0 + local.get 1 + i32.store)) + +;; function u0:0(i32, i32, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i32, v2: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 store little heap v1, v5 +;; @0034 jump block1 +;; +;; block1: +;; @0034 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-store16.wat b/cranelift/filetests/filetests/wasm/i32-store16.wat new file mode 100644 index 000000000000..f486e34db490 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-store16.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.store16") (param i32 i32) + local.get 0 + local.get 1 + i32.store16)) + +;; function u0:0(i32, i32, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i32, v2: i64): +;; @0033 v3 = uextend.i64 v0 +;; @0033 v4 = global_value.i64 gv1 +;; @0033 v5 = iadd v4, v3 +;; @0033 istore16 little heap v1, v5 +;; @0036 jump block1 +;; +;; block1: +;; @0036 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i32-store8.wat b/cranelift/filetests/filetests/wasm/i32-store8.wat new file mode 100644 index 000000000000..eb64c0ac0529 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i32-store8.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i32.store8") (param i32 i32) + local.get 0 + local.get 1 + i32.store8)) + +;; function u0:0(i32, i32, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i32, v2: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 istore8 little heap v1, v5 +;; @0035 jump block1 +;; +;; block1: +;; @0035 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-load.wat b/cranelift/filetests/filetests/wasm/i64-load.wat new file mode 100644 index 000000000000..1fe9bc04eae7 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-load.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.load") (param i32) (result i64) + local.get 0 + i64.load)) + +;; function u0:0(i32, i64 vmctx) -> i64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @002e v3 = uextend.i64 v0 +;; @002e v4 = global_value.i64 gv1 +;; @002e v5 = iadd v4, v3 +;; @002e v6 = load.i64 little heap v5 +;; @0031 jump block1(v6) +;; +;; block1(v2: i64): +;; @0031 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-load16-s.wat b/cranelift/filetests/filetests/wasm/i64-load16-s.wat new file mode 100644 index 000000000000..d18d9b297eee --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-load16-s.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.load16_s") (param i32) (result i64) + local.get 0 + i64.load16_s)) + +;; function u0:0(i32, i64 vmctx) -> i64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 v6 = sload16.i64 little heap v5 +;; @0035 jump block1(v6) +;; +;; block1(v2: i64): +;; @0035 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-load16-u.wat b/cranelift/filetests/filetests/wasm/i64-load16-u.wat new file mode 100644 index 000000000000..358e141afc14 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-load16-u.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.load16_u") (param i32) (result i64) + local.get 0 + i64.load16_u)) + +;; function u0:0(i32, i64 vmctx) -> i64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 v6 = uload16.i64 little heap v5 +;; @0035 jump block1(v6) +;; +;; block1(v2: i64): +;; @0035 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-load8-s.wat b/cranelift/filetests/filetests/wasm/i64-load8-s.wat new file mode 100644 index 000000000000..8537e734527a --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-load8-s.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.load8_s") (param i32) (result i64) + local.get 0 + i64.load8_s)) + +;; function u0:0(i32, i64 vmctx) -> i64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 v6 = sload8.i64 little heap v5 +;; @0034 jump block1(v6) +;; +;; block1(v2: i64): +;; @0034 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-load8-u.wat b/cranelift/filetests/filetests/wasm/i64-load8-u.wat new file mode 100644 index 000000000000..c1e6297c90be --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-load8-u.wat @@ -0,0 +1,24 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.load8_u") (param i32) (result i64) + local.get 0 + i64.load8_u)) + +;; function u0:0(i32, i64 vmctx) -> i64 fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 v6 = uload8.i64 little heap v5 +;; @0034 jump block1(v6) +;; +;; block1(v2: i64): +;; @0034 return v2 +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-memory64.clif b/cranelift/filetests/filetests/wasm/i64-memory64.clif deleted file mode 100644 index 64c3baecc64f..000000000000 --- a/cranelift/filetests/filetests/wasm/i64-memory64.clif +++ /dev/null @@ -1,117 +0,0 @@ -; Test basic code generation for i32 memory WebAssembly instructions. -test compile - -; We only test on 64-bit since the heap_addr instructions and vmctx parameters -; explicitly mention the pointer width. -target aarch64 -target x86_64 haswell - -function %i64_load(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = load.i64 v2 - return v3 -} - -function %i64_store(i64, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i64, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - store v0, v3 - return -} - -function %i64_load8_s(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = sload8.i64 v2 - return v3 -} - -function %i64_load8_u(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = uload8.i64 v2 - return v3 -} - -function %i64_store8(i64, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i64, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - istore8 v0, v3 - return -} - -function %i64_load16_s(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = sload16.i64 v2 - return v3 -} - -function %i64_load16_u(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = uload16.i64 v2 - return v3 -} - -function %i64_store16(i64, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i64, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - istore16 v0, v3 - return -} - -function %i64_load32_s(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = sload32.i64 v2 - return v3 -} - -function %i64_load32_u(i32, i64 vmctx) -> i64 { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i32, v1: i64): - v2 = heap_addr.i64 heap0, v0, 0, 1 - v3 = uload32.i64 v2 - return v3 -} - -function %i64_store32(i64, i32, i64 vmctx) { - gv0 = vmctx - heap0 = static gv0, min 0x0001_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000 - -block0(v0: i64, v1: i32, v2: i64): - v3 = heap_addr.i64 heap0, v1, 0, 1 - istore32 v0, v3 - return -} diff --git a/cranelift/filetests/filetests/wasm/i64-store.wat b/cranelift/filetests/filetests/wasm/i64-store.wat new file mode 100644 index 000000000000..f500ec8498fd --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-store.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i32 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.store") (param i32 i64) + local.get 0 + local.get 1 + i64.store)) + +;; function u0:0(i32, i64, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64, v2: i64): +;; @0031 v3 = uextend.i64 v0 +;; @0031 v4 = global_value.i64 gv1 +;; @0031 v5 = iadd v4, v3 +;; @0031 store little heap v1, v5 +;; @0034 jump block1 +;; +;; block1: +;; @0034 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-store16.wat b/cranelift/filetests/filetests/wasm/i64-store16.wat new file mode 100644 index 000000000000..e0950125d211 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-store16.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.store16") (param i32 i64) + local.get 0 + local.get 1 + i64.store16)) + +;; function u0:0(i32, i64, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64, v2: i64): +;; @0033 v3 = uextend.i64 v0 +;; @0033 v4 = global_value.i64 gv1 +;; @0033 v5 = iadd v4, v3 +;; @0033 istore16 little heap v1, v5 +;; @0036 jump block1 +;; +;; block1: +;; @0036 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-store32.wat b/cranelift/filetests/filetests/wasm/i64-store32.wat new file mode 100644 index 000000000000..59cc1d050067 --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-store32.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.store32") (param i32 i64) + local.get 0 + local.get 1 + i64.store32)) + +;; function u0:0(i32, i64, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64, v2: i64): +;; @0033 v3 = uextend.i64 v0 +;; @0033 v4 = global_value.i64 gv1 +;; @0033 v5 = iadd v4, v3 +;; @0033 istore32 little heap v1, v5 +;; @0036 jump block1 +;; +;; block1: +;; @0036 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/i64-store8.wat b/cranelift/filetests/filetests/wasm/i64-store8.wat new file mode 100644 index 000000000000..27a92006b42d --- /dev/null +++ b/cranelift/filetests/filetests/wasm/i64-store8.wat @@ -0,0 +1,25 @@ +;;! target = "x86_64" + +;; Test basic code generation for i64 memory WebAssembly instructions. + +(module + (memory 1) + (func (export "i64.store8") (param i32 i64) + local.get 0 + local.get 1 + i64.store8)) + +;; function u0:0(i32, i64, i64 vmctx) fast { +;; gv0 = vmctx +;; gv1 = load.i64 notrap aligned readonly gv0 +;; +;; block0(v0: i32, v1: i64, v2: i64): +;; @0032 v3 = uextend.i64 v0 +;; @0032 v4 = global_value.i64 gv1 +;; @0032 v5 = iadd v4, v3 +;; @0032 istore8 little heap v1, v5 +;; @0035 jump block1 +;; +;; block1: +;; @0035 return +;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat index a3e74b577867..abdee4670612 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 store little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd_imm v4, -4 +;; @0048 v6 = icmp ugt v3, v5 +;; @0048 trapnz v6, heap_oob +;; @0048 v7 = global_value.i64 gv2 +;; @0048 v8 = iadd v7, v3 +;; @0048 v9 = load.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat index 0fdfd2b22fc8..6311eff510f4 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4100 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 4096 +;; @0040 store little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4100 +;; @0049 v6 = icmp ugt v3, v5 +;; @0049 trapnz v6, heap_oob +;; @0049 v7 = global_value.i64 gv2 +;; @0049 v8 = iadd v7, v3 +;; @0049 v9 = iadd_imm v8, 4096 +;; @0049 v10 = load.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat index f53457f7d872..0e5e00017750 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0004 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = icmp ugt v5, v6 +;; @0040 trapnz v7, heap_oob +;; @0040 v8 = global_value.i64 gv2 +;; @0040 v9 = iadd v8, v3 +;; @0040 v10 = iadd_imm v9, 0xffff_0000 +;; @0040 store little heap v1, v10 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0004 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = icmp ugt v5, v6 +;; @004c trapnz v7, heap_oob +;; @004c v8 = global_value.i64 gv2 +;; @004c v9 = iadd v8, v3 +;; @004c v10 = iadd_imm v9, 0xffff_0000 +;; @004c v11 = load.i32 little heap v10 +;; @0053 jump block1(v11) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat index 944a54c93e85..3eb89a7137dd 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = icmp uge v3, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 istore8 little heap v1, v7 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = icmp uge v3, v4 +;; @0048 trapnz v5, heap_oob +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v3 +;; @0048 v8 = uload8.i32 little heap v7 +;; @004b jump block1(v8) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat index 4fa30f1bf21e..7868f17e506d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4097 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 4096 +;; @0040 istore8 little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4097 +;; @0049 v6 = icmp ugt v3, v5 +;; @0049 trapnz v6, heap_oob +;; @0049 v7 = global_value.i64 gv2 +;; @0049 v8 = iadd v7, v3 +;; @0049 v9 = iadd_imm v8, 4096 +;; @0049 v10 = uload8.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat index fdef6cfd540e..d678f9f53be9 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0001 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = icmp ugt v5, v6 +;; @0040 trapnz v7, heap_oob +;; @0040 v8 = global_value.i64 gv2 +;; @0040 v9 = iadd v8, v3 +;; @0040 v10 = iadd_imm v9, 0xffff_0000 +;; @0040 istore8 little heap v1, v10 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0001 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = icmp ugt v5, v6 +;; @004c trapnz v7, heap_oob +;; @004c v8 = global_value.i64 gv2 +;; @004c v9 = iadd v8, v3 +;; @004c v10 = iadd_imm v9, 0xffff_0000 +;; @004c v11 = uload8.i32 little heap v10 +;; @0053 jump block1(v11) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat index 8732f777a396..bfae3f1f527e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v3, v5 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 store little heap v1, v10 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd_imm v4, -4 +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v3 +;; @0048 v8 = iconst.i64 0 +;; @0048 v9 = icmp ugt v3, v5 +;; @0048 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0048 v11 = load.i32 little heap v10 +;; @004b jump block1(v11) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat index f6272a02d250..7c0f93daad1e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4100 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v3, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 store little heap v1, v11 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4100 +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v3 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = iconst.i64 0 +;; @0049 v10 = icmp ugt v3, v5 +;; @0049 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0049 v12 = load.i32 little heap v11 +;; @004d jump block1(v12) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat index 08d288e4879c..38e88e61cf88 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0004 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 v10 = iconst.i64 0 +;; @0040 v11 = icmp ugt v5, v6 +;; @0040 v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @0040 store little heap v1, v12 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +66,20 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0004 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v3 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = iconst.i64 0 +;; @004c v11 = icmp ugt v5, v6 +;; @004c v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @004c v13 = load.i32 little heap v12 +;; @0053 jump block1(v13) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat index 9fbb235443bb..6328f28f563c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp uge v3, v4 +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 istore8 little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp uge v3, v4 +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = uload8.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat index 95b57803dee0..5c318c3f57fe 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4097 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v3, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 istore8 little heap v1, v11 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4097 +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v3 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = iconst.i64 0 +;; @0049 v10 = icmp ugt v3, v5 +;; @0049 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0049 v12 = uload8.i32 little heap v11 +;; @004d jump block1(v12) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat index 91d4d6c3fb87..137667b996c9 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0001 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 v10 = iconst.i64 0 +;; @0040 v11 = icmp ugt v5, v6 +;; @0040 v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @0040 istore8 little heap v1, v12 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +66,20 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0001 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v3 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = iconst.i64 0 +;; @004c v11 = icmp ugt v5, v6 +;; @004c v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @004c v13 = uload8.i32 little heap v12 +;; @0053 jump block1(v13) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat index 8e3ef5bf353c..6a2591c838ab 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 store little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd_imm v4, -4 +;; @0048 v6 = icmp ugt v3, v5 +;; @0048 trapnz v6, heap_oob +;; @0048 v7 = global_value.i64 gv2 +;; @0048 v8 = iadd v7, v3 +;; @0048 v9 = load.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat index e23d476c6222..b4a0c8a3584b 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4100 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 4096 +;; @0040 store little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4100 +;; @0049 v6 = icmp ugt v3, v5 +;; @0049 trapnz v6, heap_oob +;; @0049 v7 = global_value.i64 gv2 +;; @0049 v8 = iadd v7, v3 +;; @0049 v9 = iadd_imm v8, 4096 +;; @0049 v10 = load.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat index f5b846b1fe55..0aa1790593ec 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0004 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = icmp ugt v5, v6 +;; @0040 trapnz v7, heap_oob +;; @0040 v8 = global_value.i64 gv2 +;; @0040 v9 = iadd v8, v3 +;; @0040 v10 = iadd_imm v9, 0xffff_0000 +;; @0040 store little heap v1, v10 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0004 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = icmp ugt v5, v6 +;; @004c trapnz v7, heap_oob +;; @004c v8 = global_value.i64 gv2 +;; @004c v9 = iadd v8, v3 +;; @004c v10 = iadd_imm v9, 0xffff_0000 +;; @004c v11 = load.i32 little heap v10 +;; @0053 jump block1(v11) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat index e7d543c245d1..e90e8d56e3cb 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = icmp uge v3, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 istore8 little heap v1, v7 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = icmp uge v3, v4 +;; @0048 trapnz v5, heap_oob +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v3 +;; @0048 v8 = uload8.i32 little heap v7 +;; @004b jump block1(v8) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat index 05b6f6cee2d2..b347cf95d3da 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4097 +;; @0040 v6 = icmp ugt v3, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 4096 +;; @0040 istore8 little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4097 +;; @0049 v6 = icmp ugt v3, v5 +;; @0049 trapnz v6, heap_oob +;; @0049 v7 = global_value.i64 gv2 +;; @0049 v8 = iadd v7, v3 +;; @0049 v9 = iadd_imm v8, 4096 +;; @0049 v10 = uload8.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat index f93c4b9b1235..fa2d6148a077 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0001 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = icmp ugt v5, v6 +;; @0040 trapnz v7, heap_oob +;; @0040 v8 = global_value.i64 gv2 +;; @0040 v9 = iadd v8, v3 +;; @0040 v10 = iadd_imm v9, 0xffff_0000 +;; @0040 istore8 little heap v1, v10 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0001 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = icmp ugt v5, v6 +;; @004c trapnz v7, heap_oob +;; @004c v8 = global_value.i64 gv2 +;; @004c v9 = iadd v8, v3 +;; @004c v10 = iadd_imm v9, 0xffff_0000 +;; @004c v11 = uload8.i32 little heap v10 +;; @0053 jump block1(v11) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat index 2664b0b36659..8e59145752a3 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v3, v5 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 store little heap v1, v10 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd_imm v4, -4 +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v3 +;; @0048 v8 = iconst.i64 0 +;; @0048 v9 = icmp ugt v3, v5 +;; @0048 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0048 v11 = load.i32 little heap v10 +;; @004b jump block1(v11) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat index 23d2e8c9dfdc..4ed3c951f2e6 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4100 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v3, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 store little heap v1, v11 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4100 +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v3 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = iconst.i64 0 +;; @0049 v10 = icmp ugt v3, v5 +;; @0049 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0049 v12 = load.i32 little heap v11 +;; @004d jump block1(v12) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat index 577596c70482..5d127f03c854 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0004 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 v10 = iconst.i64 0 +;; @0040 v11 = icmp ugt v5, v6 +;; @0040 v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @0040 store little heap v1, v12 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +66,20 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0004 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0004 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v3 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = iconst.i64 0 +;; @004c v11 = icmp ugt v5, v6 +;; @004c v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @004c v13 = load.i32 little heap v12 +;; @0053 jump block1(v13) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat index 04e038a61f76..a983c0f44cdc 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp uge v3, v4 +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 istore8 little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp uge v3, v4 +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = uload8.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat index 70751fea1e1f..bca09c66721d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd_imm v4, -4097 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v3 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v3, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 istore8 little heap v1, v11 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd_imm v4, -4097 +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v3 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = iconst.i64 0 +;; @0049 v10 = icmp ugt v3, v5 +;; @0049 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0049 v12 = uload8.i32 little heap v11 +;; @004d jump block1(v12) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat index 0aae2568d0fd..db6d99ea179d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0xffff_0001 +;; @0040 v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @0040 v6 = global_value.i64 gv1 +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v3 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 v10 = iconst.i64 0 +;; @0040 v11 = icmp ugt v5, v6 +;; @0040 v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @0040 istore8 little heap v1, v12 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +66,20 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = uextend.i64 v0 +;; @004c v4 = iconst.i64 0xffff_0001 +;; @004c v5 = uadd_overflow_trap v3, v4, heap_oob ; v4 = 0xffff_0001 +;; @004c v6 = global_value.i64 gv1 +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v3 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = iconst.i64 0 +;; @004c v11 = icmp ugt v5, v6 +;; @004c v12 = select_spectre_guard v11, v10, v9 ; v10 = 0 +;; @004c v13 = uload8.i32 little heap v12 +;; @0053 jump block1(v13) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat index 4e7ce64428cc..d1bbfe763afd 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 store little heap v1, v7 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = iadd_imm v3, -4 +;; @0048 v5 = icmp ugt v0, v4 +;; @0048 trapnz v5, heap_oob +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v0 +;; @0048 v8 = load.i32 little heap v7 +;; @004b jump block1(v8) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat index 09ce20f1b0be..48d3c4cdb9b4 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4100 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 store little heap v1, v8 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4100 +;; @0049 v5 = icmp ugt v0, v4 +;; @0049 trapnz v5, heap_oob +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v0 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = load.i32 little heap v8 +;; @004d jump block1(v9) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat index 55e27a601d73..2818830f2e5e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0004 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = icmp ugt v4, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v0 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 store little heap v1, v9 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0004 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = icmp ugt v4, v5 +;; @004c trapnz v6, heap_oob +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v0 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = load.i32 little heap v9 +;; @0053 jump block1(v10) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat index c6df56d56c97..344421bd20a4 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat @@ -43,11 +43,14 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = icmp uge v0, v3 +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 istore8 little heap v1, v6 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +61,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = icmp uge v0, v3 +;; @0048 trapnz v4, heap_oob +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v0 +;; @0048 v7 = uload8.i32 little heap v6 +;; @004b jump block1(v7) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat index 9bd55d0161aa..fe99a3a69a27 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4097 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 istore8 little heap v1, v8 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4097 +;; @0049 v5 = icmp ugt v0, v4 +;; @0049 trapnz v5, heap_oob +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v0 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = uload8.i32 little heap v8 +;; @004d jump block1(v9) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat index 3d8ec18e95c8..dfffbffa10a9 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0001 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = icmp ugt v4, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v0 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 istore8 little heap v1, v9 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0001 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = icmp ugt v4, v5 +;; @004c trapnz v6, heap_oob +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v0 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = uload8.i32 little heap v9 +;; @0053 jump block1(v10) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat index abc1591361a0..624eb4421b32 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v4 +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 store little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = iadd_imm v3, -4 +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v0 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp ugt v0, v4 +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = load.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat index a38bd7b22cad..ca2281275079 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4100 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v0, v4 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 store little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4100 +;; @0049 v5 = global_value.i64 gv2 +;; @0049 v6 = iadd v5, v0 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v0, v4 +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = load.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat index 77d6acd3285b..60ba4113f274 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0004 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 0xffff_0000 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v4, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 store little heap v1, v11 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0004 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = global_value.i64 gv2 +;; @004c v7 = iadd v6, v0 +;; @004c v8 = iadd_imm v7, 0xffff_0000 +;; @004c v9 = iconst.i64 0 +;; @004c v10 = icmp ugt v4, v5 +;; @004c v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @004c v12 = load.i32 little heap v11 +;; @0053 jump block1(v12) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat index 4df1dd1c4f67..891c5f7da97c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = global_value.i64 gv2 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp uge v0, v3 +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 istore8 little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = global_value.i64 gv2 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp uge v0, v3 +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = uload8.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat index b8b5062c1a6d..7e9b712d82b4 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4097 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v0, v4 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 istore8 little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4097 +;; @0049 v5 = global_value.i64 gv2 +;; @0049 v6 = iadd v5, v0 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v0, v4 +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = uload8.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat index aa0c3ac9ec9c..c7c026b9b385 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0001 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 0xffff_0000 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v4, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 istore8 little heap v1, v11 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0001 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = global_value.i64 gv2 +;; @004c v7 = iadd v6, v0 +;; @004c v8 = iadd_imm v7, 0xffff_0000 +;; @004c v9 = iconst.i64 0 +;; @004c v10 = icmp ugt v4, v5 +;; @004c v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @004c v12 = uload8.i32 little heap v11 +;; @0053 jump block1(v12) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat index 5521e6f10cdf..cab9f42410ca 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 store little heap v1, v7 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = iadd_imm v3, -4 +;; @0048 v5 = icmp ugt v0, v4 +;; @0048 trapnz v5, heap_oob +;; @0048 v6 = global_value.i64 gv2 +;; @0048 v7 = iadd v6, v0 +;; @0048 v8 = load.i32 little heap v7 +;; @004b jump block1(v8) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat index 4bede2971330..e42f905faa33 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4100 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 store little heap v1, v8 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4100 +;; @0049 v5 = icmp ugt v0, v4 +;; @0049 trapnz v5, heap_oob +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v0 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = load.i32 little heap v8 +;; @004d jump block1(v9) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat index 15d574bbc6ce..f581508ed974 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0004 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = icmp ugt v4, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v0 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 store little heap v1, v9 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0004 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = icmp ugt v4, v5 +;; @004c trapnz v6, heap_oob +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v0 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = load.i32 little heap v9 +;; @0053 jump block1(v10) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat index 5bbc8088abf3..e0e5a5379751 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat @@ -43,11 +43,14 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = icmp uge v0, v3 +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 istore8 little heap v1, v6 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +61,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = icmp uge v0, v3 +;; @0048 trapnz v4, heap_oob +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v0 +;; @0048 v7 = uload8.i32 little heap v6 +;; @004b jump block1(v7) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat index 9e7de1e8fae8..146f58b03b1e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4097 +;; @0040 v5 = icmp ugt v0, v4 +;; @0040 trapnz v5, heap_oob +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 4096 +;; @0040 istore8 little heap v1, v8 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4097 +;; @0049 v5 = icmp ugt v0, v4 +;; @0049 trapnz v5, heap_oob +;; @0049 v6 = global_value.i64 gv2 +;; @0049 v7 = iadd v6, v0 +;; @0049 v8 = iadd_imm v7, 4096 +;; @0049 v9 = uload8.i32 little heap v8 +;; @004d jump block1(v9) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat index 02f755ff4a63..8e1e4b857d60 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0001 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = icmp ugt v4, v5 +;; @0040 trapnz v6, heap_oob +;; @0040 v7 = global_value.i64 gv2 +;; @0040 v8 = iadd v7, v0 +;; @0040 v9 = iadd_imm v8, 0xffff_0000 +;; @0040 istore8 little heap v1, v9 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0001 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = icmp ugt v4, v5 +;; @004c trapnz v6, heap_oob +;; @004c v7 = global_value.i64 gv2 +;; @004c v8 = iadd v7, v0 +;; @004c v9 = iadd_imm v8, 0xffff_0000 +;; @004c v10 = uload8.i32 little heap v9 +;; @0053 jump block1(v10) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat index 1c7c2969a5ae..57bfbfbc896c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat @@ -43,11 +43,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v4 +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 store little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +63,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = iadd_imm v3, -4 +;; @0048 v5 = global_value.i64 gv2 +;; @0048 v6 = iadd v5, v0 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp ugt v0, v4 +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = load.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat index 7f3ad93feae9..5cc0fad0c1e7 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4100 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v0, v4 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 store little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4100 +;; @0049 v5 = global_value.i64 gv2 +;; @0049 v6 = iadd v5, v0 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v0, v4 +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = load.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat index ef15b90f3e19..6df2c93dd9ec 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0004 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 0xffff_0000 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v4, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 store little heap v1, v11 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0004 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0004 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = global_value.i64 gv2 +;; @004c v7 = iadd v6, v0 +;; @004c v8 = iadd_imm v7, 0xffff_0000 +;; @004c v9 = iconst.i64 0 +;; @004c v10 = icmp ugt v4, v5 +;; @004c v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @004c v12 = load.i32 little heap v11 +;; @0053 jump block1(v12) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat index 40e2f7c7ac9b..d390da8cf014 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat @@ -43,11 +43,15 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = global_value.i64 gv2 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp uge v0, v3 +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 istore8 little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -58,12 +62,16 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = global_value.i64 gv1 +;; @0048 v4 = global_value.i64 gv2 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp uge v0, v3 +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = uload8.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat index 7cb107f64115..f15a8869e8e0 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -43,11 +43,17 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = global_value.i64 gv1 +;; @0040 v4 = iadd_imm v3, -4097 +;; @0040 v5 = global_value.i64 gv2 +;; @0040 v6 = iadd v5, v0 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v0, v4 +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 istore8 little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -58,12 +64,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = global_value.i64 gv1 +;; @0049 v4 = iadd_imm v3, -4097 +;; @0049 v5 = global_value.i64 gv2 +;; @0049 v6 = iadd v5, v0 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v0, v4 +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = uload8.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat index 7d53b4a757b9..5b1307c75d0c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_dynamic_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -43,11 +43,18 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0xffff_0001 +;; @0040 v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = global_value.i64 gv2 +;; @0040 v7 = iadd v6, v0 +;; @0040 v8 = iadd_imm v7, 0xffff_0000 +;; @0040 v9 = iconst.i64 0 +;; @0040 v10 = icmp ugt v4, v5 +;; @0040 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @0040 istore8 little heap v1, v11 ;; @0047 jump block1 ;; ;; block1: @@ -58,12 +65,19 @@ ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0+8 ;; gv2 = load.i64 notrap aligned readonly gv0 -;; heap0 = dynamic gv2, min 0x0001_0000, bound gv1, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) +;; @004c v3 = iconst.i64 0xffff_0001 +;; @004c v4 = uadd_overflow_trap v0, v3, heap_oob ; v3 = 0xffff_0001 +;; @004c v5 = global_value.i64 gv1 +;; @004c v6 = global_value.i64 gv2 +;; @004c v7 = iadd v6, v0 +;; @004c v8 = iadd_imm v7, 0xffff_0000 +;; @004c v9 = iconst.i64 0 +;; @004c v10 = icmp ugt v4, v5 +;; @004c v11 = select_spectre_guard v10, v9, v8 ; v9 = 0 +;; @004c v12 = uload8.i32 little heap v11 +;; @0053 jump block1(v12) ;; ;; block1(v2: i32): ;; @0053 return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat index 0ff0702b4c17..3da0d433a944 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = icmp_imm ugt v3, 0x0fff_fffc +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 store little heap v1, v6 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = icmp_imm ugt v3, 0x0fff_fffc +;; @0048 trapnz v4, heap_oob +;; @0048 v5 = global_value.i64 gv1 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = load.i32 little heap v6 +;; @004b jump block1(v7) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat index 5e7a99e6bd64..44734b44a023 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = icmp_imm ugt v3, 0x0fff_effc +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 store little heap v1, v7 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = icmp_imm ugt v3, 0x0fff_effc +;; @0049 trapnz v4, heap_oob +;; @0049 v5 = global_value.i64 gv1 +;; @0049 v6 = iadd v5, v3 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = load.i32 little heap v7 +;; @004d jump block1(v8) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat index 1626de9cd6e2..38a9566727a0 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat index a6f8bb444bd7..acae947c597d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = icmp_imm ugt v3, 0x0fff_ffff +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 istore8 little heap v1, v6 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = icmp_imm ugt v3, 0x0fff_ffff +;; @0048 trapnz v4, heap_oob +;; @0048 v5 = global_value.i64 gv1 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = uload8.i32 little heap v6 +;; @004b jump block1(v7) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat index 09ccc2238fc2..29d67fe8a912 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = icmp_imm ugt v3, 0x0fff_efff +;; @0040 trapnz v4, heap_oob +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 istore8 little heap v1, v7 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = icmp_imm ugt v3, 0x0fff_efff +;; @0049 trapnz v4, heap_oob +;; @0049 v5 = global_value.i64 gv1 +;; @0049 v6 = iadd v5, v3 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = uload8.i32 little heap v7 +;; @004d jump block1(v8) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat index bc62c76e949b..1eec80fbfcf9 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat index aa142955f4f7..c694199f19aa 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0x0fff_fffc +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v3, v4 ; v4 = 0x0fff_fffc +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 store little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = iconst.i64 0x0fff_fffc +;; @0048 v5 = global_value.i64 gv1 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp ugt v3, v4 ; v4 = 0x0fff_fffc +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = load.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat index dc3e06c9c874..88141f3846a2 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0x0fff_effc +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v3, v4 ; v4 = 0x0fff_effc +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 store little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +60,18 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = iconst.i64 0x0fff_effc +;; @0049 v5 = global_value.i64 gv1 +;; @0049 v6 = iadd v5, v3 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v3, v4 ; v4 = 0x0fff_effc +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = load.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat index efdcd28da398..4e906a0097d2 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat index 1e287eab6e92..8dac563b0443 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0x0fff_ffff +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v3, v4 ; v4 = 0x0fff_ffff +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 istore8 little heap v1, v9 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = iconst.i64 0x0fff_ffff +;; @0048 v5 = global_value.i64 gv1 +;; @0048 v6 = iadd v5, v3 +;; @0048 v7 = iconst.i64 0 +;; @0048 v8 = icmp ugt v3, v4 ; v4 = 0x0fff_ffff +;; @0048 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0048 v10 = uload8.i32 little heap v9 +;; @004b jump block1(v10) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat index b935485212d9..19b3e954aec4 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = iconst.i64 0x0fff_efff +;; @0040 v5 = global_value.i64 gv1 +;; @0040 v6 = iadd v5, v3 +;; @0040 v7 = iadd_imm v6, 4096 +;; @0040 v8 = iconst.i64 0 +;; @0040 v9 = icmp ugt v3, v4 ; v4 = 0x0fff_efff +;; @0040 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0040 istore8 little heap v1, v10 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +60,18 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = iconst.i64 0x0fff_efff +;; @0049 v5 = global_value.i64 gv1 +;; @0049 v6 = iadd v5, v3 +;; @0049 v7 = iadd_imm v6, 4096 +;; @0049 v8 = iconst.i64 0 +;; @0049 v9 = icmp ugt v3, v4 ; v4 = 0x0fff_efff +;; @0049 v10 = select_spectre_guard v9, v8, v7 ; v8 = 0 +;; @0049 v11 = uload8.i32 little heap v10 +;; @004d jump block1(v11) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat index 043979d84211..cb81063e2bb3 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat index b4a3555d12da..9b6881e65b1a 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat @@ -40,11 +40,12 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 store little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +55,13 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v3 +;; @0048 v6 = load.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat index ac62d8c1b146..a7b43d2075fb 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 store little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v3 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = load.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat index af531a611507..c89980fea651 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat index 3592850e54cf..463974ba4d4a 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat @@ -40,11 +40,12 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 istore8 little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +55,13 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v3 +;; @0048 v6 = uload8.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat index fc2b36ff72a0..2764a8734e04 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 istore8 little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v3 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = uload8.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat index 48b5c73ae50f..9b9b2f48263c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat index 26f9b0676407..9151ef442b7f 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat @@ -40,11 +40,12 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 store little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +55,13 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v3 +;; @0048 v6 = load.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat index 64184b6850e8..ff6527a8b67c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 store little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v3 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = load.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat index 7dbec666b13d..fb6cd492543d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat index accd04ab2447..58e13849d186 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat @@ -40,11 +40,12 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 istore8 little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +55,13 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = uextend.i64 v0 +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v3 +;; @0048 v6 = uload8.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat index 3860d842f7f7..25153188f6bd 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = uextend.i64 v0 +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v3 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 istore8 little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = uextend.i64 v0 +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v3 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = uload8.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat index a823b76bd3b8..3603eb0f520c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,17 @@ ;; function u0:0(i32, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 v3 = uextend.i64 v0 +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i32, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i32 ;; ;; block0(v0: i32, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c v3 = uextend.i64 v0 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat index 431e3270c568..a6924a9af8d8 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_fffc +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 store little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = icmp_imm ugt v0, 0x0fff_fffc +;; @0048 trapnz v3, heap_oob +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = load.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat index fde4a14b572a..bff5b7a49b84 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_effc +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 store little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = icmp_imm ugt v0, 0x0fff_effc +;; @0049 trapnz v3, heap_oob +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = load.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat index ddcc9d3edb4d..151d19741c0f 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat index 914439d6de5f..34f78ee4e832 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_ffff +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 istore8 little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = icmp_imm ugt v0, 0x0fff_ffff +;; @0048 trapnz v3, heap_oob +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = uload8.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat index 62b702688f30..6218cb0e8806 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_efff +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 istore8 little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = icmp_imm ugt v0, 0x0fff_efff +;; @0049 trapnz v3, heap_oob +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = uload8.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat index 2055957e70aa..1a7729d88a6c 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat index ab69327111ac..595bd68d8cd7 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_fffc +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_fffc +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 store little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = iconst.i64 0x0fff_fffc +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_fffc +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = load.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat index 06fac2c15efb..1179ce17fa27 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_effc +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_effc +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 store little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = iconst.i64 0x0fff_effc +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = iconst.i64 0 +;; @0049 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_effc +;; @0049 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0049 v10 = load.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat index 9a7cea73a06b..9d0e47fc048d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat index b65344116ec9..d0f545e2bdb2 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_ffff +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_ffff +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 istore8 little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = iconst.i64 0x0fff_ffff +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_ffff +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = uload8.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat index fcabe8cb27a6..d362c56b93bd 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_efff +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_efff +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 istore8 little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = iconst.i64 0x0fff_efff +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = iconst.i64 0 +;; @0049 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_efff +;; @0049 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0049 v10 = uload8.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat index 08c7889dea72..1ba900ed2d24 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat index be2c8ab03ac1..17be28d960ae 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_fffc +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 store little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = icmp_imm ugt v0, 0x0fff_fffc +;; @0048 trapnz v3, heap_oob +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = load.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat index f47c13485b9a..0527549ce39e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_effc +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 store little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = icmp_imm ugt v0, 0x0fff_effc +;; @0049 trapnz v3, heap_oob +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = load.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat index c49eec34773f..10e61b6b121d 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat index 3449b83faf28..c9ad77fa55c0 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat @@ -40,11 +40,13 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_ffff +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 istore8 little heap v1, v5 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +56,14 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = icmp_imm ugt v0, 0x0fff_ffff +;; @0048 trapnz v3, heap_oob +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = uload8.i32 little heap v5 +;; @004b jump block1(v6) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat index 87f1ff2beed7..cb8badc5518e 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,14 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = icmp_imm ugt v0, 0x0fff_efff +;; @0040 trapnz v3, heap_oob +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 istore8 little heap v1, v6 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +57,15 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = icmp_imm ugt v0, 0x0fff_efff +;; @0049 trapnz v3, heap_oob +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = uload8.i32 little heap v6 +;; @004d jump block1(v7) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat index 92102ed2b1c1..96de204b22ae 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat index 45a9f7e7f1a5..c77ca4cbc070 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_fffc +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_fffc +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 store little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 4 -;; @0048 v4 = load.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = iconst.i64 0x0fff_fffc +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_fffc +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = load.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat index 02fd250965c3..ed41d8682901 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0x1000_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0040 store little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_effc +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_effc +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 store little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 4 -;; @0049 v4 = load.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = iconst.i64 0x0fff_effc +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = iconst.i64 0 +;; @0049 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_effc +;; @0049 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0049 v10 = load.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat index f85b234ea762..d17f9c5d0545 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @0040 store little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 4 -;; @004c v4 = load.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat index c775300cb9ec..abc0786205f6 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0_offset.wat @@ -40,11 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_ffff +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iconst.i64 0 +;; @0040 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_ffff +;; @0040 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0040 istore8 little heap v1, v8 ;; @0043 jump block1 ;; ;; block1: @@ -54,12 +58,16 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0048 v3 = heap_addr.i64 heap0, v0, 0, 1 -;; @0048 v4 = uload8.i32 little heap v3 -;; @004b jump block1(v4) +;; @0048 v3 = iconst.i64 0x0fff_ffff +;; @0048 v4 = global_value.i64 gv1 +;; @0048 v5 = iadd v4, v0 +;; @0048 v6 = iconst.i64 0 +;; @0048 v7 = icmp ugt v0, v3 ; v3 = 0x0fff_ffff +;; @0048 v8 = select_spectre_guard v7, v6, v5 ; v6 = 0 +;; @0048 v9 = uload8.i32 little heap v8 +;; @004b jump block1(v9) ;; ;; block1(v2: i32): ;; @004b return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat index 0a5bd59485e3..8fa0523a2945 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0x1000_offset.wat @@ -40,11 +40,16 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0040 istore8 little heap v1, v3 +;; @0040 v3 = iconst.i64 0x0fff_efff +;; @0040 v4 = global_value.i64 gv1 +;; @0040 v5 = iadd v4, v0 +;; @0040 v6 = iadd_imm v5, 4096 +;; @0040 v7 = iconst.i64 0 +;; @0040 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_efff +;; @0040 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0040 istore8 little heap v1, v9 ;; @0044 jump block1 ;; ;; block1: @@ -54,12 +59,17 @@ ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @0049 v3 = heap_addr.i64 heap0, v0, 4096, 1 -;; @0049 v4 = uload8.i32 little heap v3 -;; @004d jump block1(v4) +;; @0049 v3 = iconst.i64 0x0fff_efff +;; @0049 v4 = global_value.i64 gv1 +;; @0049 v5 = iadd v4, v0 +;; @0049 v6 = iadd_imm v5, 4096 +;; @0049 v7 = iconst.i64 0 +;; @0049 v8 = icmp ugt v0, v3 ; v3 = 0x0fff_efff +;; @0049 v9 = select_spectre_guard v8, v7, v6 ; v7 = 0 +;; @0049 v10 = uload8.i32 little heap v9 +;; @004d jump block1(v10) ;; ;; block1(v2: i32): ;; @004d return v2 diff --git a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat index add0d6b608e8..cfd6a406b20f 100644 --- a/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat +++ b/cranelift/filetests/filetests/wasm/load-store/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat @@ -40,27 +40,15 @@ ;; function u0:0(i64, i32, i64 vmctx) fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i32, v2: i64): -;; @0040 v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @0040 istore8 little heap v1, v3 -;; @0047 jump block1 -;; -;; block1: -;; @0047 return +;; @0040 trap heap_oob ;; } ;; ;; function u0:1(i64, i64 vmctx) -> i32 fast { ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly gv0 -;; heap0 = static gv1, min 0x0001_0000, bound 0x1000_0000, offset_guard 0xffff_ffff, index_type i64 ;; ;; block0(v0: i64, v1: i64): -;; @004c v3 = heap_addr.i64 heap0, v0, 0xffff_0000, 1 -;; @004c v4 = uload8.i32 little heap v3 -;; @0053 jump block1(v4) -;; -;; block1(v2: i32): -;; @0053 return v2 +;; @004c trap heap_oob ;; } \ No newline at end of file diff --git a/cranelift/filetests/src/lib.rs b/cranelift/filetests/src/lib.rs index 5fd5255df6e2..bf6954796989 100644 --- a/cranelift/filetests/src/lib.rs +++ b/cranelift/filetests/src/lib.rs @@ -34,7 +34,6 @@ pub mod function_runner; mod match_directive; mod runner; mod runone; -mod runtest_environment; mod subtest; mod test_alias_analysis; diff --git a/cranelift/filetests/src/runtest_environment.rs b/cranelift/filetests/src/runtest_environment.rs index 5a7fe1564492..8a32e8161809 100644 --- a/cranelift/filetests/src/runtest_environment.rs +++ b/cranelift/filetests/src/runtest_environment.rs @@ -1,60 +1,18 @@ use anyhow::anyhow; use cranelift_codegen::ir::{ArgumentPurpose, Function}; -use cranelift_reader::parse_heap_command; -use cranelift_reader::{Comment, HeapCommand}; +use cranelift_reader::Comment; /// Stores info about the expected environment for a test function. #[derive(Debug, Clone)] -pub struct RuntestEnvironment { - pub heaps: Vec, -} +pub struct RuntestEnvironment {} impl RuntestEnvironment { /// Parse the environment from a set of comments pub fn parse(comments: &[Comment]) -> anyhow::Result { - let mut env = RuntestEnvironment { heaps: Vec::new() }; - - for comment in comments.iter() { - if let Some(heap_command) = parse_heap_command(comment.text)? { - let heap_index = env.heaps.len() as u64; - let expected_ptr = heap_index * 16; - if Some(expected_ptr) != heap_command.ptr_offset.map(|p| p.into()) { - return Err(anyhow!( - "Invalid ptr offset, expected vmctx+{}", - expected_ptr - )); - } - - let expected_bound = (heap_index * 16) + 8; - if Some(expected_bound) != heap_command.bound_offset.map(|p| p.into()) { - return Err(anyhow!( - "Invalid bound offset, expected vmctx+{}", - expected_bound - )); - } - - env.heaps.push(heap_command); - }; - } - + let mut env = RuntestEnvironment {}; Ok(env) } - pub fn is_active(&self) -> bool { - !self.heaps.is_empty() - } - - /// Allocates memory for heaps - pub fn allocate_memory(&self) -> Vec { - self.heaps - .iter() - .map(|cmd| { - let size: u64 = cmd.size.into(); - vec![0u8; size as usize] - }) - .collect() - } - /// Validates the signature of a [Function] ensuring that if this environment is active, the /// function has a `vmctx` argument pub fn validate_signature(&self, func: &Function) -> Result<(), String> { @@ -76,5 +34,3 @@ impl RuntestEnvironment { Ok(()) } } - -pub(crate) type HeapMemory = Vec; diff --git a/cranelift/filetests/src/test_interpret.rs b/cranelift/filetests/src/test_interpret.rs index 14f191cfa9d1..f8d2f1b57b48 100644 --- a/cranelift/filetests/src/test_interpret.rs +++ b/cranelift/filetests/src/test_interpret.rs @@ -4,17 +4,14 @@ //! using [RunCommand](cranelift_reader::RunCommand)s. use crate::runone::FileUpdate; -use crate::runtest_environment::RuntestEnvironment; use crate::subtest::SubTest; -use anyhow::{anyhow, Context}; -use cranelift_codegen::data_value::DataValue; -use cranelift_codegen::ir::types::I64; +use anyhow::Context; use cranelift_codegen::ir::Function; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::Flags; use cranelift_codegen::{self, ir}; use cranelift_interpreter::environment::FunctionStore; -use cranelift_interpreter::interpreter::{HeapInit, Interpreter, InterpreterState}; +use cranelift_interpreter::interpreter::{Interpreter, InterpreterState}; use cranelift_interpreter::step::ControlFlow; use cranelift_reader::{parse_run_command, Details, TestCommand, TestFile}; use log::{info, trace}; @@ -62,10 +59,7 @@ impl SubTest for TestInterpret { for (func, details) in &testfile.functions { info!("Test: {}({}) interpreter", self.name(), func.name); - let test_env = RuntestEnvironment::parse(&details.comments[..])?; - test_env.validate_signature(&func).map_err(|s| anyhow!(s))?; - - run_test(&test_env, &func_store, func, details).context(self.name())?; + run_test(&func_store, func, details).context(self.name())?; } Ok(()) @@ -80,12 +74,7 @@ impl SubTest for TestInterpret { } } -fn run_test( - test_env: &RuntestEnvironment, - func_store: &FunctionStore, - func: &Function, - details: &Details, -) -> anyhow::Result<()> { +fn run_test(func_store: &FunctionStore, func: &Function, details: &Details) -> anyhow::Result<()> { for comment in details.comments.iter() { if let Some(command) = parse_run_command(comment.text, &func.signature)? { trace!("Parsed run command: {}", command); @@ -94,14 +83,9 @@ fn run_test( .run(|func_name, run_args| { // Rebuild the interpreter state on every run to ensure that we don't accidentally depend on // some leftover state - let mut state = - InterpreterState::default().with_function_store(func_store.clone()); + let state = InterpreterState::default().with_function_store(func_store.clone()); let mut args = Vec::with_capacity(run_args.len()); - if test_env.is_active() { - let vmctx_addr = register_heaps(&mut state, test_env); - args.push(vmctx_addr); - } args.extend_from_slice(run_args); // Because we have stored function names with a leading %, we need to re-add it. @@ -119,34 +103,3 @@ fn run_test( } Ok(()) } - -/// Build a VMContext struct with the layout described in docs/testing.md. -pub fn register_heaps<'a>( - state: &mut InterpreterState<'a>, - test_env: &RuntestEnvironment, -) -> DataValue { - let mem = test_env.allocate_memory(); - let vmctx_struct = mem - .into_iter() - // This memory layout (a contiguous list of base + bound ptrs) - // is enforced by the RuntestEnvironment when parsing the heap - // directives. So we are safe to replicate that here. - .flat_map(|mem| { - let heap_len = mem.len() as u64; - let heap = state.register_heap(HeapInit::FromBacking(mem)); - [ - state.get_heap_address(I64, heap, 0).unwrap(), - state.get_heap_address(I64, heap, heap_len).unwrap(), - ] - }) - .map(|addr| { - let mut mem = [0u8; 8]; - addr.write_to_slice(&mut mem[..]); - mem - }) - .flatten() - .collect(); - - let vmctx_heap = state.register_heap(HeapInit::FromBacking(vmctx_struct)); - state.get_heap_address(I64, vmctx_heap, 0).unwrap() -} diff --git a/cranelift/filetests/src/test_run.rs b/cranelift/filetests/src/test_run.rs index 9af1a9622cb8..febc30155a29 100644 --- a/cranelift/filetests/src/test_run.rs +++ b/cranelift/filetests/src/test_run.rs @@ -4,7 +4,6 @@ use crate::function_runner::{CompiledTestFile, TestFileCompiler}; use crate::runone::FileUpdate; -use crate::runtest_environment::{HeapMemory, RuntestEnvironment}; use crate::subtest::{Context, SubTest}; use anyhow::Context as _; use cranelift_codegen::data_value::DataValue; @@ -117,22 +116,16 @@ fn run_test( func: &ir::Function, context: &Context, ) -> anyhow::Result<()> { - let test_env = RuntestEnvironment::parse(&context.details.comments[..])?; - for comment in context.details.comments.iter() { if let Some(command) = parse_run_command(comment.text, &func.signature)? { trace!("Parsed run command: {}", command); command .run(|_, run_args| { - test_env.validate_signature(&func)?; - let (_heaps, _ctx_struct, vmctx_ptr) = - build_vmctx_struct(&test_env, context.isa.unwrap().pointer_type()); + let (_ctx_struct, _vmctx_ptr) = + build_vmctx_struct(context.isa.unwrap().pointer_type()); let mut args = Vec::with_capacity(run_args.len()); - if test_env.is_active() { - args.push(vmctx_ptr); - } args.extend_from_slice(run_args); let trampoline = testfile.get_trampoline(func).unwrap(); @@ -215,22 +208,13 @@ impl SubTest for TestRun { } /// Build a VMContext struct with the layout described in docs/testing.md. -pub fn build_vmctx_struct( - test_env: &RuntestEnvironment, - ptr_ty: Type, -) -> (Vec, Vec, DataValue) { - let heaps = test_env.allocate_memory(); - - let context_struct: Vec = heaps - .iter() - .flat_map(|heap| [heap.as_ptr(), heap.as_ptr().wrapping_add(heap.len())]) - .map(|p| p as usize as u64) - .collect(); +pub fn build_vmctx_struct(ptr_ty: Type) -> (Vec, DataValue) { + let context_struct: Vec = Vec::new(); let ptr = context_struct.as_ptr() as usize as i128; let ptr_dv = DataValue::from_integer(ptr, ptr_ty).expect("Failed to cast pointer to native target size"); // Return all these to make sure we don't deallocate the heaps too early - (heaps, context_struct, ptr_dv) + (context_struct, ptr_dv) } diff --git a/cranelift/filetests/src/test_wasm/config.rs b/cranelift/filetests/src/test_wasm/config.rs index c6baf217cd6b..fba40b62ce31 100644 --- a/cranelift/filetests/src/test_wasm/config.rs +++ b/cranelift/filetests/src/test_wasm/config.rs @@ -154,8 +154,11 @@ pub struct TestHeap { } impl TestHeap { - pub fn to_ir(&self, name_to_ir_global: &BTreeMap) -> ir::HeapData { - ir::HeapData { + pub fn to_ir( + &self, + name_to_ir_global: &BTreeMap, + ) -> cranelift_wasm::HeapData { + cranelift_wasm::HeapData { base: name_to_ir_global[&self.base], min_size: self.min_size.into(), offset_guard_size: self.offset_guard_size.into(), @@ -187,15 +190,18 @@ pub struct TestHeapStyle { } impl TestHeapStyle { - pub fn to_ir(&self, name_to_ir_global: &BTreeMap) -> ir::HeapStyle { + pub fn to_ir( + &self, + name_to_ir_global: &BTreeMap, + ) -> cranelift_wasm::HeapStyle { match self.kind.as_str() { - "static" => ir::HeapStyle::Static { + "static" => cranelift_wasm::HeapStyle::Static { bound: match &self.bound { toml::Value::Integer(x) => u64::try_from(*x).unwrap().into(), _ => unreachable!(), }, }, - "dynamic" => ir::HeapStyle::Dynamic { + "dynamic" => cranelift_wasm::HeapStyle::Dynamic { bound_gv: match &self.bound { toml::Value::String(g) => name_to_ir_global[g], _ => unreachable!(), diff --git a/cranelift/filetests/src/test_wasm/env.rs b/cranelift/filetests/src/test_wasm/env.rs index fd1f1844398a..5d363aa412ab 100644 --- a/cranelift/filetests/src/test_wasm/env.rs +++ b/cranelift/filetests/src/test_wasm/env.rs @@ -49,6 +49,7 @@ impl<'data> ModuleEnvironment<'data> for ModuleEnv { &self.inner.info, self.inner.expected_reachability.clone(), self.config.clone(), + self.heap_access_spectre_mitigation, ); let func_index = FuncIndex::new( self.inner.get_num_func_imports() + self.inner.info.function_bodies.len(), @@ -234,6 +235,7 @@ pub struct FuncEnv<'a> { pub config: TestConfig, pub name_to_ir_global: BTreeMap, pub next_heap: usize, + pub heap_access_spectre_mitigation: bool, } impl<'a> FuncEnv<'a> { @@ -241,6 +243,7 @@ impl<'a> FuncEnv<'a> { mod_info: &'a cranelift_wasm::DummyModuleInfo, expected_reachability: Option, config: TestConfig, + heap_access_spectre_mitigation: bool, ) -> Self { let inner = cranelift_wasm::DummyFuncEnvironment::new(mod_info, expected_reachability); Self { @@ -248,6 +251,7 @@ impl<'a> FuncEnv<'a> { config, name_to_ir_global: Default::default(), next_heap: 0, + heap_access_spectre_mitigation, } } } @@ -256,6 +260,10 @@ impl<'a> TargetEnvironment for FuncEnv<'a> { fn target_config(&self) -> TargetFrontendConfig { self.inner.target_config() } + + fn heap_access_spectre_mitigation(&self) -> bool { + self.heap_access_spectre_mitigation + } } impl<'a> FuncEnvironment for FuncEnv<'a> { @@ -263,7 +271,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, func: &mut ir::Function, index: cranelift_wasm::MemoryIndex, - ) -> cranelift_wasm::WasmResult { + ) -> cranelift_wasm::WasmResult { if self.next_heap < self.config.heaps.len() { let heap = &self.config.heaps[self.next_heap]; self.next_heap += 1; @@ -311,7 +319,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { self.name_to_ir_global.insert(global_name.to_string(), g); } - Ok(func.create_heap(heap.to_ir(&self.name_to_ir_global))) + Ok(self.inner.heaps.push(heap.to_ir(&self.name_to_ir_global))) } else { self.inner.make_heap(func, index) } @@ -378,7 +386,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, val: ir::Value, ) -> cranelift_wasm::WasmResult { self.inner.translate_memory_grow(pos, index, heap, val) @@ -388,7 +396,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, ) -> cranelift_wasm::WasmResult { self.inner.translate_memory_size(pos, index, heap) } @@ -397,9 +405,9 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, src_index: cranelift_wasm::MemoryIndex, - src_heap: ir::Heap, + src_heap: cranelift_wasm::Heap, dst_index: cranelift_wasm::MemoryIndex, - dst_heap: ir::Heap, + dst_heap: cranelift_wasm::Heap, dst: ir::Value, src: ir::Value, len: ir::Value, @@ -412,7 +420,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, dst: ir::Value, val: ir::Value, len: ir::Value, @@ -425,7 +433,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, seg_index: u32, dst: ir::Value, src: ir::Value, @@ -574,7 +582,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, addr: ir::Value, expected: ir::Value, timeout: ir::Value, @@ -587,7 +595,7 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { &mut self, pos: cranelift_codegen::cursor::FuncCursor, index: cranelift_wasm::MemoryIndex, - heap: ir::Heap, + heap: cranelift_wasm::Heap, addr: ir::Value, count: ir::Value, ) -> cranelift_wasm::WasmResult { @@ -598,4 +606,11 @@ impl<'a> FuncEnvironment for FuncEnv<'a> { fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { self.inner.unsigned_add_overflow_condition() } + + fn heaps( + &self, + ) -> &cranelift_codegen::entity::PrimaryMap + { + self.inner.heaps() + } } diff --git a/cranelift/frontend/src/frontend.rs b/cranelift/frontend/src/frontend.rs index 89949c679c17..2de86095779b 100644 --- a/cranelift/frontend/src/frontend.rs +++ b/cranelift/frontend/src/frontend.rs @@ -8,10 +8,10 @@ use cranelift_codegen::ir; use cranelift_codegen::ir::condcodes::IntCC; use cranelift_codegen::ir::{ types, AbiParam, Block, DataFlowGraph, DynamicStackSlot, DynamicStackSlotData, ExtFuncData, - ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Heap, HeapData, Inst, - InstBuilder, InstBuilderBase, InstructionData, JumpTable, JumpTableData, LibCall, MemFlags, - RelSourceLoc, SigRef, Signature, StackSlot, StackSlotData, Type, Value, ValueLabel, - ValueLabelAssignments, ValueLabelStart, + ExternalName, FuncRef, Function, GlobalValue, GlobalValueData, Inst, InstBuilder, + InstBuilderBase, InstructionData, JumpTable, JumpTableData, LibCall, MemFlags, RelSourceLoc, + SigRef, Signature, StackSlot, StackSlotData, Type, Value, ValueLabel, ValueLabelAssignments, + ValueLabelStart, }; use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_codegen::packed_option::PackedOption; @@ -512,11 +512,6 @@ impl<'a> FunctionBuilder<'a> { self.func.create_global_value(data) } - /// Declares a heap accessible to the function. - pub fn create_heap(&mut self, data: HeapData) -> Heap { - self.func.create_heap(data) - } - /// Returns an object with the [`InstBuilder`](cranelift_codegen::ir::InstBuilder) /// trait that allows to conveniently append an instruction to the current `Block` being built. pub fn ins<'short>(&'short mut self) -> FuncInstBuilder<'short, 'a> { diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs index 61d22b991a2a..dd572ced9e91 100644 --- a/cranelift/fuzzgen/src/function_generator.rs +++ b/cranelift/fuzzgen/src/function_generator.rs @@ -1209,8 +1209,8 @@ where builder: &mut FunctionBuilder, min_size: u32, ) -> Result<(Value, Offset32)> { - // TODO: Currently our only source of addresses is stack_addr, but we should - // add heap_addr, global_value, symbol_value eventually + // TODO: Currently our only source of addresses is stack_addr, but we + // should add global_value, symbol_value eventually let (addr, available_size) = { let (ss, slot_size) = self.stack_slot_with_size(min_size)?; let max_offset = slot_size.saturating_sub(min_size); diff --git a/cranelift/interpreter/src/interpreter.rs b/cranelift/interpreter/src/interpreter.rs index 022b82770c3e..85f9fca53095 100644 --- a/cranelift/interpreter/src/interpreter.rs +++ b/cranelift/interpreter/src/interpreter.rs @@ -11,12 +11,12 @@ use crate::step::{step, ControlFlow, StepError}; use crate::value::{Value, ValueError}; use cranelift_codegen::data_value::DataValue; use cranelift_codegen::ir::{ - ArgumentPurpose, Block, FuncRef, Function, GlobalValue, GlobalValueData, Heap, LibCall, - StackSlot, TrapCode, Type, Value as ValueRef, + ArgumentPurpose, Block, FuncRef, Function, GlobalValue, GlobalValueData, LibCall, StackSlot, + TrapCode, Type, Value as ValueRef, }; use log::trace; use smallvec::SmallVec; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; use std::fmt::Debug; use std::iter; use thiserror::Error; @@ -175,21 +175,6 @@ pub enum InterpreterError { FuelExhausted, } -pub type HeapBacking = Vec; - -/// Represents a registered heap with an interpreter. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct HeapId(u32); - -/// Options for initializing a heap memory region -#[derive(Debug)] -pub enum HeapInit { - /// A zero initialized heap with `size` bytes - Zeroed(usize), - /// Initializes the heap with the backing memory unchanged. - FromBacking(HeapBacking), -} - pub type LibCallValues = SmallVec<[V; 1]>; pub type LibCallHandler = fn(LibCall, LibCallValues) -> Result, TrapCode>; @@ -201,7 +186,6 @@ pub struct InterpreterState<'a> { /// Number of bytes from the bottom of the stack where the current frame's stack space is pub frame_offset: usize, pub stack: Vec, - pub heaps: Vec, pub pinned_reg: DataValue, } @@ -213,7 +197,6 @@ impl Default for InterpreterState<'_> { frame_stack: vec![], frame_offset: 0, stack: Vec::with_capacity(1024), - heaps: Vec::new(), pinned_reg: DataValue::U64(0), } } @@ -230,57 +213,6 @@ impl<'a> InterpreterState<'a> { self } - /// Registers a static heap and returns a reference to it - /// - /// This heap reference can be used to generate a heap pointer, which - /// can be used inside the interpreter to load / store values into the heap. - /// - /// ```rust - /// # use cranelift_codegen::ir::types::I64; - /// # use cranelift_interpreter::interpreter::{InterpreterState, HeapInit}; - /// let mut state = InterpreterState::default(); - /// let heap0 = state.register_heap(HeapInit::Zeroed(1024)); - /// - /// let backing = Vec::from([10u8; 24]); - /// let heap1 = state.register_heap(HeapInit::FromBacking(backing)); - /// ``` - pub fn register_heap(&mut self, init: HeapInit) -> HeapId { - let heap_id = HeapId(self.heaps.len() as u32); - - self.heaps.push(match init { - HeapInit::Zeroed(size) => iter::repeat(0).take(size).collect(), - HeapInit::FromBacking(backing) => backing, - }); - - heap_id - } - - /// Returns a heap address that can be used inside the interpreter - /// - /// ```rust - /// # use cranelift_codegen::ir::types::I64; - /// # use cranelift_interpreter::interpreter::{InterpreterState, HeapInit}; - /// let mut state = InterpreterState::default(); - /// let heap_id = state.register_heap(HeapInit::Zeroed(1024)); - /// let heap_base = state.get_heap_address(I64, heap_id, 0); - /// let heap_bound = state.get_heap_address(I64, heap_id, 1024); - /// ``` - pub fn get_heap_address( - &self, - ty: Type, - heap_id: HeapId, - offset: u64, - ) -> Result { - let size = AddressSize::try_from(ty)?; - let heap_id = heap_id.0 as u64; - let addr = Address::from_parts(size, AddressRegion::Heap, heap_id, offset)?; - - self.validate_address(&addr)?; - let dv = addr.try_into()?; - - Ok(dv) - } - fn current_frame_mut(&mut self) -> &mut Frame<'a> { let num_frames = self.frame_stack.len(); match num_frames { @@ -371,33 +303,6 @@ impl<'a> State<'a, DataValue> for InterpreterState<'a> { Address::from_parts(size, AddressRegion::Stack, 0, final_offset) } - /// Builds an [Address] for the [Heap] referenced in the currently executing function. - /// - /// A CLIF Heap is essentially a GlobalValue and some metadata about that memory - /// region, such as bounds. Since heaps are based on Global Values it means that - /// once that GV is resolved we can essentially end up anywhere in memory. - /// - /// To build an [Address] we perform GV resolution, and try to ensure that we end up - /// in a valid region of memory. - fn heap_address( - &self, - size: AddressSize, - heap: Heap, - offset: u64, - ) -> Result { - let heap_data = &self.get_current_function().heaps[heap]; - let heap_base = self.resolve_global_value(heap_data.base)?; - let mut addr = Address::try_from(heap_base)?; - addr.size = size; - addr.offset += offset; - - // After resolving the address can point anywhere, we need to check if it's - // still valid. - self.validate_address(&addr)?; - - Ok(addr) - } - fn checked_load(&self, addr: Address, ty: Type) -> Result { let load_size = ty.bytes() as usize; let addr_start = addr.offset as usize; @@ -411,14 +316,6 @@ impl<'a> State<'a, DataValue> for InterpreterState<'a> { &self.stack[addr_start..addr_end] } - AddressRegion::Heap => { - let heap_mem = match self.heaps.get(addr.entry as usize) { - Some(mem) if addr_end <= mem.len() => mem, - _ => return Err(MemoryError::OutOfBoundsLoad { addr, load_size }), - }; - - &heap_mem[addr_start..addr_end] - } _ => unimplemented!(), }; @@ -438,14 +335,6 @@ impl<'a> State<'a, DataValue> for InterpreterState<'a> { &mut self.stack[addr_start..addr_end] } - AddressRegion::Heap => { - let heap_mem = match self.heaps.get_mut(addr.entry as usize) { - Some(mem) if addr_end <= mem.len() => mem, - _ => return Err(MemoryError::OutOfBoundsStore { addr, store_size }), - }; - - &mut heap_mem[addr_start..addr_end] - } _ => unimplemented!(), }; @@ -561,24 +450,7 @@ impl<'a> State<'a, DataValue> for InterpreterState<'a> { if addr.offset > stack_len { return Err(MemoryError::InvalidEntry { entry: addr.entry, - max: self.heaps.len() as u64, - }); - } - } - AddressRegion::Heap => { - let heap_len = self - .heaps - .get(addr.entry as usize) - .ok_or_else(|| MemoryError::InvalidEntry { - entry: addr.entry, - max: self.heaps.len() as u64, - }) - .map(|heap| heap.len() as u64)?; - - if addr.offset > heap_len { - return Err(MemoryError::InvalidOffset { - offset: addr.offset, - max: heap_len, + max: self.stack.len() as u64, }); } } @@ -602,7 +474,6 @@ mod tests { use super::*; use crate::step::CraneliftTrap; use cranelift_codegen::ir::immediates::Ieee32; - use cranelift_codegen::ir::types::I64; use cranelift_codegen::ir::TrapCode; use cranelift_reader::parse_functions; use smallvec::smallvec; @@ -957,53 +828,6 @@ mod tests { assert_eq!(trap, CraneliftTrap::User(TrapCode::HeapOutOfBounds)); } - /// Most heap tests are in .clif files using the filetest machinery. However, this is a sanity - /// check that the heap mechanism works without the rest of the filetest infrastructure - #[test] - fn heap_sanity_test() { - let code = " - function %heap_load_store(i64 vmctx) -> i8 { - gv0 = vmctx - gv1 = load.i64 notrap aligned gv0+0 - ; gv2/3 do nothing, but makes sure we understand the iadd_imm mechanism - gv2 = iadd_imm.i64 gv1, 1 - gv3 = iadd_imm.i64 gv2, -1 - heap0 = static gv3, min 0x1000, bound 0x1_0000_0000, offset_guard 0, index_type i64 - - block0(v0: i64): - v1 = iconst.i64 0 - v2 = iconst.i64 123 - v3 = heap_addr.i64 heap0, v1, 0, 8 - store.i64 v2, v3 - v4 = load.i64 v3 - v5 = icmp eq v2, v4 - return v5 - }"; - - let func = parse_functions(code).unwrap().into_iter().next().unwrap(); - let mut env = FunctionStore::default(); - env.add(func.name.to_string(), &func); - let mut state = InterpreterState::default().with_function_store(env); - - let heap0 = state.register_heap(HeapInit::Zeroed(0x1000)); - let base_addr = state.get_heap_address(I64, heap0, 0).unwrap(); - - // Build a vmctx struct by writing the base pointer at index 0 - let mut vmctx_struct = vec![0u8; 8]; - base_addr.write_to_slice(&mut vmctx_struct[..]); - - // This is our vmctx "heap" - let vmctx = state.register_heap(HeapInit::FromBacking(vmctx_struct)); - let vmctx_addr = state.get_heap_address(I64, vmctx, 0).unwrap(); - - let result = Interpreter::new(state) - .call_by_name("%heap_load_store", &[vmctx_addr]) - .unwrap() - .unwrap_return(); - - assert_eq!(result, vec![DataValue::I8(1)]) - } - #[test] fn srem_trap() { let code = "function %test() -> i64 { diff --git a/cranelift/interpreter/src/state.rs b/cranelift/interpreter/src/state.rs index 868266d7b7ad..49526e4a8302 100644 --- a/cranelift/interpreter/src/state.rs +++ b/cranelift/interpreter/src/state.rs @@ -3,7 +3,7 @@ use crate::address::{Address, AddressSize}; use crate::interpreter::LibCallHandler; use cranelift_codegen::data_value::DataValue; -use cranelift_codegen::ir::{FuncRef, Function, GlobalValue, Heap, StackSlot, Type, Value}; +use cranelift_codegen::ir::{FuncRef, Function, GlobalValue, StackSlot, Type, Value}; use cranelift_entity::PrimaryMap; use smallvec::SmallVec; use thiserror::Error; @@ -57,13 +57,6 @@ pub trait State<'a, V> { slot: StackSlot, offset: u64, ) -> Result; - /// Computes a heap address - fn heap_address( - &self, - size: AddressSize, - heap: Heap, - offset: u64, - ) -> Result; /// Retrieve a value `V` from memory at the given `address`, checking if it belongs either to the /// stack or to one of the heaps; the number of bytes loaded corresponds to the specified [Type]. fn checked_load(&self, address: Address, ty: Type) -> Result; @@ -149,15 +142,6 @@ where unimplemented!() } - fn heap_address( - &self, - _size: AddressSize, - _heap: Heap, - _offset: u64, - ) -> Result { - unimplemented!() - } - fn checked_load(&self, _addr: Address, _ty: Type) -> Result { unimplemented!() } diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 5bb2b1e5a42a..4fc0b9676168 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -6,7 +6,6 @@ use crate::state::{MemoryError, State}; use crate::value::{Value, ValueConversionKind, ValueError, ValueResult}; use cranelift_codegen::data_value::DataValue; use cranelift_codegen::ir::condcodes::{FloatCC, IntCC}; -use cranelift_codegen::ir::immediates::HeapImmData; use cranelift_codegen::ir::{ types, AbiParam, Block, ExternalName, FuncRef, Function, InstructionData, Opcode, TrapCode, Type, Value as ValueRef, @@ -485,89 +484,6 @@ where } Opcode::SymbolValue => unimplemented!("SymbolValue"), Opcode::TlsValue => unimplemented!("TlsValue"), - Opcode::HeapLoad => { - if let InstructionData::HeapLoad { heap_imm, arg, .. } = inst { - let HeapImmData { - flags, - heap, - offset, - } = state.get_current_function().dfg.heap_imms[heap_imm]; - let offset = i128::from(u32::from(offset)); - let addr_ty = state.get_current_function().dfg.value_type(arg); - let index = state.get_value(arg).unwrap().into_int().unwrap(); - let load_ty = inst_context.controlling_type().unwrap(); - let load_size = i128::from(load_ty.bytes()); - assign_or_memtrap(AddressSize::try_from(addr_ty).and_then(|addr_size| { - let heap_address = index.saturating_add(offset).saturating_add(load_size); - let heap_address = - u64::try_from(heap_address).map_err(|e| MemoryError::OutOfBoundsLoad { - addr: Address::try_from(0).unwrap(), - load_size: load_size as usize, - })?; - let address = state.heap_address(addr_size, heap, heap_address)?; - state.checked_load(address, load_ty) - })) - } else { - unreachable!() - } - } - Opcode::HeapStore => { - if let InstructionData::HeapStore { heap_imm, args, .. } = inst { - let HeapImmData { - flags, - heap, - offset, - } = state.get_current_function().dfg.heap_imms[heap_imm]; - let offset = i128::from(u32::from(offset)); - let addr_ty = state.get_current_function().dfg.value_type(args[0]); - let index = state.get_value(args[0]).unwrap().into_int().unwrap(); - let value = state.get_value(args[1]).unwrap(); - let store_ty = state.get_current_function().dfg.value_type(args[1]); - let store_size = i128::from(store_ty.bytes()); - continue_or_memtrap(AddressSize::try_from(addr_ty).and_then(|addr_size| { - let heap_address = index.saturating_add(offset).saturating_add(store_size); - let heap_address = - u64::try_from(heap_address).map_err(|e| MemoryError::OutOfBoundsStore { - addr: Address::try_from(0).unwrap(), - store_size: store_size as usize, - })?; - let address = state.heap_address(addr_size, heap, heap_address)?; - state.checked_store(address, value) - })) - } else { - unreachable!() - } - } - Opcode::HeapAddr => { - if let InstructionData::HeapAddr { - heap, - offset: imm_offset, - size, - .. - } = inst - { - let addr_ty = inst_context.controlling_type().unwrap(); - let dyn_offset = arg(0)?.into_int()? as u64; - assign_or_memtrap({ - AddressSize::try_from(addr_ty).and_then(|addr_size| { - // Attempt to build an address at the maximum possible offset - // for this load. If address generation fails we know it's out of bounds. - let bound_offset = - (dyn_offset + u64::from(u32::from(imm_offset)) + u64::from(size)) - .saturating_sub(1); - state.heap_address(addr_size, heap, bound_offset)?; - - // Build the actual address - let mut addr = state.heap_address(addr_size, heap, dyn_offset)?; - addr.offset += u64::from(u32::from(imm_offset)); - let dv = DataValue::try_from(addr)?; - Ok(dv.into()) - }) - }) - } else { - unreachable!() - } - } Opcode::GetPinnedReg => assign(state.get_pinned_reg()), Opcode::SetPinnedReg => { let arg0 = arg(0)?; diff --git a/cranelift/reader/src/heap_command.rs b/cranelift/reader/src/heap_command.rs deleted file mode 100644 index 280482eff8f5..000000000000 --- a/cranelift/reader/src/heap_command.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Heap commands. -//! -//! Functions in a `.clif` file can have *heap commands* appended that control the heaps allocated -//! by the `test run` and `test interpret` infrastructure. -//! -//! The general syntax is: -//! - `; heap: , size=n` -//! -//! `heap_type` can have two values: -//! - `static`: This is a non resizable heap type with a fixed size -//! - `dynamic`: This is a resizable heap, which can grow -//! -//! `size=n` indicates the size of the heap. For dynamic heaps, it indicates the starting size of -//! the heap. - -use cranelift_codegen::ir::immediates::Uimm64; -use std::fmt::{self, Display, Formatter}; - -/// A heap command appearing in a test file. -/// -/// For parsing, see `Parser::parse_heap_command` -#[derive(PartialEq, Debug, Clone)] -pub struct HeapCommand { - /// Indicates the requested heap type - pub heap_type: HeapType, - /// Size of the heap. - /// - /// For dynamic heaps this is the starting size. For static heaps, this is the total size. - pub size: Uimm64, - /// Offset of the heap pointer from the vmctx base - /// - /// This is done for verification purposes only - pub ptr_offset: Option, - /// Offset of the bound pointer from the vmctx base - /// - /// This is done for verification purposes only - pub bound_offset: Option, -} - -impl Display for HeapCommand { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "heap: {}, size={}", self.heap_type, self.size)?; - - if let Some(offset) = self.ptr_offset { - write!(f, ", ptr=vmctx+{}", offset)? - } - - if let Some(offset) = self.bound_offset { - write!(f, ", bound=vmctx+{}", offset)? - } - - Ok(()) - } -} - -/// CLIF Representation of a heap type. e.g.: `static` -#[allow(missing_docs)] -#[derive(Debug, PartialEq, Clone)] -pub enum HeapType { - Static, - Dynamic, -} - -impl Display for HeapType { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - HeapType::Static => write!(f, "static"), - HeapType::Dynamic => write!(f, "dynamic"), - } - } -} diff --git a/cranelift/reader/src/lexer.rs b/cranelift/reader/src/lexer.rs index cbf847399d3c..6622c52549dd 100644 --- a/cranelift/reader/src/lexer.rs +++ b/cranelift/reader/src/lexer.rs @@ -40,7 +40,6 @@ pub enum Token<'a> { StackSlot(u32), // ss3 DynamicStackSlot(u32), // dss4 GlobalValue(u32), // gv3 - Heap(u32), // heap2 Table(u32), // table2 JumpTable(u32), // jt2 Constant(u32), // const2 @@ -346,7 +345,6 @@ impl<'a> Lexer<'a> { "dss" => Some(Token::DynamicStackSlot(number)), "dt" => Some(Token::DynamicType(number)), "gv" => Some(Token::GlobalValue(number)), - "heap" => Some(Token::Heap(number)), "table" => Some(Token::Table(number)), "jt" => Some(Token::JumpTable(number)), "const" => Some(Token::Constant(number)), diff --git a/cranelift/reader/src/lib.rs b/cranelift/reader/src/lib.rs index 5307e1d4c6f9..b627d69b19d8 100644 --- a/cranelift/reader/src/lib.rs +++ b/cranelift/reader/src/lib.rs @@ -26,18 +26,14 @@ )] pub use crate::error::{Location, ParseError, ParseResult}; -pub use crate::heap_command::{HeapCommand, HeapType}; pub use crate::isaspec::{parse_options, IsaSpec, ParseOptionError}; -pub use crate::parser::{ - parse_functions, parse_heap_command, parse_run_command, parse_test, ParseOptions, -}; +pub use crate::parser::{parse_functions, parse_run_command, parse_test, ParseOptions}; pub use crate::run_command::{Comparison, Invocation, RunCommand}; pub use crate::sourcemap::SourceMap; pub use crate::testcommand::{TestCommand, TestOption}; pub use crate::testfile::{Comment, Details, Feature, TestFile}; mod error; -mod heap_command; mod isaspec; mod lexer; mod parser; diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs index baf0bc0a9334..57629a02ff08 100644 --- a/cranelift/reader/src/parser.rs +++ b/cranelift/reader/src/parser.rs @@ -1,7 +1,6 @@ //! Parser for .clif files. use crate::error::{Location, ParseError, ParseResult}; -use crate::heap_command::{HeapCommand, HeapType}; use crate::isaspec; use crate::lexer::{LexError, Lexer, LocatedError, LocatedToken, Token}; use crate::run_command::{Comparison, Invocation, RunCommand}; @@ -11,9 +10,7 @@ use crate::testfile::{Comment, Details, Feature, TestFile}; use cranelift_codegen::data_value::DataValue; use cranelift_codegen::entity::{EntityRef, PrimaryMap}; use cranelift_codegen::ir::entities::{AnyEntity, DynamicType}; -use cranelift_codegen::ir::immediates::{ - HeapImmData, Ieee32, Ieee64, Imm64, Offset32, Uimm32, Uimm64, -}; +use cranelift_codegen::ir::immediates::{Ieee32, Ieee64, Imm64, Offset32, Uimm32, Uimm64}; use cranelift_codegen::ir::instructions::{InstructionData, InstructionFormat, VariableArgs}; use cranelift_codegen::ir::types::INVALID; use cranelift_codegen::ir::types::*; @@ -21,9 +18,8 @@ use cranelift_codegen::ir::{self, UserExternalNameRef}; use cranelift_codegen::ir::{ AbiParam, ArgumentExtension, ArgumentPurpose, Block, Constant, ConstantData, DynamicStackSlot, DynamicStackSlotData, DynamicTypeData, ExtFuncData, ExternalName, FuncRef, Function, - GlobalValue, GlobalValueData, Heap, HeapData, HeapStyle, JumpTable, JumpTableData, MemFlags, - Opcode, SigRef, Signature, StackSlot, StackSlotData, StackSlotKind, Table, TableData, Type, - UserFuncName, Value, + GlobalValue, GlobalValueData, JumpTable, JumpTableData, MemFlags, Opcode, SigRef, Signature, + StackSlot, StackSlotData, StackSlotKind, Table, TableData, Type, UserFuncName, Value, }; use cranelift_codegen::isa::{self, CallConv}; use cranelift_codegen::packed_option::ReservedValue; @@ -189,24 +185,6 @@ pub fn parse_run_command<'a>(text: &str, signature: &Signature) -> ParseResult(text: &str) -> ParseResult> { - let _tt = timing::parse_text(); - // We remove leading spaces and semi-colons for convenience here instead of at the call sites - // since this function will be attempting to parse a HeapCommand from a CLIF comment. - let trimmed_text = text.trim_start_matches(|c| c == ' ' || c == ';'); - let mut parser = Parser::new(trimmed_text); - match parser.token() { - Some(Token::Identifier("heap")) => parser.parse_heap_command().map(|c| Some(c)), - Some(_) | None => Ok(None), - } -} - pub struct Parser<'a> { lex: Lexer<'a>, @@ -340,33 +318,6 @@ impl Context { } } - // Allocate a heap slot. - fn add_heap(&mut self, heap: Heap, data: HeapData, loc: Location) -> ParseResult<()> { - self.map.def_heap(heap, loc)?; - while self.function.heaps.next_key().index() <= heap.index() { - self.function.create_heap(HeapData { - base: GlobalValue::reserved_value(), - min_size: Uimm64::new(0), - offset_guard_size: Uimm64::new(0), - style: HeapStyle::Static { - bound: Uimm64::new(0), - }, - index_type: INVALID, - }); - } - self.function.heaps[heap] = data; - Ok(()) - } - - // Resolve a reference to a heap. - fn check_heap(&self, heap: Heap, loc: Location) -> ParseResult<()> { - if !self.map.contains_heap(heap) { - err!(loc, "undefined heap {}", heap) - } else { - Ok(()) - } - } - // Allocate a table slot. fn add_table(&mut self, table: Table, data: TableData, loc: Location) -> ParseResult<()> { while self.function.tables.next_key().index() <= table.index() { @@ -708,17 +659,6 @@ impl<'a> Parser<'a> { err!(self.loc, err_msg) } - // Match and consume a heap reference. - fn match_heap(&mut self, err_msg: &str) -> ParseResult { - if let Some(Token::Heap(heap)) = self.token() { - self.consume(); - if let Some(heap) = Heap::with_number(heap) { - return Ok(heap); - } - } - err!(self.loc, err_msg) - } - // Match and consume a table reference. fn match_table(&mut self, err_msg: &str) -> ParseResult
{ if let Some(Token::Table(table)) = self.token() { @@ -878,19 +818,6 @@ impl<'a> Parser<'a> { } } - // Match and consume an optional uimm32 offset immediate. - // - // Note that this will match an empty string as an empty offset, and that if an offset is - // present, it must contain a plus sign. - fn optional_uimm32_offset(&mut self) -> ParseResult { - match self.token() { - Some(Token::Integer(x)) if x.starts_with('+') => { - self.match_uimm32("expected a uimm32 offset immediate") - } - _ => Ok(Uimm32::from(0)), - } - } - // Match and consume a u8 immediate. // This is used for lane numbers in SIMD vectors. fn match_uimm8(&mut self, err_msg: &str) -> ParseResult { @@ -1541,11 +1468,6 @@ impl<'a> Parser<'a> { self.parse_global_value_decl() .and_then(|(gv, dat)| ctx.add_gv(gv, dat, self.loc)) } - Some(Token::Heap(..)) => { - self.start_gathering_comments(); - self.parse_heap_decl() - .and_then(|(heap, dat)| ctx.add_heap(heap, dat, self.loc)) - } Some(Token::Table(..)) => { self.start_gathering_comments(); self.parse_table_decl() @@ -1733,77 +1655,6 @@ impl<'a> Parser<'a> { Ok((gv, data)) } - // Parse a heap decl. - // - // heap-decl ::= * Heap(heap) "=" heap-desc - // heap-desc ::= heap-style heap-base { "," heap-attr } - // heap-style ::= "static" | "dynamic" - // heap-base ::= GlobalValue(base) - // heap-attr ::= "min" Imm64(bytes) - // | "bound" Imm64(bytes) - // | "offset_guard" Imm64(bytes) - // | "index_type" type - // - fn parse_heap_decl(&mut self) -> ParseResult<(Heap, HeapData)> { - let heap = self.match_heap("expected heap number: heap«n»")?; - self.match_token(Token::Equal, "expected '=' in heap declaration")?; - - let style_name = self.match_any_identifier("expected 'static' or 'dynamic'")?; - - // heap-desc ::= heap-style * heap-base { "," heap-attr } - // heap-base ::= * GlobalValue(base) - let base = match self.token() { - Some(Token::GlobalValue(base_num)) => match GlobalValue::with_number(base_num) { - Some(gv) => gv, - None => return err!(self.loc, "invalid global value number for heap base"), - }, - _ => return err!(self.loc, "expected heap base"), - }; - self.consume(); - - let mut data = HeapData { - base, - min_size: 0.into(), - offset_guard_size: 0.into(), - style: HeapStyle::Static { bound: 0.into() }, - index_type: ir::types::I32, - }; - - // heap-desc ::= heap-style heap-base * { "," heap-attr } - while self.optional(Token::Comma) { - match self.match_any_identifier("expected heap attribute name")? { - "min" => { - data.min_size = self.match_uimm64("expected integer min size")?; - } - "bound" => { - data.style = match style_name { - "dynamic" => HeapStyle::Dynamic { - bound_gv: self.match_gv("expected gv bound")?, - }, - "static" => HeapStyle::Static { - bound: self.match_uimm64("expected integer bound")?, - }, - t => return err!(self.loc, "unknown heap style '{}'", t), - }; - } - "offset_guard" => { - data.offset_guard_size = - self.match_uimm64("expected integer offset-guard size")?; - } - "index_type" => { - data.index_type = self.match_type("expected index type")?; - } - t => return err!(self.loc, "unknown heap attribute '{}'", t), - } - } - - // Collect any trailing comments. - self.token(); - self.claim_gathered_comments(heap); - - Ok((heap, data)) - } - // Parse a table decl. // // table-decl ::= * Table(table) "=" table-desc @@ -2457,86 +2308,6 @@ impl<'a> Parser<'a> { Ok(args) } - /// Parse a vmctx offset annotation - /// - /// vmctx-offset ::= "vmctx" "+" UImm64(offset) - fn parse_vmctx_offset(&mut self) -> ParseResult { - self.match_token(Token::Identifier("vmctx"), "expected a 'vmctx' token")?; - - // The '+' token here gets parsed as part of the integer text, so we can't just match_token it - // and `match_uimm64` doesn't support leading '+' tokens, so we can't use that either. - match self.token() { - Some(Token::Integer(text)) if text.starts_with('+') => { - self.consume(); - - text[1..] - .parse() - .map_err(|_| self.error("expected u64 decimal immediate")) - } - token => err!( - self.loc, - format!("Unexpected token {:?} after vmctx", token) - ), - } - } - - /// Parse a CLIF heap command. - /// - /// heap-command ::= "heap" ":" heap-type { "," heap-attr } - /// heap-attr ::= "size" "=" UImm64(bytes) - fn parse_heap_command(&mut self) -> ParseResult { - self.match_token(Token::Identifier("heap"), "expected a 'heap:' command")?; - self.match_token(Token::Colon, "expected a ':' after heap command")?; - - let mut heap_command = HeapCommand { - heap_type: self.parse_heap_type()?, - size: Uimm64::new(0), - ptr_offset: None, - bound_offset: None, - }; - - while self.optional(Token::Comma) { - let identifier = self.match_any_identifier("expected heap attribute name")?; - self.match_token(Token::Equal, "expected '=' after heap attribute name")?; - - match identifier { - "size" => { - heap_command.size = self.match_uimm64("expected integer size")?; - } - "ptr" => { - heap_command.ptr_offset = Some(self.parse_vmctx_offset()?); - } - "bound" => { - heap_command.bound_offset = Some(self.parse_vmctx_offset()?); - } - t => return err!(self.loc, "unknown heap attribute '{}'", t), - } - } - - if heap_command.size == Uimm64::new(0) { - return err!(self.loc, self.error("Expected a heap size to be specified")); - } - - Ok(heap_command) - } - - /// Parse a heap type. - /// - /// heap-type ::= "static" | "dynamic" - fn parse_heap_type(&mut self) -> ParseResult { - match self.token() { - Some(Token::Identifier("static")) => { - self.consume(); - Ok(HeapType::Static) - } - Some(Token::Identifier("dynamic")) => { - self.consume(); - Ok(HeapType::Dynamic) - } - _ => Err(self.error("expected a heap type, e.g. static or dynamic")), - } - } - /// Parse a CLIF run command. /// /// run-command ::= "run" [":" invocation comparison expected] @@ -2974,59 +2745,6 @@ impl<'a> Parser<'a> { dynamic_stack_slot: dss, } } - InstructionFormat::HeapAddr => { - let heap = self.match_heap("expected heap identifier")?; - ctx.check_heap(heap, self.loc)?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let arg = self.match_value("expected SSA value heap address")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let offset = self.match_uimm32("expected 32-bit integer offset")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let size = self.match_uimm8("expected 8-bit integer size")?; - InstructionData::HeapAddr { - opcode, - heap, - arg, - offset, - size, - } - } - InstructionFormat::HeapLoad => { - let heap = self.match_heap("expected heap identifier")?; - ctx.check_heap(heap, self.loc)?; - let flags = self.optional_memflags(); - let arg = self.match_value("expected SSA value heap index")?; - let offset = self.optional_uimm32_offset()?; - let heap_imm = ctx.function.dfg.heap_imms.push(HeapImmData { - flags, - heap, - offset, - }); - InstructionData::HeapLoad { - opcode, - heap_imm, - arg, - } - } - InstructionFormat::HeapStore => { - let heap = self.match_heap("expected heap identifier")?; - ctx.check_heap(heap, self.loc)?; - let flags = self.optional_memflags(); - let index = self.match_value("expected SSA value heap index")?; - let offset = self.optional_uimm32_offset()?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let value = self.match_value("expected SSA value to store")?; - let heap_imm = ctx.function.dfg.heap_imms.push(HeapImmData { - flags, - heap, - offset, - }); - InstructionData::HeapStore { - opcode, - heap_imm, - args: [index, value], - } - } InstructionFormat::TableAddr => { let table = self.match_table("expected table identifier")?; ctx.check_table(table, self.loc)?; @@ -3409,25 +3127,6 @@ mod tests { assert!(!is_warning); } - #[test] - fn duplicate_heap() { - let ParseError { - location, - message, - is_warning, - } = Parser::new( - "function %blocks() system_v { - heap0 = static gv0, min 0x1000, bound 0x10_0000, offset_guard 0x1000 - heap0 = static gv0, min 0x1000, bound 0x10_0000, offset_guard 0x1000", - ) - .parse_function() - .unwrap_err(); - - assert_eq!(location.line_number, 3); - assert_eq!(message, "duplicate entity: heap0"); - assert!(!is_warning); - } - #[test] fn duplicate_sig() { let ParseError { @@ -3834,45 +3533,6 @@ mod tests { assert!(parse("run: ", &sig(&[], &[])).is_err()); } - #[test] - fn parse_heap_commands() { - fn parse(text: &str) -> ParseResult { - Parser::new(text).parse_heap_command() - } - - // Check that we can parse and display the same set of heap commands. - fn assert_roundtrip(text: &str) { - assert_eq!(parse(text).unwrap().to_string(), text); - } - - assert_roundtrip("heap: static, size=10"); - assert_roundtrip("heap: dynamic, size=10"); - assert_roundtrip("heap: static, size=10, ptr=vmctx+10"); - assert_roundtrip("heap: static, size=10, bound=vmctx+11"); - assert_roundtrip("heap: static, size=10, ptr=vmctx+10, bound=vmctx+10"); - assert_roundtrip("heap: dynamic, size=10, ptr=vmctx+10"); - assert_roundtrip("heap: dynamic, size=10, bound=vmctx+11"); - assert_roundtrip("heap: dynamic, size=10, ptr=vmctx+10, bound=vmctx+10"); - - let static_heap = parse("heap: static, size=10, ptr=vmctx+8, bound=vmctx+2").unwrap(); - assert_eq!(static_heap.size, Uimm64::new(10)); - assert_eq!(static_heap.heap_type, HeapType::Static); - assert_eq!(static_heap.ptr_offset, Some(Uimm64::new(8))); - assert_eq!(static_heap.bound_offset, Some(Uimm64::new(2))); - let dynamic_heap = parse("heap: dynamic, size=0x10").unwrap(); - assert_eq!(dynamic_heap.size, Uimm64::new(16)); - assert_eq!(dynamic_heap.heap_type, HeapType::Dynamic); - assert_eq!(dynamic_heap.ptr_offset, None); - assert_eq!(dynamic_heap.bound_offset, None); - - assert!(parse("heap: static").is_err()); - assert!(parse("heap: dynamic").is_err()); - assert!(parse("heap: static size=0").is_err()); - assert!(parse("heap: dynamic size=0").is_err()); - assert!(parse("heap: static, size=10, ptr=10").is_err()); - assert!(parse("heap: static, size=10, bound=vmctx-10").is_err()); - } - #[test] fn parse_data_values() { fn parse(text: &str, ty: Type) -> DataValue { diff --git a/cranelift/reader/src/sourcemap.rs b/cranelift/reader/src/sourcemap.rs index 00425dc5863d..57be4d55ee41 100644 --- a/cranelift/reader/src/sourcemap.rs +++ b/cranelift/reader/src/sourcemap.rs @@ -10,8 +10,8 @@ use crate::error::{Location, ParseResult}; use crate::lexer::split_entity_name; use cranelift_codegen::ir::entities::{AnyEntity, DynamicType}; use cranelift_codegen::ir::{ - Block, Constant, DynamicStackSlot, FuncRef, GlobalValue, Heap, JumpTable, SigRef, StackSlot, - Table, Value, + Block, Constant, DynamicStackSlot, FuncRef, GlobalValue, JumpTable, SigRef, StackSlot, Table, + Value, }; use std::collections::HashMap; @@ -49,11 +49,6 @@ impl SourceMap { self.locations.contains_key(&gv.into()) } - /// Look up a heap entity. - pub fn contains_heap(&self, heap: Heap) -> bool { - self.locations.contains_key(&heap.into()) - } - /// Look up a table entity. pub fn contains_table(&self, table: Table) -> bool { self.locations.contains_key(&table.into()) @@ -111,13 +106,6 @@ impl SourceMap { Some(gv.into()) } }), - "heap" => Heap::with_number(num).and_then(|heap| { - if !self.contains_heap(heap) { - None - } else { - Some(heap.into()) - } - }), "table" => Table::with_number(num).and_then(|table| { if !self.contains_table(table) { None @@ -194,11 +182,6 @@ impl SourceMap { self.def_entity(entity.into(), loc) } - /// Define the heap `entity`. - pub fn def_heap(&mut self, entity: Heap, loc: Location) -> ParseResult<()> { - self.def_entity(entity.into(), loc) - } - /// Define the table `entity`. pub fn def_table(&mut self, entity: Table, loc: Location) -> ParseResult<()> { self.def_entity(entity.into(), loc) diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index e381825d8f2d..05f7d0b99186 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -71,6 +71,8 @@ //! //! ("Relax verification to allow I8X16 to act as a default vector type") +mod bounds_checks; + use super::{hash_map, HashMap}; use crate::environ::{FuncEnvironment, GlobalVariable}; use crate::state::{ControlStackFrame, ElseData, FuncTranslationState}; @@ -95,6 +97,24 @@ use std::convert::TryFrom; use std::vec::Vec; use wasmparser::{FuncValidator, MemArg, Operator, WasmModuleResources}; +/// Given an `Option`, unwrap the inner `T` or, if the option is `None`, set +/// the state to unreachable and return. +/// +/// Used in combination with calling `prepare_addr` and `prepare_atomic_addr` +/// when we can statically determine that a Wasm access will unconditionally +/// trap. +macro_rules! unwrap_or_return_unreachable_state { + ($state:ident, $value:expr) => { + match $value { + Some(x) => x, + None => { + $state.reachable = false; + return Ok(()); + } + } + }; +} + // Clippy warns about "align: _" but its important to document that the flags field is ignored #[cfg_attr( feature = "cargo-clippy", @@ -695,32 +715,50 @@ pub fn translate_operator( translate_load(memarg, ir::Opcode::Load, I8X16, builder, state, environ)?; } Operator::V128Load8x8S { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().sload8x8(flags, base, 0); state.push1(loaded); } Operator::V128Load8x8U { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().uload8x8(flags, base, 0); state.push1(loaded); } Operator::V128Load16x4S { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().sload16x4(flags, base, 0); state.push1(loaded); } Operator::V128Load16x4U { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().uload16x4(flags, base, 0); state.push1(loaded); } Operator::V128Load32x2S { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().sload32x2(flags, base, 0); state.push1(loaded); } Operator::V128Load32x2U { memarg } => { - let (flags, base) = prepare_addr(memarg, 8, builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, 8, builder, state, environ)? + ); let loaded = builder.ins().uload32x2(flags, base, 0); state.push1(loaded); } @@ -1070,7 +1108,7 @@ pub fn translate_operator( let effective_addr = if memarg.offset == 0 { addr } else { - let index_type = builder.func.heaps[heap].index_type; + let index_type = environ.heaps()[heap].index_type; let offset = builder.ins().iconst(index_type, memarg.offset as i64); builder .ins() @@ -1096,7 +1134,7 @@ pub fn translate_operator( let effective_addr = if memarg.offset == 0 { addr } else { - let index_type = builder.func.heaps[heap].index_type; + let index_type = environ.heaps()[heap].index_type; let offset = builder.ins().iconst(index_type, memarg.offset as i64); builder .ins() @@ -2193,14 +2231,19 @@ fn translate_unreachable_operator( /// generate necessary IR to validate that the heap address is correctly /// in-bounds, and various parameters are returned describing the valid *native* /// heap address if execution reaches that point. -fn prepare_addr( +/// +/// Returns `None` when the Wasm access will unconditionally trap. +fn prepare_addr( memarg: &MemArg, access_size: u8, builder: &mut FunctionBuilder, state: &mut FuncTranslationState, environ: &mut FE, -) -> WasmResult<(MemFlags, Value)> { - let addr = state.pop1(); +) -> WasmResult> +where + FE: FuncEnvironment + ?Sized, +{ + let index = state.pop1(); let heap = state.get_heap(builder.func, memarg.memory, environ)?; // How exactly the bounds check is performed here and what it's performed @@ -2276,11 +2319,14 @@ fn prepare_addr( let addr = match u32::try_from(memarg.offset) { // If our offset fits within a u32, then we can place the it into the // offset immediate of the `heap_addr` instruction. - Ok(offset) => { - builder - .ins() - .heap_addr(environ.pointer_type(), heap, addr, offset, access_size) - } + Ok(offset) => bounds_checks::bounds_check_and_compute_addr( + builder, + &*environ, + &environ.heaps()[heap], + index, + offset, + access_size, + ), // If the offset doesn't fit within a u32, then we can't pass it // directly into `heap_addr`. @@ -2309,17 +2355,26 @@ fn prepare_addr( // relatively odd/rare. In the future if needed we can look into // optimizing this more. Err(_) => { - let index_type = builder.func.heaps[heap].index_type; + let index_type = environ.heaps()[heap].index_type; let offset = builder.ins().iconst(index_type, memarg.offset as i64); - let addr = + let adjusted_index = builder .ins() - .uadd_overflow_trap(addr, offset, ir::TrapCode::HeapOutOfBounds); - builder - .ins() - .heap_addr(environ.pointer_type(), heap, addr, 0, access_size) + .uadd_overflow_trap(index, offset, ir::TrapCode::HeapOutOfBounds); + bounds_checks::bounds_check_and_compute_addr( + builder, + &*environ, + &environ.heaps()[heap], + adjusted_index, + 0, + access_size, + ) } }; + let addr = match addr { + None => return Ok(None), + Some(a) => a, + }; // Note that we don't set `is_aligned` here, even if the load instruction's // alignment immediate may says it's aligned, because WebAssembly's @@ -2334,7 +2389,7 @@ fn prepare_addr( // vmctx, stack) accesses. flags.set_heap(); - Ok((flags, addr)) + Ok(Some((flags, addr))) } fn align_atomic_addr( @@ -2372,13 +2427,16 @@ fn align_atomic_addr( } } +/// Like `prepare_addr` but for atomic accesses. +/// +/// Returns `None` when the Wasm access will unconditionally trap. fn prepare_atomic_addr( memarg: &MemArg, loaded_bytes: u8, builder: &mut FunctionBuilder, state: &mut FuncTranslationState, environ: &mut FE, -) -> WasmResult<(MemFlags, Value)> { +) -> WasmResult> { align_atomic_addr(memarg, loaded_bytes, builder, state); prepare_addr(memarg, loaded_bytes, builder, state, environ) } @@ -2392,13 +2450,16 @@ fn translate_load( state: &mut FuncTranslationState, environ: &mut FE, ) -> WasmResult<()> { - let (flags, base) = prepare_addr( - memarg, - mem_op_size(opcode, result_ty), - builder, + let (flags, base) = unwrap_or_return_unreachable_state!( state, - environ, - )?; + prepare_addr( + memarg, + mem_op_size(opcode, result_ty), + builder, + state, + environ, + )? + ); let (load, dfg) = builder .ins() .Load(opcode, result_ty, flags, Offset32::new(0), base); @@ -2417,7 +2478,10 @@ fn translate_store( let val = state.pop1(); let val_ty = builder.func.dfg.value_type(val); - let (flags, base) = prepare_addr(memarg, mem_op_size(opcode, val_ty), builder, state, environ)?; + let (flags, base) = unwrap_or_return_unreachable_state!( + state, + prepare_addr(memarg, mem_op_size(opcode, val_ty), builder, state, environ)? + ); builder .ins() .Store(opcode, val_ty, flags, Offset32::new(0), val, base); @@ -2474,13 +2538,16 @@ fn translate_atomic_rmw( arg2 = builder.ins().ireduce(access_ty, arg2); } - let (flags, addr) = prepare_atomic_addr( - memarg, - u8::try_from(access_ty.bytes()).unwrap(), - builder, + let (flags, addr) = unwrap_or_return_unreachable_state!( state, - environ, - )?; + prepare_atomic_addr( + memarg, + u8::try_from(access_ty.bytes()).unwrap(), + builder, + state, + environ, + )? + ); let mut res = builder.ins().atomic_rmw(access_ty, flags, op, addr, arg2); if access_ty != widened_ty { @@ -2528,13 +2595,16 @@ fn translate_atomic_cas( replacement = builder.ins().ireduce(access_ty, replacement); } - let (flags, addr) = prepare_atomic_addr( - memarg, - u8::try_from(access_ty.bytes()).unwrap(), - builder, + let (flags, addr) = unwrap_or_return_unreachable_state!( state, - environ, - )?; + prepare_atomic_addr( + memarg, + u8::try_from(access_ty.bytes()).unwrap(), + builder, + state, + environ, + )? + ); let mut res = builder.ins().atomic_cas(flags, addr, expected, replacement); if access_ty != widened_ty { res = builder.ins().uextend(widened_ty, res); @@ -2568,13 +2638,16 @@ fn translate_atomic_load( }; assert!(w_ty_ok && widened_ty.bytes() >= access_ty.bytes()); - let (flags, addr) = prepare_atomic_addr( - memarg, - u8::try_from(access_ty.bytes()).unwrap(), - builder, + let (flags, addr) = unwrap_or_return_unreachable_state!( state, - environ, - )?; + prepare_atomic_addr( + memarg, + u8::try_from(access_ty.bytes()).unwrap(), + builder, + state, + environ, + )? + ); let mut res = builder.ins().atomic_load(access_ty, flags, addr); if access_ty != widened_ty { res = builder.ins().uextend(widened_ty, res); @@ -2614,13 +2687,16 @@ fn translate_atomic_store( data = builder.ins().ireduce(access_ty, data); } - let (flags, addr) = prepare_atomic_addr( - memarg, - u8::try_from(access_ty.bytes()).unwrap(), - builder, + let (flags, addr) = unwrap_or_return_unreachable_state!( state, - environ, - )?; + prepare_atomic_addr( + memarg, + u8::try_from(access_ty.bytes()).unwrap(), + builder, + state, + environ, + )? + ); builder.ins().atomic_store(flags, data, addr); Ok(()) } diff --git a/cranelift/codegen/src/legalizer/heap.rs b/cranelift/wasm/src/code_translator/bounds_checks.rs similarity index 52% rename from cranelift/codegen/src/legalizer/heap.rs rename to cranelift/wasm/src/code_translator/bounds_checks.rs index d294772f2330..406e60863eb7 100644 --- a/cranelift/codegen/src/legalizer/heap.rs +++ b/cranelift/wasm/src/code_translator/bounds_checks.rs @@ -1,131 +1,47 @@ -//! Legalization of heaps. +//! Implementation of Wasm to CLIF memory access translation. //! -//! This module exports the `expand_heap_addr` function which transforms a `heap_addr` -//! instruction into code that depends on the kind of heap referenced. - -use crate::cursor::{Cursor, FuncCursor}; -use crate::flowgraph::ControlFlowGraph; -use crate::ir::condcodes::IntCC; -use crate::ir::immediates::{HeapImmData, Offset32, Uimm32, Uimm8}; -use crate::ir::{self, InstBuilder, RelSourceLoc}; -use crate::isa::TargetIsa; -use crate::trace; - -/// Expand a `heap_load` instruction according to the definition of the heap. -pub fn expand_heap_load( - inst: ir::Inst, - func: &mut ir::Function, - cfg: &mut ControlFlowGraph, - isa: &dyn TargetIsa, - heap_imm: ir::HeapImm, - index: ir::Value, -) { - let HeapImmData { - flags, - heap, - offset, - } = func.dfg.heap_imms[heap_imm]; - - let result_ty = func.dfg.ctrl_typevar(inst); - let access_size = result_ty.bytes(); - let access_size = u8::try_from(access_size).unwrap(); - - let mut pos = FuncCursor::new(func).at_inst(inst); - pos.use_srcloc(inst); - - let addr = - bounds_check_and_compute_addr(&mut pos, cfg, isa, heap, index, offset.into(), access_size); - - pos.func - .dfg - .replace(inst) - .load(result_ty, flags, addr, Offset32::new(0)); -} - -/// Expand a `heap_store` instruction according to the definition of the heap. -pub fn expand_heap_store( - inst: ir::Inst, - func: &mut ir::Function, - cfg: &mut ControlFlowGraph, - isa: &dyn TargetIsa, - heap_imm: ir::HeapImm, - index: ir::Value, - value: ir::Value, -) { - let HeapImmData { - flags, - heap, - offset, - } = func.dfg.heap_imms[heap_imm]; - - let store_ty = func.dfg.value_type(value); - let access_size = u8::try_from(store_ty.bytes()).unwrap(); - - let mut pos = FuncCursor::new(func).at_inst(inst); - pos.use_srcloc(inst); - - let addr = - bounds_check_and_compute_addr(&mut pos, cfg, isa, heap, index, offset.into(), access_size); - - pos.func - .dfg - .replace(inst) - .store(flags, value, addr, Offset32::new(0)); -} - -/// Expand a `heap_addr` instruction according to the definition of the heap. -pub fn expand_heap_addr( - inst: ir::Inst, - func: &mut ir::Function, - cfg: &mut ControlFlowGraph, - isa: &dyn TargetIsa, - heap: ir::Heap, - index: ir::Value, - offset: Uimm32, - access_size: Uimm8, -) { - let mut pos = FuncCursor::new(func).at_inst(inst); - pos.use_srcloc(inst); - - let addr = - bounds_check_and_compute_addr(&mut pos, cfg, isa, heap, index, offset.into(), access_size); +//! Given +//! +//! * a dynamic Wasm memory index operand, +//! * a static offset immediate, and +//! * a static access size, +//! +//! bounds check the memory access and translate it into a native memory access. - // Replace the `heap_addr` and its result value with the legalized native - // address. - let addr_inst = pos.func.dfg.value_def(addr).unwrap_inst(); - pos.func.dfg.replace_with_aliases(inst, addr_inst); - pos.func.layout.remove_inst(inst); -} +use crate::{HeapData, HeapStyle, TargetEnvironment}; +use cranelift_codegen::{ + cursor::{Cursor, FuncCursor}, + ir::{self, condcodes::IntCC, InstBuilder, RelSourceLoc}, +}; +use cranelift_frontend::FunctionBuilder; /// Helper used to emit bounds checks (as necessary) and compute the native /// address of a heap access. /// -/// Returns the `ir::Value` holding the native address of the heap access. -fn bounds_check_and_compute_addr( - pos: &mut FuncCursor, - cfg: &mut ControlFlowGraph, - isa: &dyn TargetIsa, - heap: ir::Heap, +/// Returns the `ir::Value` holding the native address of the heap access, or +/// `None` if the heap access will unconditionally trap. +pub fn bounds_check_and_compute_addr( + builder: &mut FunctionBuilder, + env: &TE, + heap: &HeapData, // Dynamic operand indexing into the heap. index: ir::Value, // Static immediate added to the index. offset: u32, // Static size of the heap access. access_size: u8, -) -> ir::Value { - let pointer_type = isa.pointer_type(); - let spectre = isa.flags().enable_heap_access_spectre_mitigation(); +) -> Option +where + TE: TargetEnvironment + ?Sized, +{ + let index = cast_index_to_pointer_ty( + index, + heap.index_type, + env.pointer_type(), + &mut builder.cursor(), + ); let offset_and_size = offset_plus_size(offset, access_size); - - let ir::HeapData { - base: _, - min_size, - offset_guard_size: guard_size, - style, - index_type, - } = pos.func.heaps[heap].clone(); - - let index = cast_index_to_pointer_ty(index, index_type, pointer_type, pos); + let spectre_mitigations_enabled = env.heap_access_spectre_mitigation(); // We need to emit code that will trap (or compute an address that will trap // when accessed) if @@ -146,7 +62,7 @@ fn bounds_check_and_compute_addr( // different bounds checks and optimizations of those bounds checks. It is // intentionally written in a straightforward case-matching style that will // hopefully make it easy to port to ISLE one day. - match style { + match heap.style { // ====== Dynamic Memories ====== // // 1. First special case for when `offset + access_size == 1`: @@ -157,13 +73,12 @@ fn bounds_check_and_compute_addr( // 1.a. When Spectre mitigations are enabled, avoid duplicating // bounds checks between the mitigations and the regular bounds // checks. - ir::HeapStyle::Dynamic { bound_gv } if offset_and_size == 1 && spectre => { - let bound = pos.ins().global_value(pointer_type, bound_gv); - compute_addr( - isa, - pos, + HeapStyle::Dynamic { bound_gv } if offset_and_size == 1 && spectre_mitigations_enabled => { + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + Some(compute_addr( + &mut builder.cursor(), heap, - pointer_type, + env.pointer_type(), index, offset, Some(SpectreOobComparison { @@ -171,16 +86,23 @@ fn bounds_check_and_compute_addr( lhs: index, rhs: bound, }), - ) + )) } // 1.b. Emit explicit `index >= bound` bounds checks. - ir::HeapStyle::Dynamic { bound_gv } if offset_and_size == 1 => { - let bound = pos.ins().global_value(pointer_type, bound_gv); - let oob = pos + HeapStyle::Dynamic { bound_gv } if offset_and_size == 1 => { + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + let oob = builder .ins() .icmp(IntCC::UnsignedGreaterThanOrEqual, index, bound); - pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); - compute_addr(isa, pos, heap, pointer_type, index, offset, None) + builder.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); + Some(compute_addr( + &mut builder.cursor(), + heap, + env.pointer_type(), + index, + offset, + None, + )) } // 2. Second special case for when `offset + access_size <= min_size`. @@ -192,14 +114,15 @@ fn bounds_check_and_compute_addr( // ==> index > bound - (offset + access_size) // // 2.a. Dedupe bounds checks with Spectre mitigations. - ir::HeapStyle::Dynamic { bound_gv } if offset_and_size <= min_size.into() && spectre => { - let bound = pos.ins().global_value(pointer_type, bound_gv); - let adjusted_bound = pos.ins().iadd_imm(bound, -(offset_and_size as i64)); - compute_addr( - isa, - pos, + HeapStyle::Dynamic { bound_gv } + if offset_and_size <= heap.min_size.into() && spectre_mitigations_enabled => + { + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + let adjusted_bound = builder.ins().iadd_imm(bound, -(offset_and_size as i64)); + Some(compute_addr( + &mut builder.cursor(), heap, - pointer_type, + env.pointer_type(), index, offset, Some(SpectreOobComparison { @@ -207,18 +130,25 @@ fn bounds_check_and_compute_addr( lhs: index, rhs: adjusted_bound, }), - ) + )) } // 2.b. Emit explicit `index > bound - (offset + access_size)` bounds // checks. - ir::HeapStyle::Dynamic { bound_gv } if offset_and_size <= min_size.into() => { - let bound = pos.ins().global_value(pointer_type, bound_gv); - let adjusted_bound = pos.ins().iadd_imm(bound, -(offset_and_size as i64)); - let oob = pos + HeapStyle::Dynamic { bound_gv } if offset_and_size <= heap.min_size.into() => { + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + let adjusted_bound = builder.ins().iadd_imm(bound, -(offset_and_size as i64)); + let oob = builder .ins() .icmp(IntCC::UnsignedGreaterThan, index, adjusted_bound); - pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); - compute_addr(isa, pos, heap, pointer_type, index, offset, None) + builder.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); + Some(compute_addr( + &mut builder.cursor(), + heap, + env.pointer_type(), + index, + offset, + None, + )) } // 3. General case for dynamic memories: @@ -228,17 +158,20 @@ fn bounds_check_and_compute_addr( // And we have to handle the overflow case in the left-hand side. // // 3.a. Dedupe bounds checks with Spectre mitigations. - ir::HeapStyle::Dynamic { bound_gv } if spectre => { - let access_size_val = pos.ins().iconst(pointer_type, offset_and_size as i64); - let adjusted_index = - pos.ins() - .uadd_overflow_trap(index, access_size_val, ir::TrapCode::HeapOutOfBounds); - let bound = pos.ins().global_value(pointer_type, bound_gv); - compute_addr( - isa, - pos, + HeapStyle::Dynamic { bound_gv } if spectre_mitigations_enabled => { + let access_size_val = builder + .ins() + .iconst(env.pointer_type(), offset_and_size as i64); + let adjusted_index = builder.ins().uadd_overflow_trap( + index, + access_size_val, + ir::TrapCode::HeapOutOfBounds, + ); + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + Some(compute_addr( + &mut builder.cursor(), heap, - pointer_type, + env.pointer_type(), index, offset, Some(SpectreOobComparison { @@ -246,21 +179,32 @@ fn bounds_check_and_compute_addr( lhs: adjusted_index, rhs: bound, }), - ) + )) } // 3.b. Emit an explicit `index + offset + access_size > bound` // check. - ir::HeapStyle::Dynamic { bound_gv } => { - let access_size_val = pos.ins().iconst(pointer_type, offset_and_size as i64); - let adjusted_index = - pos.ins() - .uadd_overflow_trap(index, access_size_val, ir::TrapCode::HeapOutOfBounds); - let bound = pos.ins().global_value(pointer_type, bound_gv); - let oob = pos + HeapStyle::Dynamic { bound_gv } => { + let access_size_val = builder + .ins() + .iconst(env.pointer_type(), offset_and_size as i64); + let adjusted_index = builder.ins().uadd_overflow_trap( + index, + access_size_val, + ir::TrapCode::HeapOutOfBounds, + ); + let bound = builder.ins().global_value(env.pointer_type(), bound_gv); + let oob = builder .ins() .icmp(IntCC::UnsignedGreaterThan, adjusted_index, bound); - pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); - compute_addr(isa, pos, heap, pointer_type, index, offset, None) + builder.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); + Some(compute_addr( + &mut builder.cursor(), + heap, + env.pointer_type(), + index, + offset, + None, + )) } // ====== Static Memories ====== @@ -271,18 +215,9 @@ fn bounds_check_and_compute_addr( // 1. First special case: trap immediately if `offset + access_size > // bound`, since we will end up being out-of-bounds regardless of the // given `index`. - ir::HeapStyle::Static { bound } if offset_and_size > bound.into() => { - pos.ins().trap(ir::TrapCode::HeapOutOfBounds); - - // Split the block, as the trap is a terminator instruction. - let curr_block = pos.current_block().expect("Cursor is not in a block"); - let new_block = pos.func.dfg.make_block(); - pos.insert_block(new_block); - cfg.recompute_block(pos.func, curr_block); - cfg.recompute_block(pos.func, new_block); - - let null = pos.ins().iconst(pointer_type, 0); - return null; + HeapStyle::Static { bound } if offset_and_size > bound.into() => { + builder.ins().trap(ir::TrapCode::HeapOutOfBounds); + None } // 2. Second special case for when we can completely omit explicit @@ -323,12 +258,19 @@ fn bounds_check_and_compute_addr( // `u32::MAX`. This means that `index` is always either in bounds or // within the guard page region, neither of which require emitting an // explicit bounds check. - ir::HeapStyle::Static { bound } - if index_type == ir::types::I32 + HeapStyle::Static { bound } + if heap.index_type == ir::types::I32 && u64::from(u32::MAX) - <= u64::from(bound) + u64::from(guard_size) - offset_and_size => + <= u64::from(bound) + u64::from(heap.offset_guard_size) - offset_and_size => { - compute_addr(isa, pos, heap, pointer_type, index, offset, None) + Some(compute_addr( + &mut builder.cursor(), + heap, + env.pointer_type(), + index, + offset, + None, + )) } // 3. General case for static memories. @@ -344,16 +286,17 @@ fn bounds_check_and_compute_addr( // factor in the guard pages here. // // 3.a. Dedupe the Spectre mitigation and the explicit bounds check. - ir::HeapStyle::Static { bound } if spectre => { + HeapStyle::Static { bound } if spectre_mitigations_enabled => { // NB: this subtraction cannot wrap because we didn't hit the first // special case. let adjusted_bound = u64::from(bound) - offset_and_size; - let adjusted_bound = pos.ins().iconst(pointer_type, adjusted_bound as i64); - compute_addr( - isa, - pos, + let adjusted_bound = builder + .ins() + .iconst(env.pointer_type(), adjusted_bound as i64); + Some(compute_addr( + &mut builder.cursor(), heap, - pointer_type, + env.pointer_type(), index, offset, Some(SpectreOobComparison { @@ -361,18 +304,26 @@ fn bounds_check_and_compute_addr( lhs: index, rhs: adjusted_bound, }), - ) + )) } // 3.b. Emit the explicit `index > bound - (offset + access_size)` // check. - ir::HeapStyle::Static { bound } => { + HeapStyle::Static { bound } => { // See comment in 3.a. above. let adjusted_bound = u64::from(bound) - offset_and_size; - let oob = pos - .ins() - .icmp_imm(IntCC::UnsignedGreaterThan, index, adjusted_bound as i64); - pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); - compute_addr(isa, pos, heap, pointer_type, index, offset, None) + let oob = + builder + .ins() + .icmp_imm(IntCC::UnsignedGreaterThan, index, adjusted_bound as i64); + builder.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds); + Some(compute_addr( + &mut builder.cursor(), + heap, + env.pointer_type(), + index, + offset, + None, + )) } } } @@ -416,9 +367,8 @@ struct SpectreOobComparison { /// Emit code for the base address computation of a `heap_addr` instruction, /// without any bounds checks (other than optional Spectre mitigations). fn compute_addr( - isa: &dyn TargetIsa, pos: &mut FuncCursor, - heap: ir::Heap, + heap: &HeapData, addr_ty: ir::Type, index: ir::Value, offset: u32, @@ -431,54 +381,24 @@ fn compute_addr( debug_assert_eq!(pos.func.dfg.value_type(index), addr_ty); // Add the heap base address base - let base = if isa.flags().enable_pinned_reg() && isa.flags().use_pinned_reg_as_heap_base() { - let base = pos.ins().get_pinned_reg(isa.pointer_type()); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(base)); - base - } else { - let base_gv = pos.func.heaps[heap].base; - let base = pos.ins().global_value(addr_ty, base_gv); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(base)); - base - }; + let base = pos.ins().global_value(addr_ty, heap.base); - if let Some(SpectreOobComparison { cc, lhs, rhs }) = spectre_oob_comparison { - let final_base = pos.ins().iadd(base, index); + let final_base = pos.ins().iadd(base, index); + let final_addr = if offset == 0 { + final_base + } else { // NB: The addition of the offset immediate must happen *before* the // `select_spectre_guard`. If it happens after, then we potentially are // letting speculative execution read the whole first 4GiB of memory. - let final_addr = if offset == 0 { - final_base - } else { - let final_addr = pos.ins().iadd_imm(final_base, offset as i64); - trace!( - " inserting: {}", - pos.func.dfg.display_value_inst(final_addr) - ); - final_addr - }; - let zero = pos.ins().iconst(addr_ty, 0); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(zero)); + pos.ins().iadd_imm(final_base, offset as i64) + }; + if let Some(SpectreOobComparison { cc, lhs, rhs }) = spectre_oob_comparison { + let null = pos.ins().iconst(addr_ty, 0); let cmp = pos.ins().icmp(cc, lhs, rhs); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(cmp)); - - let value = pos.ins().select_spectre_guard(cmp, zero, final_addr); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(value)); - value - } else if offset == 0 { - let addr = pos.ins().iadd(base, index); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(addr)); - addr + pos.ins().select_spectre_guard(cmp, null, final_addr) } else { - let final_base = pos.ins().iadd(base, index); - trace!( - " inserting: {}", - pos.func.dfg.display_value_inst(final_base) - ); - let addr = pos.ins().iadd_imm(final_base, offset as i64); - trace!(" inserting: {}", pos.func.dfg.display_value_inst(addr)); - addr + final_addr } } diff --git a/cranelift/wasm/src/environ/dummy.rs b/cranelift/wasm/src/environ/dummy.rs index 41e56932e24e..030e0c9ed904 100644 --- a/cranelift/wasm/src/environ/dummy.rs +++ b/cranelift/wasm/src/environ/dummy.rs @@ -10,8 +10,8 @@ use crate::func_translator::FuncTranslator; use crate::state::FuncTranslationState; use crate::WasmType; use crate::{ - DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, - Table, TableIndex, TypeIndex, WasmFuncType, WasmResult, + DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData, + HeapStyle, Memory, MemoryIndex, Table, TableIndex, TypeIndex, WasmFuncType, WasmResult, }; use core::convert::TryFrom; use cranelift_codegen::cursor::FuncCursor; @@ -212,6 +212,9 @@ pub struct DummyFuncEnvironment<'dummy_environment> { /// Expected reachability data (before/after for each op) to assert. This is used for testing. expected_reachability: Option, + + /// Heaps we have created to implement Wasm linear memories. + pub heaps: PrimaryMap, } impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> { @@ -223,6 +226,7 @@ impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> { Self { mod_info, expected_reachability, + heaps: Default::default(), } } @@ -250,6 +254,10 @@ impl<'dummy_environment> TargetEnvironment for DummyFuncEnvironment<'dummy_envir fn target_config(&self) -> TargetFrontendConfig { self.mod_info.config } + + fn heap_access_spectre_mitigation(&self) -> bool { + false + } } impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> { @@ -275,7 +283,11 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ }) } - fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult { + fn heaps(&self) -> &PrimaryMap { + &self.heaps + } + + fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult { // Create a static heap whose base address is stored at `vmctx+0`. let addr = func.create_global_value(ir::GlobalValueData::VMContext); let gv = func.create_global_value(ir::GlobalValueData::Load { @@ -285,12 +297,12 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ readonly: true, }); - Ok(func.create_heap(ir::HeapData { + Ok(self.heaps.push(HeapData { base: gv, - min_size: 0.into(), - offset_guard_size: 0x8000_0000.into(), - style: ir::HeapStyle::Static { - bound: 0x1_0000_0000.into(), + min_size: 0, + offset_guard_size: 0x8000_0000, + style: HeapStyle::Static { + bound: 0x1_0000_0000, }, index_type: I32, })) @@ -455,7 +467,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, mut pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, _val: ir::Value, ) -> WasmResult { Ok(pos.ins().iconst(I32, -1)) @@ -465,7 +477,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, mut pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, ) -> WasmResult { Ok(pos.ins().iconst(I32, -1)) } @@ -474,9 +486,9 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, _pos: FuncCursor, _src_index: MemoryIndex, - _src_heap: ir::Heap, + _src_heap: Heap, _dst_index: MemoryIndex, - _dst_heap: ir::Heap, + _dst_heap: Heap, _dst: ir::Value, _src: ir::Value, _len: ir::Value, @@ -488,7 +500,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, _pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, _dst: ir::Value, _val: ir::Value, _len: ir::Value, @@ -500,7 +512,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, _pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, _seg_index: u32, _dst: ir::Value, _src: ir::Value, @@ -625,7 +637,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, mut pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, _addr: ir::Value, _expected: ir::Value, _timeout: ir::Value, @@ -637,7 +649,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ &mut self, mut pos: FuncCursor, _index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, _addr: ir::Value, _count: ir::Value, ) -> WasmResult { @@ -653,6 +665,10 @@ impl TargetEnvironment for DummyEnvironment { fn target_config(&self) -> TargetFrontendConfig { self.info.config } + + fn heap_access_spectre_mitigation(&self) -> bool { + false + } } impl<'data> ModuleEnvironment<'data> for DummyEnvironment { diff --git a/cranelift/wasm/src/environ/spec.rs b/cranelift/wasm/src/environ/spec.rs index 5d579d0a47a2..08b27597ab9a 100644 --- a/cranelift/wasm/src/environ/spec.rs +++ b/cranelift/wasm/src/environ/spec.rs @@ -8,14 +8,16 @@ use crate::state::FuncTranslationState; use crate::{ - DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, - Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, WasmResult, WasmType, + DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData, Memory, MemoryIndex, + SignatureIndex, Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError, WasmFuncType, + WasmResult, WasmType, }; use core::convert::From; use cranelift_codegen::cursor::FuncCursor; use cranelift_codegen::ir::immediates::Offset32; use cranelift_codegen::ir::{self, InstBuilder}; use cranelift_codegen::isa::TargetFrontendConfig; +use cranelift_entity::PrimaryMap; use cranelift_frontend::FunctionBuilder; use std::boxed::Box; use std::string::ToString; @@ -46,6 +48,9 @@ pub trait TargetEnvironment { /// Get the information needed to produce Cranelift IR for the given target. fn target_config(&self) -> TargetFrontendConfig; + /// Whether to enable Spectre mitigations for heap accesses. + fn heap_access_spectre_mitigation(&self) -> bool; + /// Get the Cranelift integer type to use for native pointers. /// /// This returns `I64` for 64-bit architectures and `I32` for 32-bit architectures. @@ -112,11 +117,20 @@ pub trait FuncEnvironment: TargetEnvironment { index: GlobalIndex, ) -> WasmResult; + /// Get the heaps for this function environment. + /// + /// The returned map should provide heap format details (encoded in + /// `HeapData`) for each `Heap` that was previously returned by + /// `make_heap()`. The translator will first call make_heap for each Wasm + /// memory, and then later when translating code, will invoke `heaps()` to + /// learn how to access the environment's implementation of each memory. + fn heaps(&self) -> &PrimaryMap; + /// Set up the necessary preamble definitions in `func` to access the linear memory identified /// by `index`. /// /// The index space covers both imported and locally declared memories. - fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult; + fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult; /// Set up the necessary preamble definitions in `func` to access the table identified /// by `index`. @@ -206,7 +220,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, val: ir::Value, ) -> WasmResult; @@ -220,7 +234,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, ) -> WasmResult; /// Translate a `memory.copy` WebAssembly instruction. @@ -231,9 +245,9 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, src_index: MemoryIndex, - src_heap: ir::Heap, + src_heap: Heap, dst_index: MemoryIndex, - dst_heap: ir::Heap, + dst_heap: Heap, dst: ir::Value, src: ir::Value, len: ir::Value, @@ -247,7 +261,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, dst: ir::Value, val: ir::Value, len: ir::Value, @@ -263,7 +277,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, seg_index: u32, dst: ir::Value, src: ir::Value, @@ -420,7 +434,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, addr: ir::Value, expected: ir::Value, timeout: ir::Value, @@ -440,7 +454,7 @@ pub trait FuncEnvironment: TargetEnvironment { &mut self, pos: FuncCursor, index: MemoryIndex, - heap: ir::Heap, + heap: Heap, addr: ir::Value, count: ir::Value, ) -> WasmResult; diff --git a/cranelift/wasm/src/heap.rs b/cranelift/wasm/src/heap.rs new file mode 100644 index 000000000000..2b2a9fb99b65 --- /dev/null +++ b/cranelift/wasm/src/heap.rs @@ -0,0 +1,99 @@ +//! Heaps to implement WebAssembly linear memories. + +use cranelift_codegen::ir::{GlobalValue, Type}; +use cranelift_entity::entity_impl; + +/// An opaque reference to a [`HeapData`][crate::HeapData]. +/// +/// While the order is stable, it is arbitrary. +#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Heap(u32); +entity_impl!(Heap, "heap"); + +/// A heap implementing a WebAssembly linear memory. +/// +/// Code compiled from WebAssembly runs in a sandbox where it can't access all +/// process memory. Instead, it is given a small set of memory areas to work in, +/// and all accesses are bounds checked. `cranelift-wasm` models this through +/// the concept of *heaps*. +/// +/// Heap addresses can be smaller than the native pointer size, for example +/// unsigned `i32` offsets on a 64-bit architecture. +/// +/// A heap appears as three consecutive ranges of address space: +/// +/// 1. The *mapped pages* are the accessible memory range in the heap. A heap +/// may have a minimum guaranteed size which means that some mapped pages are +/// always present. +/// +/// 2. The *unmapped pages* is a possibly empty range of address space that may +/// be mapped in the future when the heap is grown. They are addressable +/// but not accessible. +/// +/// 3. The *offset-guard pages* is a range of address space that is guaranteed +/// to always cause a trap when accessed. It is used to optimize bounds +/// checking for heap accesses with a shared base pointer. They are +/// addressable but not accessible. +/// +/// The *heap bound* is the total size of the mapped and unmapped pages. This is +/// the bound that `heap_addr` checks against. Memory accesses inside the heap +/// bounds can trap if they hit an unmapped page (which is not accessible). +/// +/// Two styles of heaps are supported, *static* and *dynamic*. They behave +/// differently when resized. +/// +/// #### Static heaps +/// +/// A *static heap* starts out with all the address space it will ever need, so it +/// never moves to a different address. At the base address is a number of mapped +/// pages corresponding to the heap's current size. Then follows a number of +/// unmapped pages where the heap can grow up to its maximum size. After the +/// unmapped pages follow the offset-guard pages which are also guaranteed to +/// generate a trap when accessed. +/// +/// #### Dynamic heaps +/// +/// A *dynamic heap* can be relocated to a different base address when it is +/// resized, and its bound can move dynamically. The offset-guard pages move +/// when the heap is resized. The bound of a dynamic heap is stored in a global +/// value. +#[derive(Clone, PartialEq, Hash)] +#[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))] +pub struct HeapData { + /// The address of the start of the heap's storage. + pub base: GlobalValue, + + /// Guaranteed minimum heap size in bytes. Heap accesses before `min_size` + /// don't need bounds checking. + pub min_size: u64, + + /// Size in bytes of the offset-guard pages following the heap. + pub offset_guard_size: u64, + + /// Heap style, with additional style-specific info. + pub style: HeapStyle, + + /// The index type for the heap. + pub index_type: Type, +} + +/// Style of heap including style-specific information. +#[derive(Clone, PartialEq, Hash)] +#[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))] +pub enum HeapStyle { + /// A dynamic heap can be relocated to a different base address when it is + /// grown. + Dynamic { + /// Global value providing the current bound of the heap in bytes. + bound_gv: GlobalValue, + }, + + /// A static heap has a fixed base address and a number of not-yet-allocated + /// pages before the offset-guard pages. + Static { + /// Heap bound in bytes. The offset-guard pages are allocated after the + /// bound. + bound: u64, + }, +} diff --git a/cranelift/wasm/src/lib.rs b/cranelift/wasm/src/lib.rs index f4d57e0aa434..695d62e7e6a5 100644 --- a/cranelift/wasm/src/lib.rs +++ b/cranelift/wasm/src/lib.rs @@ -51,6 +51,7 @@ use std::collections::{ mod code_translator; mod environ; mod func_translator; +mod heap; mod module_translator; mod sections_translator; mod state; @@ -61,6 +62,7 @@ pub use crate::environ::{ GlobalVariable, ModuleEnvironment, TargetEnvironment, }; pub use crate::func_translator::FuncTranslator; +pub use crate::heap::{Heap, HeapData, HeapStyle}; pub use crate::module_translator::translate_module; pub use crate::state::FuncTranslationState; pub use crate::translation_utils::*; diff --git a/cranelift/wasm/src/state.rs b/cranelift/wasm/src/state.rs index 03051ed630f6..0517dd2fc4b3 100644 --- a/cranelift/wasm/src/state.rs +++ b/cranelift/wasm/src/state.rs @@ -4,7 +4,7 @@ //! value and control stacks during the translation of a single function. use crate::environ::{FuncEnvironment, GlobalVariable}; -use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult}; +use crate::{FuncIndex, GlobalIndex, Heap, MemoryIndex, TableIndex, TypeIndex, WasmResult}; use crate::{HashMap, Occupied, Vacant}; use cranelift_codegen::ir::{self, Block, Inst, Value}; use std::vec::Vec; @@ -225,7 +225,7 @@ pub struct FuncTranslationState { globals: HashMap, // Map of heaps that have been created by `FuncEnvironment::make_heap`. - heaps: HashMap, + memory_to_heap: HashMap, // Map of tables that have been created by `FuncEnvironment::make_table`. pub(crate) tables: HashMap, @@ -258,7 +258,7 @@ impl FuncTranslationState { control_stack: Vec::new(), reachable: true, globals: HashMap::new(), - heaps: HashMap::new(), + memory_to_heap: HashMap::new(), tables: HashMap::new(), signatures: HashMap::new(), functions: HashMap::new(), @@ -270,7 +270,7 @@ impl FuncTranslationState { debug_assert!(self.control_stack.is_empty()); self.reachable = true; self.globals.clear(); - self.heaps.clear(); + self.memory_to_heap.clear(); self.tables.clear(); self.signatures.clear(); self.functions.clear(); @@ -462,9 +462,9 @@ impl FuncTranslationState { func: &mut ir::Function, index: u32, environ: &mut FE, - ) -> WasmResult { + ) -> WasmResult { let index = MemoryIndex::from_u32(index); - match self.heaps.entry(index) { + match self.memory_to_heap.entry(index) { Occupied(entry) => Ok(*entry.get()), Vacant(entry) => Ok(*entry.insert(environ.make_heap(func, index)?)), } diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index 518f524c3c7d..6a3473ca6d9f 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -5,12 +5,12 @@ use cranelift_codegen::ir::immediates::{Imm64, Offset32, Uimm64}; use cranelift_codegen::ir::types::*; use cranelift_codegen::ir::{AbiParam, ArgumentPurpose, Function, InstBuilder, Signature}; use cranelift_codegen::isa::{self, TargetFrontendConfig, TargetIsa}; -use cranelift_entity::EntityRef; +use cranelift_entity::{EntityRef, PrimaryMap}; use cranelift_frontend::FunctionBuilder; use cranelift_frontend::Variable; use cranelift_wasm::{ - self, FuncIndex, FuncTranslationState, GlobalIndex, GlobalVariable, MemoryIndex, TableIndex, - TargetEnvironment, TypeIndex, WasmError, WasmResult, WasmType, + self, FuncIndex, FuncTranslationState, GlobalIndex, GlobalVariable, Heap, HeapData, HeapStyle, + MemoryIndex, TableIndex, TargetEnvironment, TypeIndex, WasmError, WasmResult, WasmType, }; use std::convert::TryFrom; use std::mem; @@ -110,6 +110,9 @@ pub struct FuncEnvironment<'module_environment> { translation: &'module_environment ModuleTranslation<'module_environment>, types: &'module_environment ModuleTypes, + /// Heaps implementing WebAssembly linear memories. + heaps: PrimaryMap, + /// The Cranelift global holding the vmctx address. vmctx: Option, @@ -170,6 +173,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> { module: &translation.module, translation, types, + heaps: PrimaryMap::default(), vmctx: None, builtin_function_signatures, offsets: VMOffsets::new(isa.pointer_bytes(), &translation.module), @@ -813,9 +817,17 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm fn reference_type(&self, ty: WasmType) -> ir::Type { crate::reference_type(ty, self.pointer_type()) } + + fn heap_access_spectre_mitigation(&self) -> bool { + self.isa.flags().enable_heap_access_spectre_mitigation() + } } impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> { + fn heaps(&self) -> &PrimaryMap { + &self.heaps + } + fn is_wasm_parameter(&self, _signature: &ir::Signature, index: usize) -> bool { // The first two parameters are the vmctx and caller vmctx. The rest are // the wasm parameters. @@ -1366,7 +1378,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m Ok(()) } - fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult { + fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult { let pointer_type = self.pointer_type(); let is_shared = self.module.memory_plans[index].memory.shared; let (ptr, base_offset, current_length_offset) = { @@ -1430,8 +1442,8 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m readonly: false, }); ( - Uimm64::new(offset_guard_size), - ir::HeapStyle::Dynamic { + offset_guard_size, + HeapStyle::Dynamic { bound_gv: heap_bound, }, false, @@ -1443,9 +1455,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m pre_guard_size: _, memory: _, } => ( - Uimm64::new(offset_guard_size), - ir::HeapStyle::Static { - bound: Uimm64::new(u64::from(bound) * u64::from(WASM_PAGE_SIZE)), + offset_guard_size, + HeapStyle::Static { + bound: u64::from(bound) * u64::from(WASM_PAGE_SIZE), }, true, ), @@ -1457,9 +1469,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m global_type: pointer_type, readonly: readonly_base, }); - Ok(func.create_heap(ir::HeapData { + Ok(self.heaps.push(HeapData { base: heap_base, - min_size: 0.into(), + min_size: 0, offset_guard_size, style: heap_style, index_type: self.memory_index_type(index), @@ -1686,7 +1698,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor<'_>, index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, val: ir::Value, ) -> WasmResult { let func_sig = self @@ -1712,7 +1724,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor<'_>, index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, ) -> WasmResult { let pointer_type = self.pointer_type(); let vmctx = self.vmctx(&mut pos.func); @@ -1788,9 +1800,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor, src_index: MemoryIndex, - _src_heap: ir::Heap, + _src_heap: Heap, dst_index: MemoryIndex, - _dst_heap: ir::Heap, + _dst_heap: Heap, dst: ir::Value, src: ir::Value, len: ir::Value, @@ -1828,7 +1840,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor, memory_index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, dst: ir::Value, val: ir::Value, len: ir::Value, @@ -1854,7 +1866,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor, memory_index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, seg_index: u32, dst: ir::Value, src: ir::Value, @@ -1976,7 +1988,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor, memory_index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, addr: ir::Value, expected: ir::Value, timeout: ir::Value, @@ -2003,7 +2015,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m &mut self, mut pos: FuncCursor, memory_index: MemoryIndex, - _heap: ir::Heap, + _heap: Heap, addr: ir::Value, count: ir::Value, ) -> WasmResult {