Skip to content

Commit 56e4975

Browse files
committed
do not swap elements in conditionalizeExpensiveOnBitwise if they invalidate each other - it is not enough to check side effects, we must check the interaction as well
1 parent 7a06499 commit 56e4975

3 files changed

Lines changed: 143 additions & 6 deletions

src/passes/OptimizeInstructions.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -874,14 +874,17 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
874874
auto* left = binary->left;
875875
auto* right = binary->right;
876876
if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right)) return nullptr;
877-
auto leftEffects = EffectAnalyzer(getPassOptions(), left).hasSideEffects();
878-
auto rightEffects = EffectAnalyzer(getPassOptions(), right).hasSideEffects();
879-
if (leftEffects && rightEffects) return nullptr; // both must execute
880-
// canonicalize with side effects, if any, happening on the left
881-
if (rightEffects) {
877+
auto leftEffects = EffectAnalyzer(getPassOptions(), left);
878+
auto rightEffects = EffectAnalyzer(getPassOptions(), right);
879+
auto leftSideEffects = leftEffects.hasSideEffects();
880+
auto rightSideEffects = rightEffects.hasSideEffects();
881+
if (leftSideEffects && rightSideEffects) return nullptr; // both must execute
882+
// canonicalize with side effects, if any, happening on the left
883+
if (rightSideEffects) {
882884
if (CostAnalyzer(left).cost < MIN_COST) return nullptr; // avoidable code is too cheap
885+
if (leftEffects.invalidates(rightEffects)) return nullptr; // cannot reorder
883886
std::swap(left, right);
884-
} else if (leftEffects) {
887+
} else if (leftSideEffects) {
885888
if (CostAnalyzer(right).cost < MIN_COST) return nullptr; // avoidable code is too cheap
886889
} else {
887890
// no side effects, reorder based on cost estimation

test/passes/optimize-instructions_optimize-level=2_ignore-implicit-traps.txt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,74 @@
251251
(get_local $5)
252252
)
253253
)
254+
(func $invalidate-conditionalizeExpensiveOnBitwise (type $0) (param $0 i32) (param $1 i32) (result i32)
255+
(if
256+
(i32.eqz
257+
(i32.and
258+
(i32.lt_s
259+
(i32.and
260+
(i32.shr_s
261+
(i32.shl
262+
(i32.add
263+
(get_local $1)
264+
(i32.const -1)
265+
)
266+
(i32.const 24)
267+
)
268+
(i32.const 24)
269+
)
270+
(i32.const 255)
271+
)
272+
(i32.const 3)
273+
)
274+
(i32.ne
275+
(tee_local $1
276+
(i32.const 0)
277+
)
278+
(i32.const 0)
279+
)
280+
)
281+
)
282+
(return
283+
(get_local $0)
284+
)
285+
)
286+
(return
287+
(get_local $1)
288+
)
289+
)
290+
(func $invalidate-conditionalizeExpensiveOnBitwise-ok (type $0) (param $0 i32) (param $1 i32) (result i32)
291+
(if
292+
(i32.eqz
293+
(if (result i32)
294+
(tee_local $1
295+
(i32.const 0)
296+
)
297+
(i32.lt_s
298+
(i32.and
299+
(i32.shr_s
300+
(i32.shl
301+
(i32.add
302+
(get_local $0)
303+
(i32.const -1)
304+
)
305+
(i32.const 24)
306+
)
307+
(i32.const 24)
308+
)
309+
(i32.const 255)
310+
)
311+
(i32.const 3)
312+
)
313+
(i32.const 0)
314+
)
315+
)
316+
(return
317+
(get_local $0)
318+
)
319+
)
320+
(return
321+
(get_local $1)
322+
)
323+
)
254324
)

test/passes/optimize-instructions_optimize-level=2_ignore-implicit-traps.wast

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,5 +259,69 @@
259259
(get_local $5)
260260
)
261261
)
262+
(func $invalidate-conditionalizeExpensiveOnBitwise (param $0 i32) (param $1 i32) (result i32)
263+
(if
264+
(i32.eqz
265+
(i32.and
266+
(i32.lt_s
267+
(i32.and
268+
(i32.shr_s
269+
(i32.shl
270+
(i32.add
271+
(get_local $1) ;; conflict with tee
272+
(i32.const -1)
273+
)
274+
(i32.const 24)
275+
)
276+
(i32.const 24)
277+
)
278+
(i32.const 255)
279+
)
280+
(i32.const 3)
281+
)
282+
(i32.ne
283+
(tee_local $1
284+
(i32.const 0)
285+
)
286+
(i32.const 0)
287+
)
288+
)
289+
)
290+
(return (get_local $0))
291+
)
292+
(return (get_local $1))
293+
)
294+
(func $invalidate-conditionalizeExpensiveOnBitwise-ok (param $0 i32) (param $1 i32) (result i32)
295+
(if
296+
(i32.eqz
297+
(i32.and
298+
(i32.lt_s
299+
(i32.and
300+
(i32.shr_s
301+
(i32.shl
302+
(i32.add
303+
(get_local $0) ;; no conflict
304+
(i32.const -1)
305+
)
306+
(i32.const 24)
307+
)
308+
(i32.const 24)
309+
)
310+
(i32.const 255)
311+
)
312+
(i32.const 3)
313+
)
314+
(i32.ne
315+
(tee_local $1
316+
(i32.const 0)
317+
)
318+
(i32.const 0)
319+
)
320+
)
321+
)
322+
(return (get_local $0))
323+
)
324+
(return (get_local $1))
325+
)
262326
)
263327

0 commit comments

Comments
 (0)