summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/RemoveUnusedBrs.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 5631c9d5f..157cfc1f3 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -97,6 +97,12 @@ static bool tooCostlyToRunUnconditionally(const PassOptions& passOptions,
return total >= TOO_MUCH;
}
+static bool canEmitSelectWithArms(Expression* ifTrue, Expression* ifFalse) {
+ // A select only allows a single value in its arms in the spec:
+ // https://webassembly.github.io/spec/core/valid/instructions.html#xref-syntax-instructions-syntax-instr-parametric-mathsf-select-t-ast
+ return ifTrue->type.isSingle() && ifFalse->type.isSingle();
+}
+
struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
bool isFunctionParallel() override { return true; }
@@ -1023,7 +1029,8 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
EffectAnalyzer(passOptions, features, curr)
.hasSideEffects();
list[0] = old;
- if (canReorder && !hasSideEffects) {
+ if (canReorder && !hasSideEffects &&
+ canEmitSelectWithArms(br->value, curr)) {
ExpressionManipulator::nop(list[0]);
replaceCurrent(
builder.makeSelect(br->condition, br->value, curr));
@@ -1044,8 +1051,11 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
// Convert an if into a select, if possible and beneficial to do so.
Select* selectify(If* iff) {
- if (!iff->ifFalse || !iff->ifTrue->type.isSingle() ||
- !iff->ifFalse->type.isSingle()) {
+ // Only an if-else can be turned into a select.
+ if (!iff->ifFalse) {
+ return nullptr;
+ }
+ if (!canEmitSelectWithArms(iff->ifTrue, iff->ifFalse)) {
return nullptr;
}
if (iff->condition->type == Type::unreachable) {