@@ -37,6 +37,77 @@ Example of some instructions we would like to add:
37
37
- Relaxed Swizzle (implementation defined out of bounds behavior)
38
38
- Relaxed Rounding Q-format Multiplication (optional saturation)
39
39
40
+ ### Consistency
41
+
42
+ This proposal introduces non-deterministic instructions - given the same
43
+ inputs, two calls to the same instruction can return different results. For
44
+ example:
45
+
46
+ ``` wast
47
+ (module
48
+ (func (param v128 v128 v128)
49
+ (f32x4.qfma (local.get 0) (local.get 1) (local.get 2)) ;; (1)
50
+ ;; some other computation
51
+ (f32x4.qfma (local.get 0) (local.get 1) (local.get 2)))) ;; (2)
52
+ ```
53
+
54
+ The same instruction at ` (1) ` and ` (2) ` , when given the same inputs, can return
55
+ two different results. This is compliant as the instruction is
56
+ non-deterministic, though unlikely on certain embeddings like the Web (where
57
+ the same implementation for ` f32x4.qfma ` is likely to be used for all calls to
58
+ that instruction). One can imagine splitting an application's module and
59
+ running them on multiple runtimes, where the runtimes produce
60
+ different results - this can be surprising to the application.
61
+
62
+ Applications can specify their consistency needs using a new module-level
63
+ entity ` fpenv ` (name subject to change). A ` fpenv ` is defined in the ` fpenv `
64
+ section of a module. All Relaxed SIMD instructions will take an additional
65
+ ` varuint32 ` immediate, which is an index into the ` fpenv ` index space:
66
+
67
+ ``` wast
68
+ (module
69
+ (func (param v128 v128 v128)
70
+ (f32x4.qfma $fpu (local.get 0) (local.get 1) (local.get 2)) ;; (1)
71
+ ;; ...
72
+ (f32x4.qfma $fpu (local.get 0) (local.get 1) (local.get 2)) ;; (2)
73
+ )
74
+ (fpenv $fpu 0))
75
+ ```
76
+
77
+ In the example above, both ` f32x4.qfma ` instructions refer to the same ` fpenv ` ,
78
+ and will get the same results when given the same input.
79
+
80
+ A ` fpenv ` has a single ` varuint32 ` attribute which is reserved for future
81
+ extensibility and must be ` 0 ` for now. The value of an ` fpenv ` is
82
+ non-deterministically computed when the module which declares it is
83
+ instantiated. This value determines the semantics of the instructions that
84
+ uses it as an immediate.
85
+
86
+ As such, all the non-determinism of Relaxed SIMD is encapsulated in ` fpenv ` ,
87
+ which makes Relaxed SIMD instructions themselves deterministic.
88
+
89
+ Modules can import/export an ` fpenv ` to specify consistency requirements:
90
+
91
+ ``` wast
92
+ ;; module a
93
+ (module
94
+ (fpenv $fpu (export "foo") 0)
95
+ (func (param v128 v128 v128)
96
+ (f32x4.qfma $fpu (local.get 0) (local.get 1) (local.get 2)))) ;; (1)
97
+ ```
98
+
99
+ ``` wast
100
+ ;; module b
101
+ (module
102
+ (import "a" "foo" (fpenv $fpu 0))
103
+ (func (param v128 v128 v128)
104
+ (f32x4.qfma $fpu (local.get 0) (local.get 1) (local.get 2)))) ;; (2)
105
+ ```
106
+
107
+ In the above example, the same ` fpenv ` is exported by module ` a ` , and imported
108
+ by module ` b ` , so instructions ` (1) ` and ` (2) ` will consistently return the
109
+ same results when given the same inputs.
110
+
40
111
## References
41
112
42
113
- Poll for phase 1
0 commit comments