Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2793,6 +2793,7 @@ struct OptimizeInstructions

// Ignore extraneous things and compare them syntactically. We can also
// look at the full fallthrough for both sides now.
auto* originalLeft = left;
left = getFallthrough(left);
auto* originalRight = right;
right = getFallthrough(right);
Expand Down Expand Up @@ -2821,6 +2822,26 @@ struct OptimizeInstructions
}
}

// The same, with left, as we can have this situation:
//
// (local.tee $x ..)
// (something using $x)
// )
// (something using $x)
//
// The fallthroughs are identical, but the tee may cause us to read a
// different value.
if (originalLeft != left) {
auto originalLeftEffects = effects(originalLeft);
// |left == right| here (we would have exited early, otherwise, above), so
// we could compute either. Compute |left| as it might have better cache
// locality.
auto leftEffects = effects(left);
if (originalLeftEffects.invalidates(leftEffects)) {
return false;
}
}

// To be equal, they must also be known to return the same result
// deterministically. We check the right side, as if the right is marked
// idempotent, that is enough (that tells us it does not generate a new
Expand Down
37 changes: 37 additions & 0 deletions test/lit/passes/optimize-instructions-mvp.wast
Original file line number Diff line number Diff line change
Expand Up @@ -16451,6 +16451,43 @@
)
)
)

;; CHECK: (func $ternary-tee-with-identical-values (param $x i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.and
;; CHECK-NEXT: (local.tee $x
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $ternary-tee-with-identical-values (param $x i32)
(drop
;; The tee's value, and the select's condition, are equal. If we just
;; look at them, we could think they are equal, and simplify this.
;; However, the tee modifies $x, so we cannot fold those two
;; expressions together while removing the select. (We can, though,
;; remove the select and the const, and use an and, but we do remain with
;; two copies of the eq, as those interact.)
(select
(local.tee $x
(i32.eqz
(local.get $x)
)
)
(i32.const 0)
(i32.eqz
(local.get $x)
)
)
)
)

;; CHECK: (func $send-i32 (param $0 i32)
;; CHECK-NEXT: )
(func $send-i32 (param i32))
Expand Down
Loading