Skip to content

Commit

Permalink
cranelift: Add wasm tests for duplicate loads (#5514)
Browse files Browse the repository at this point in the history
* cranelift-filetests: Add the ability to test optimized CLIF in Wasm tests

* cranelift: Add Wasm tests for identical loads, back to back
  • Loading branch information
fitzgen committed Jan 4, 2023
1 parent 7c67378 commit d1920f5
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 0 deletions.
115 changes: 115 additions & 0 deletions cranelift/filetests/filetests/wasm/duplicate-loads-dynamic-memory.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
;;! target = "x86_64"
;;!
;;! optimize = true
;;!
;;! settings = [
;;! "enable_heap_access_spectre_mitigation=true",
;;! "opt_level=speed_and_size"
;;! ]
;;!
;;! [globals.vmctx]
;;! type = "i64"
;;! vmctx = true
;;!
;;! [globals.heap_base]
;;! type = "i64"
;;! load = { base = "vmctx", offset = 0 }
;;!
;;! [globals.heap_bound]
;;! type = "i64"
;;! load = { base = "vmctx", offset = 8 }
;;!
;;! [[heaps]]
;;! base = "heap_base"
;;! min_size = 0x10000
;;! offset_guard_size = 0xffffffff
;;! index_type = "i32"
;;! style = { kind = "dynamic", bound = "heap_bound" }

(module
(memory (export "memory") 1)
(func (export "load-without-offset") (param i32) (result i32 i32)
local.get 0
i32.load
local.get 0
i32.load
)
(func (export "load-with-offset") (param i32) (result i32 i32)
local.get 0
i32.load offset=1234
local.get 0
i32.load offset=1234
)
)

;; function u0:0(i32, i64 vmctx) -> i32, i32 fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned gv0+8
;; gv2 = load.i64 notrap aligned gv0
;;
;; block0(v0: i32, v1: i64):
;; @0057 v4 = uextend.i64 v0
;; v13 -> v4
;; @0057 v5 = load.i64 notrap aligned v1+8
;; v14 -> v5
;; v22 = iconst.i64 -4
;; v23 -> v22
;; @0057 v6 = iadd v5, v22 ; v22 = -4
;; v15 -> v6
;; @0057 v7 = load.i64 notrap aligned v1
;; v16 -> v7
;; @0057 v8 = iadd v7, v4
;; v17 -> v8
;; @0057 v9 = iconst.i64 0
;; v18 -> v9
;; @0057 v10 = icmp ugt v4, v6
;; v19 -> v10
;; @0057 v11 = select_spectre_guard v10, v9, v8 ; v9 = 0
;; @0057 v12 = load.i32 little heap v11
;; v2 -> v12
;; @005c v20 = select_spectre_guard v10, v9, v8 ; v9 = 0
;; @005c v21 = load.i32 little heap v20
;; v3 -> v21
;; @005f jump block1
;;
;; block1:
;; @005f return v12, v21
;; }
;;
;; function u0:1(i32, i64 vmctx) -> i32, i32 fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned gv0+8
;; gv2 = load.i64 notrap aligned gv0
;;
;; block0(v0: i32, v1: i64):
;; @0064 v4 = uextend.i64 v0
;; v14 -> v4
;; @0064 v5 = load.i64 notrap aligned v1+8
;; v15 -> v5
;; v24 = iconst.i64 -1238
;; v26 -> v24
;; @0064 v6 = iadd v5, v24 ; v24 = -1238
;; v16 -> v6
;; @0064 v7 = load.i64 notrap aligned v1
;; v17 -> v7
;; @0064 v8 = iadd v7, v4
;; v18 -> v8
;; v25 = iconst.i64 1234
;; v27 -> v25
;; @0064 v9 = iadd v8, v25 ; v25 = 1234
;; v19 -> v9
;; @0064 v10 = iconst.i64 0
;; v20 -> v10
;; @0064 v11 = icmp ugt v4, v6
;; v21 -> v11
;; @0064 v12 = select_spectre_guard v11, v10, v9 ; v10 = 0
;; @0064 v13 = load.i32 little heap v12
;; v2 -> v13
;; @006a v22 = select_spectre_guard v11, v10, v9 ; v10 = 0
;; @006a v23 = load.i32 little heap v22
;; v3 -> v23
;; @006e jump block1
;;
;; block1:
;; @006e return v13, v23
;; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
;;! target = "x86_64"
;;!
;;! optimize = true
;;!
;;! settings = [
;;! "enable_heap_access_spectre_mitigation=true",
;;! "opt_level=speed_and_size"
;;! ]
;;!
;;! [globals.vmctx]
;;! type = "i64"
;;! vmctx = true
;;!
;;! [globals.heap_base]
;;! type = "i64"
;;! load = { base = "vmctx", offset = 0, readonly = true }
;;!
;;! [[heaps]]
;;! base = "heap_base"
;;! min_size = 0x10000
;;! offset_guard_size = 0xffffffff
;;! index_type = "i32"
;;! style = { kind = "static", bound = 0x10000000 }

(module
(memory (export "memory") 1)
(func (export "load-without-offset") (param i32) (result i32 i32)
local.get 0
i32.load
local.get 0
i32.load
)
(func (export "load-with-offset") (param i32) (result i32 i32)
local.get 0
i32.load offset=1234
local.get 0
i32.load offset=1234
)
)

;; function u0:0(i32, i64 vmctx) -> i32, i32 fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0
;;
;; block0(v0: i32, v1: i64):
;; @0057 v4 = uextend.i64 v0
;; v8 -> v4
;; @0057 v5 = load.i64 notrap aligned readonly v1
;; v9 -> v5
;; @0057 v6 = iadd v5, v4
;; v10 -> v6
;; @0057 v7 = load.i32 little heap v6
;; v2 -> v7
;; v11 -> v7
;; v3 -> v11
;; @005f jump block1
;;
;; block1:
;; @005f return v7, v7
;; }
;;
;; function u0:1(i32, i64 vmctx) -> i32, i32 fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0
;;
;; block0(v0: i32, v1: i64):
;; @0064 v4 = uextend.i64 v0
;; v9 -> v4
;; @0064 v5 = load.i64 notrap aligned readonly v1
;; v10 -> v5
;; @0064 v6 = iadd v5, v4
;; v11 -> v6
;; v14 = iconst.i64 1234
;; v15 -> v14
;; @0064 v7 = iadd v6, v14 ; v14 = 1234
;; v12 -> v7
;; @0064 v8 = load.i32 little heap v7
;; v2 -> v8
;; v13 -> v8
;; v3 -> v13
;; @006e jump block1
;;
;; block1:
;; @006e return v8, v8
;; }
5 changes: 5 additions & 0 deletions cranelift/filetests/src/test_wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ pub fn run(path: &Path, wat: &str) -> Result<()> {
.map_err(|e| crate::pretty_anyhow_error(&e.func, e.inner))?;
writeln!(&mut actual, "function {}:", func.name).unwrap();
writeln!(&mut actual, "{}", code.disasm.as_ref().unwrap()).unwrap();
} else if config.optimize {
let mut ctx = cranelift_codegen::Context::for_function(func.clone());
ctx.optimize(isa)
.map_err(|e| crate::pretty_anyhow_error(&ctx.func, e))?;
writeln!(&mut actual, "{}", ctx.func.display()).unwrap();
} else {
writeln!(&mut actual, "{}", func.display()).unwrap();
}
Expand Down
10 changes: 10 additions & 0 deletions cranelift/filetests/src/test_wasm/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub struct TestConfig {
#[serde(default)]
pub compile: bool,

#[serde(default)]
pub optimize: bool,

#[serde(default)]
pub settings: Vec<String>,

Expand All @@ -30,6 +33,13 @@ pub struct TestConfig {

impl TestConfig {
pub fn validate(&self) -> Result<()> {
if self.compile || self.optimize {
ensure!(
!(self.compile && self.optimize),
"The `compile` and `optimize` options are mutually exclusive."
);
}

for global in self.globals.values() {
ensure!(
global.vmctx || global.load.is_some(),
Expand Down

0 comments on commit d1920f5

Please sign in to comment.