diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 20 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 57 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 52 |
3 files changed, 115 insertions, 14 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 293adcbde..6a66ae603 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -756,6 +756,26 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, std::swap(select->ifTrue, select->ifFalse); } } + if (auto* c = select->condition->dynCast<Const>()) { + // constant condition, we can just pick the right side (barring side effects) + if (c->value.getInteger()) { + if (!EffectAnalyzer(getPassOptions(), select->ifFalse).hasSideEffects()) { + return select->ifTrue; + } else { + // don't bother - we would need to reverse the order using a temp local, which is bad + } + } else { + if (!EffectAnalyzer(getPassOptions(), select->ifTrue).hasSideEffects()) { + return select->ifFalse; + } else { + Builder builder(*getModule()); + return builder.makeSequence( + builder.makeDrop(select->ifTrue), + select->ifFalse + ); + } + } + } if (ExpressionAnalyzer::equal(select->ifTrue, select->ifFalse)) { // sides are identical, fold EffectAnalyzer value(getPassOptions(), select->ifTrue); diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index bc7221d3f..0b156f803 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -219,11 +219,7 @@ ) ) (drop - (select - (i32.const 0) - (i32.const 1) - (i32.const 2) - ) + (i32.const 0) ) ) (func $load-store (; 1 ;) (type $1) @@ -2036,16 +2032,12 @@ ) ) (func $sign-ext-1-and-ne (; 36 ;) (type $2) (result i32) - (select - (i32.ne - (i32.and - (call $sign-ext-1-and-ne) - (i32.const 2147483647) - ) - (i32.const -2147483648) + (i32.ne + (i32.and + (call $sign-ext-1-and-ne) + (i32.const 2147483647) ) - (i32.const 2) - (i32.const 1) + (i32.const -2147483648) ) ) (func $neg-shifts-and-255 (; 37 ;) (type $2) (result i32) @@ -2877,6 +2869,43 @@ (get_local $x) ) ) + (func $select-on-const (; 70 ;) (type $4) (param $x i32) (param $y i32) + (drop + (get_local $x) + ) + (drop + (i32.const 3) + ) + (drop + (tee_local $x + (i32.const 5) + ) + ) + (drop + (block (result i32) + (drop + (tee_local $x + (i32.const 6) + ) + ) + (i32.const 7) + ) + ) + (drop + (select + (i32.const 4) + (tee_local $x + (i32.const 5) + ) + (i32.const 1) + ) + ) + (drop + (tee_local $x + (i32.const 6) + ) + ) + ) ) (module (type $0 (func)) diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast index f3a6b1329..b65432715 100644 --- a/test/passes/optimize-instructions.wast +++ b/test/passes/optimize-instructions.wast @@ -3427,6 +3427,58 @@ ) ) ) + (func $select-on-const (param $x i32) (param $y i32) + (drop + (select + (i32.const 2) + (get_local $x) + (i32.const 0) + ) + ) + (drop + (select + (i32.const 3) + (get_local $x) + (i32.const 1) + ) + ) + (drop + (select + (i32.const 4) + (tee_local $x + (i32.const 5) + ) + (i32.const 0) + ) + ) + (drop + (select + (tee_local $x + (i32.const 6) + ) + (i32.const 7) + (i32.const 0) + ) + ) + (drop + (select + (i32.const 4) + (tee_local $x + (i32.const 5) + ) + (i32.const 1) + ) + ) + (drop + (select + (tee_local $x + (i32.const 6) + ) + (i32.const 7) + (i32.const 1) + ) + ) + ) ) (module (import "env" "memory" (memory $0 (shared 256 256))) |