Skip to content

Commit a2f2c9b

Browse files
authored
Fix effects for AtomicFence (#8465)
When we updated EffectsAnalzyer to handle atomic effects more precisely, we forgot to update AtomicFence. It previously was considered to access shared memories, but in fact it should be considered to access all possible shared locations. This properly prevents it from being reordered with accesses to shared structs and arrays as well.
1 parent 2602030 commit a2f2c9b

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

src/ir/effects.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,10 @@ class EffectAnalyzer {
846846
// so we set these to true.
847847
parent.readsSharedMemory = true;
848848
parent.writesSharedMemory = true;
849+
parent.readsSharedMutableStruct = true;
850+
parent.writesSharedStruct = true;
851+
parent.readsSharedMutableArray = true;
852+
parent.writesSharedArray = true;
849853
parent.readOrder = parent.writeOrder = MemoryOrder::SeqCst;
850854
}
851855
void visitPause(Pause* curr) {

test/lit/passes/simplify-locals-atomic-effects.wast

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,4 +795,107 @@
795795
)
796796
(local.get $x)
797797
)
798+
799+
;; CHECK: (func $read-struct-fence (type $3) (param $shared (ref null $shared-struct)) (result i32)
800+
;; CHECK-NEXT: (local $x i32)
801+
;; CHECK-NEXT: (local.set $x
802+
;; CHECK-NEXT: (struct.get $shared-struct 0
803+
;; CHECK-NEXT: (local.get $shared)
804+
;; CHECK-NEXT: )
805+
;; CHECK-NEXT: )
806+
;; CHECK-NEXT: (atomic.fence)
807+
;; CHECK-NEXT: (local.get $x)
808+
;; CHECK-NEXT: )
809+
(func $read-struct-fence (param $shared (ref null $shared-struct)) (result i32)
810+
(local $x i32)
811+
;; A shared struct read cannot be moved past an atomic.fence.
812+
(local.set $x
813+
(struct.get $shared-struct 0 (local.get $shared))
814+
)
815+
(atomic.fence)
816+
(local.get $x)
817+
)
818+
819+
;; CHECK: (func $read-array-fence (type $2) (param $shared (ref null $shared-struct)) (param $shared-array (ref null $shared-array)) (result i32)
820+
;; CHECK-NEXT: (local $x i32)
821+
;; CHECK-NEXT: (local.set $x
822+
;; CHECK-NEXT: (array.get $shared-array
823+
;; CHECK-NEXT: (local.get $shared-array)
824+
;; CHECK-NEXT: (i32.const 0)
825+
;; CHECK-NEXT: )
826+
;; CHECK-NEXT: )
827+
;; CHECK-NEXT: (atomic.fence)
828+
;; CHECK-NEXT: (local.get $x)
829+
;; CHECK-NEXT: )
830+
(func $read-array-fence (param $shared (ref null $shared-struct)) (param $shared-array (ref null $shared-array)) (result i32)
831+
(local $x i32)
832+
;; A shared array read cannot be moved past an atomic.fence.
833+
(local.set $x
834+
(array.get $shared-array (local.get $shared-array) (i32.const 0))
835+
)
836+
(atomic.fence)
837+
(local.get $x)
838+
)
839+
840+
;; CHECK: (func $write-struct-fence (type $3) (param $shared (ref null $shared-struct)) (result i32)
841+
;; CHECK-NEXT: (local $x i32)
842+
;; CHECK-NEXT: (local.set $x
843+
;; CHECK-NEXT: (block (result i32)
844+
;; CHECK-NEXT: (struct.set $shared-struct 0
845+
;; CHECK-NEXT: (local.get $shared)
846+
;; CHECK-NEXT: (i32.const 0)
847+
;; CHECK-NEXT: )
848+
;; CHECK-NEXT: (i32.const 1)
849+
;; CHECK-NEXT: )
850+
;; CHECK-NEXT: )
851+
;; CHECK-NEXT: (atomic.fence)
852+
;; CHECK-NEXT: (local.get $x)
853+
;; CHECK-NEXT: )
854+
(func $write-struct-fence (param $shared (ref null $shared-struct)) (result i32)
855+
(local $x i32)
856+
;; A shared struct read cannot be moved past an atomic.fence.
857+
(local.set $x
858+
(block (result i32)
859+
(struct.set $shared-struct 0
860+
(local.get $shared)
861+
(i32.const 0)
862+
)
863+
(i32.const 1)
864+
)
865+
)
866+
(atomic.fence)
867+
(local.get $x)
868+
)
869+
870+
;; CHECK: (func $write-array-fence (type $6) (param $shared (ref null $shared-array)) (result i32)
871+
;; CHECK-NEXT: (local $x i32)
872+
;; CHECK-NEXT: (local.set $x
873+
;; CHECK-NEXT: (block (result i32)
874+
;; CHECK-NEXT: (array.set $shared-array
875+
;; CHECK-NEXT: (local.get $shared)
876+
;; CHECK-NEXT: (i32.const 0)
877+
;; CHECK-NEXT: (i32.const 0)
878+
;; CHECK-NEXT: )
879+
;; CHECK-NEXT: (i32.const 1)
880+
;; CHECK-NEXT: )
881+
;; CHECK-NEXT: )
882+
;; CHECK-NEXT: (atomic.fence)
883+
;; CHECK-NEXT: (local.get $x)
884+
;; CHECK-NEXT: )
885+
(func $write-array-fence (param $shared (ref null $shared-array)) (result i32)
886+
(local $x i32)
887+
;; A shared struct read cannot be moved past an atomic.fence.
888+
(local.set $x
889+
(block (result i32)
890+
(array.set $shared-array
891+
(local.get $shared)
892+
(i32.const 0)
893+
(i32.const 0)
894+
)
895+
(i32.const 1)
896+
)
897+
)
898+
(atomic.fence)
899+
(local.get $x)
900+
)
798901
)

0 commit comments

Comments
 (0)