summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2021-07-16 22:33:46 +0300
committerGitHub <noreply@github.com>2021-07-16 12:33:46 -0700
commit023bbb28f393032a8df6c743319cd835feddf5ba (patch)
tree0a34035df50a30243c7ed9c75d07255f659f0615 /src
parent18375122edc23a5ff9acc0c4f930357687ff24dd (diff)
downloadbinaryen-023bbb28f393032a8df6c743319cd835feddf5ba.tar.gz
binaryen-023bbb28f393032a8df6c743319cd835feddf5ba.tar.bz2
binaryen-023bbb28f393032a8df6c743319cd835feddf5ba.zip
[Optimize-Instructions] Simplify sign patterns like x < 0 ? -1 : 1 (#3756)
i32(x) < 0 ? i32(-1) : i32(1) -> x >> 31 | 1 i64(x) < 0 ? i64(-1) : i64(1) -> x >> 63 | 1 This shrinks 2 bytes.
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index d3c3f26f6..106bfea19 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1430,6 +1430,7 @@ private:
Expression* optimizeSelect(Select* curr) {
using namespace Match;
+ using namespace Abstract;
Builder builder(*getModule());
curr->condition = optimizeBoolean(curr->condition);
{
@@ -1482,6 +1483,29 @@ private:
}
}
{
+ // Simplify x < 0 ? -1 : 1 or x >= 0 ? 1 : -1 to
+ // i32(x) >> 31 | 1
+ // i64(x) >> 63 | 1
+ Binary* bin;
+ if (matches(
+ curr,
+ select(ival(-1), ival(1), binary(&bin, LtS, any(), ival(0)))) ||
+ matches(
+ curr,
+ select(ival(1), ival(-1), binary(&bin, GeS, any(), ival(0))))) {
+ auto c = bin->right->cast<Const>();
+ auto type = curr->ifTrue->type;
+ if (type == c->type) {
+ bin->type = type;
+ bin->op = Abstract::getBinary(type, ShrS);
+ c->value = Literal::makeFromInt32(type.getByteSize() * 8 - 1, type);
+ curr->ifTrue->cast<Const>()->value = Literal::makeOne(type);
+ return builder.makeBinary(
+ Abstract::getBinary(type, Or), bin, curr->ifTrue);
+ }
+ }
+ }
+ {
// Sides are identical, fold
Expression *ifTrue, *ifFalse, *c;
if (matches(curr, select(any(&ifTrue), any(&ifFalse), any(&c))) &&