Skip to content

Commit 7d9ec2f

Browse files
authored
[BranchHinting] Do not reorder traps in OptimizeInstructions when neverReorder is set (#9096)
In the neverReorder testing mode, no code can be reordered, as reordering it past branch hints leads to fuzzer errors.
1 parent 5eb87bf commit 7d9ec2f

2 files changed

Lines changed: 53 additions & 10 deletions

File tree

src/passes/OptimizeInstructions.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,17 @@ struct OptimizeInstructions
16111611
// ref.as_non_null then the struct.set will still trap, of course, but that
16121612
// will only happen *after* the call, which is wrong.
16131613
void skipNonNullCast(Expression*& input, Expression* parent) {
1614+
// If we must never reorder code, then we cannot remove a non-null cast.
1615+
// Such removals are valid because we move the trap later (see the
1616+
// struct.set in the example above: we can remove the ref.as_non_null
1617+
// because the set will trap anyhow, so we are pushing the trap onward; in
1618+
// the example above we have a call we can't move past, and in neverReorder
1619+
// mode we need to care about things like branch hints, which do not have
1620+
// effects, hence the need for the special neverReorder flag).
1621+
if (neverReorder) {
1622+
return;
1623+
}
1624+
16141625
// Check the other children for the ordering problem only if we find a
16151626
// possible optimization, to avoid wasted work.
16161627
bool checkedSiblings = false;

test/lit/passes/optimize-instructions_branch-hints-fold.wast

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
;; RUN: | filecheck %s --check-prefix=NO_FO
1313

1414
(module
15-
;; CHECK: (func $conditionals (type $1) (param $x i32) (result i32)
15+
;; CHECK: (type $struct (struct (field (mut i32))))
16+
;; NO_FO: (type $struct (struct (field (mut i32))))
17+
(type $struct (struct (mut i32)))
18+
19+
;; CHECK: (func $conditionals (type $2) (param $x i32) (result i32)
1620
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
1721
;; CHECK-NEXT: (if (result i32)
1822
;; CHECK-NEXT: (local.get $x)
@@ -24,7 +28,7 @@
2428
;; CHECK-NEXT: )
2529
;; CHECK-NEXT: )
2630
;; CHECK-NEXT: )
27-
;; NO_FO: (func $conditionals (type $1) (param $x i32) (result i32)
31+
;; NO_FO: (func $conditionals (type $2) (param $x i32) (result i32)
2832
;; NO_FO-NEXT: (@metadata.code.branch_hint "\01")
2933
;; NO_FO-NEXT: (if (result i32)
3034
;; NO_FO-NEXT: (local.get $x)
@@ -52,7 +56,7 @@
5256
)
5357
)
5458

55-
;; CHECK: (func $still-fold (type $0) (param $x i32) (param $y i32)
59+
;; CHECK: (func $still-fold (type $1) (param $x i32) (param $y i32)
5660
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
5761
;; CHECK-NEXT: (if
5862
;; CHECK-NEXT: (local.get $y)
@@ -61,7 +65,7 @@
6165
;; CHECK-NEXT: )
6266
;; CHECK-NEXT: )
6367
;; CHECK-NEXT: )
64-
;; NO_FO: (func $still-fold (type $0) (param $x i32) (param $y i32)
68+
;; NO_FO: (func $still-fold (type $1) (param $x i32) (param $y i32)
6569
;; NO_FO-NEXT: (if
6670
;; NO_FO-NEXT: (local.get $x)
6771
;; NO_FO-NEXT: (then
@@ -110,7 +114,7 @@
110114
)
111115
)
112116

113-
;; CHECK: (func $yes-fold (type $0) (param $x i32) (param $y i32)
117+
;; CHECK: (func $yes-fold (type $1) (param $x i32) (param $y i32)
114118
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
115119
;; CHECK-NEXT: (if
116120
;; CHECK-NEXT: (local.get $y)
@@ -119,7 +123,7 @@
119123
;; CHECK-NEXT: )
120124
;; CHECK-NEXT: )
121125
;; CHECK-NEXT: )
122-
;; NO_FO: (func $yes-fold (type $0) (param $x i32) (param $y i32)
126+
;; NO_FO: (func $yes-fold (type $1) (param $x i32) (param $y i32)
123127
;; NO_FO-NEXT: (if
124128
;; NO_FO-NEXT: (local.get $x)
125129
;; NO_FO-NEXT: (then
@@ -167,7 +171,7 @@
167171
)
168172
)
169173

170-
;; CHECK: (func $always-fold-select (type $2) (param $x i32) (param $y i32) (result i32)
174+
;; CHECK: (func $always-fold-select (type $3) (param $x i32) (param $y i32) (result i32)
171175
;; CHECK-NEXT: (drop
172176
;; CHECK-NEXT: (local.get $y)
173177
;; CHECK-NEXT: )
@@ -182,7 +186,7 @@
182186
;; CHECK-NEXT: )
183187
;; CHECK-NEXT: )
184188
;; CHECK-NEXT: )
185-
;; NO_FO: (func $always-fold-select (type $2) (param $x i32) (param $y i32) (result i32)
189+
;; NO_FO: (func $always-fold-select (type $3) (param $x i32) (param $y i32) (result i32)
186190
;; NO_FO-NEXT: (local $2 i32)
187191
;; NO_FO-NEXT: (local.set $2
188192
;; NO_FO-NEXT: (@metadata.code.branch_hint "\00")
@@ -230,7 +234,7 @@
230234
)
231235
)
232236

233-
;; CHECK: (func $ordering (type $3) (param $x i32)
237+
;; CHECK: (func $ordering (type $4) (param $x i32)
234238
;; CHECK-NEXT: (drop
235239
;; CHECK-NEXT: (i32.add
236240
;; CHECK-NEXT: (local.get $x)
@@ -244,7 +248,7 @@
244248
;; CHECK-NEXT: )
245249
;; CHECK-NEXT: )
246250
;; CHECK-NEXT: )
247-
;; NO_FO: (func $ordering (type $3) (param $x i32)
251+
;; NO_FO: (func $ordering (type $4) (param $x i32)
248252
;; NO_FO-NEXT: (drop
249253
;; NO_FO-NEXT: (i32.add
250254
;; NO_FO-NEXT: (local.get $x)
@@ -275,4 +279,32 @@
275279
)
276280
)
277281
)
282+
283+
;; CHECK: (func $struct-set (type $5) (param $ref (ref null $struct)) (param $val i32)
284+
;; CHECK-NEXT: (struct.set $struct 0
285+
;; CHECK-NEXT: (local.get $ref)
286+
;; CHECK-NEXT: (local.get $val)
287+
;; CHECK-NEXT: )
288+
;; CHECK-NEXT: )
289+
;; NO_FO: (func $struct-set (type $5) (param $ref (ref null $struct)) (param $val i32)
290+
;; NO_FO-NEXT: (struct.set $struct 0
291+
;; NO_FO-NEXT: (ref.as_non_null
292+
;; NO_FO-NEXT: (local.get $ref)
293+
;; NO_FO-NEXT: )
294+
;; NO_FO-NEXT: (local.get $val)
295+
;; NO_FO-NEXT: )
296+
;; NO_FO-NEXT: )
297+
(func $struct-set (param $ref (ref null $struct)) (param $val i32)
298+
;; Normally we can skip the ref.as_non_null because struct.set will trap on
299+
;; null anyway. But when never-fold-or-reorder is passed, we must not move the
300+
;; trap after subsequent children (which might reorder across branch hints, if
301+
;; the struct.set's value had a branch hint).
302+
(struct.set $struct 0
303+
(ref.as_non_null
304+
(local.get $ref)
305+
)
306+
(local.get $val)
307+
)
308+
)
278309
)
310+

0 commit comments

Comments
 (0)