summaryrefslogtreecommitdiff
path: root/test/lit/gc-read-write-effects.wast
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-03-05 14:26:06 -0800
committerGitHub <noreply@github.com>2021-03-05 14:26:06 -0800
commit57619b508d38677844cb482a4034dc985d2cecc6 (patch)
tree5ab8cd9fa807be2844161bf9db76c031e030297c /test/lit/gc-read-write-effects.wast
parentd7cf703bf9c6c9e09a048b976cfb0c5db6a43270 (diff)
downloadbinaryen-57619b508d38677844cb482a4034dc985d2cecc6.tar.gz
binaryen-57619b508d38677844cb482a4034dc985d2cecc6.tar.bz2
binaryen-57619b508d38677844cb482a4034dc985d2cecc6.zip
[effects] Record reads and writes of the GC heap (#3657)
Just as reads and writes to memory can interfere with each other, reads and writes of GC objects can interfere with each other. This PR adds new `readsHeap` and `writesHeap` fields to EffectAnalyzer to account for this interference. Note that memory accesses can never alias with GC heap accesses, so they are considered separately. Similarly, it would be possible to prove that different GC heap accesses never interfere with each other based on the accessed types, but that's left to future work. Fixes #3655.
Diffstat (limited to 'test/lit/gc-read-write-effects.wast')
-rw-r--r--test/lit/gc-read-write-effects.wast50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/lit/gc-read-write-effects.wast b/test/lit/gc-read-write-effects.wast
new file mode 100644
index 000000000..f487a92f5
--- /dev/null
+++ b/test/lit/gc-read-write-effects.wast
@@ -0,0 +1,50 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
+
+;; Check that writing a struct field is not reordered with reading the same
+;; struct field.
+
+;; RUN: wasm-opt -all --simplify-locals %s -S -o - | filecheck %s
+
+(module
+ (type $A (struct
+ (field (mut i32))
+ ))
+
+ ;; Check that this:
+ ;;
+ ;; y = a.0
+ ;; a.0 = 10
+ ;; return y
+ ;;
+ ;; Is not turned into this:
+ ;;
+ ;; a.0 = 10
+ ;; return a.0
+ ;;
+ ;; CHECK: (func $test (param $x (ref null $A)) (result i32)
+ ;; CHECK-NEXT: (local $y i32)
+ ;; CHECK-NEXT: (local.set $y
+ ;; CHECK-NEXT: (struct.get $A 0
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.set $A 0
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ (func $test (export "test") (param $x (ref null $A)) (result i32)
+ (local $y i32)
+ (local.set $y
+ (struct.get $A 0
+ (local.get $x)
+ )
+ )
+ (struct.set $A 0
+ (local.get $x)
+ (i32.const 10)
+ )
+ (local.get $y)
+ )
+)