summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp20
-rw-r--r--test/passes/optimize-instructions.txt57
-rw-r--r--test/passes/optimize-instructions.wast52
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)))