From 2b6ee2a822f55332df99092942dbb9d5c7b8d6f9 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 May 2026 14:09:05 -0700 Subject: [PATCH 1/2] Fix `LastStores::update` for stores without an alias region Stores without an alias region act like a fence: they clobber all regions. But we additionally need to update `self.last_fence` so that subsequent loads with regions don't get stale values forwarded past the regionless store. Fixes https://github.com/bytecodealliance/wasmtime/issues/13508 --- cranelift/codegen/src/alias_analysis.rs | 5 ++ .../filetests/alias/issue-13508.clif | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 cranelift/filetests/filetests/alias/issue-13508.clif diff --git a/cranelift/codegen/src/alias_analysis.rs b/cranelift/codegen/src/alias_analysis.rs index dbfd958361bd..bc31ed2b842c 100644 --- a/cranelift/codegen/src/alias_analysis.rs +++ b/cranelift/codegen/src/alias_analysis.rs @@ -98,7 +98,12 @@ impl LastStores { match func.dfg.mem_flags[memflags].alias_region() { Some(region) => self.regions[region] = inst.into(), None => { + // A store with no alias region may alias any region, so + // treat it like a fence: clear all regions and update + // `last_fence` so that subsequent region-tagged loads don't + // forward stale values past this store. self.regions.clear(); + self.last_fence = inst.into(); self.other = inst.into(); } } diff --git a/cranelift/filetests/filetests/alias/issue-13508.clif b/cranelift/filetests/filetests/alias/issue-13508.clif new file mode 100644 index 000000000000..b8830e9090b5 --- /dev/null +++ b/cranelift/filetests/filetests/alias/issue-13508.clif @@ -0,0 +1,54 @@ +test interpret +test run +test alias-analysis + +set opt_level=speed + +target aarch64 +target x86_64 +target riscv64 +target s390x + +function %f(i64, i64, i64) -> i32, i32, i32 { + region0 = 2 "vmctx" + +block0(v0: i64, v1: i64, v2: i64): + ;; Initialize to `-1`. + v3 = iconst.i64 -1 + store notrap v3, v0 + + ;; Memory fence nop. + v4 = atomic_cas v2, v0, v0 + + ;; Load with region (fills cache v5+4 -> v4). + v5 = load.i32 region0 v0 + ; check: v5 = load.i32 region0 v0 + + ;; Load with region again (gets cached v4). + v6 = load.i32 region0 v0 + ; check: v6 -> v5 + + ;; Store without region (clobbers cache). + v7 = iconst.i32 42 + store notrap v7, v1 + + ;; Load with region (shouldn't get cached v4). + v8 = load.i32 region0 v0 + ; check: v8 = load.i32 region0 v0 + + return v5, v6, v8 +} + +function %g() -> i32, i32, i32 { + ss0 = explicit_slot 8 + ss1 = explicit_slot 8 + fn0 = %f(i64, i64, i64) -> i32, i32, i32 + +block0: + v0 = stack_addr.i64 ss0 + v1 = stack_addr.i64 ss1 + v2, v3, v4 = call fn0(v0, v0, v1) + return v2, v3, v4 +} + +; run: %g() == [-1, -1, 42] From 6ed281d4afec4fdb20cd8ed3be1619ce656188d3 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 May 2026 14:52:17 -0700 Subject: [PATCH 2/2] Don't run the filetest on architectures that might not have enough return registers for its function signature --- cranelift/filetests/filetests/alias/issue-13508.clif | 3 --- 1 file changed, 3 deletions(-) diff --git a/cranelift/filetests/filetests/alias/issue-13508.clif b/cranelift/filetests/filetests/alias/issue-13508.clif index b8830e9090b5..2c86a63ef416 100644 --- a/cranelift/filetests/filetests/alias/issue-13508.clif +++ b/cranelift/filetests/filetests/alias/issue-13508.clif @@ -5,9 +5,6 @@ test alias-analysis set opt_level=speed target aarch64 -target x86_64 -target riscv64 -target s390x function %f(i64, i64, i64) -> i32, i32, i32 { region0 = 2 "vmctx"