diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 8b71da824..b50f99fbc 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -2157,6 +2157,67 @@ private: c->value = Literal::makeZero(c->type); return; } + // Prefer compare to signed min (s_min) instead of s_min + 1. + // (signed)x < s_min + 1 ==> x == s_min + if (binary->op == LtSInt32 && c->value.geti32() == INT32_MIN + 1) { + binary->op = EqInt32; + c->value = Literal::makeSignedMin(Type::i32); + return; + } + if (binary->op == LtSInt64 && c->value.geti64() == INT64_MIN + 1) { + binary->op = EqInt64; + c->value = Literal::makeSignedMin(Type::i64); + return; + } + // (signed)x >= s_min + 1 ==> x != s_min + if (binary->op == GeSInt32 && c->value.geti32() == INT32_MIN + 1) { + binary->op = NeInt32; + c->value = Literal::makeSignedMin(Type::i32); + return; + } + if (binary->op == GeSInt64 && c->value.geti64() == INT64_MIN + 1) { + binary->op = NeInt64; + c->value = Literal::makeSignedMin(Type::i64); + return; + } + // Prefer compare to signed max (s_max) instead of s_max - 1. + // (signed)x > s_max - 1 ==> x == s_max + if (binary->op == GtSInt32 && c->value.geti32() == INT32_MAX - 1) { + binary->op = EqInt32; + c->value = Literal::makeSignedMax(Type::i32); + return; + } + if (binary->op == GtSInt64 && c->value.geti64() == INT64_MAX - 1) { + binary->op = EqInt64; + c->value = Literal::makeSignedMax(Type::i64); + return; + } + // (signed)x <= s_max - 1 ==> x != s_max + if (binary->op == LeSInt32 && c->value.geti32() == INT32_MAX - 1) { + binary->op = NeInt32; + c->value = Literal::makeSignedMax(Type::i32); + return; + } + if (binary->op == LeSInt64 && c->value.geti64() == INT64_MAX - 1) { + binary->op = NeInt64; + c->value = Literal::makeSignedMax(Type::i64); + return; + } + // Prefer compare to unsigned max (u_max) instead of u_max - 1. + // (unsigned)x <= u_max - 1 ==> x != u_max + if (binary->op == Abstract::getBinary(c->type, Abstract::LeU) && + c->value.getInteger() == (int64_t)(UINT64_MAX - 1)) { + binary->op = Abstract::getBinary(c->type, Abstract::Ne); + c->value = Literal::makeUnsignedMax(c->type); + return; + } + // (unsigned)x > u_max - 1 ==> x == u_max + if (binary->op == Abstract::getBinary(c->type, Abstract::GtU) && + c->value.getInteger() == (int64_t)(UINT64_MAX - 1)) { + binary->op = Abstract::getBinary(c->type, Abstract::Eq); + c->value = Literal::makeUnsignedMax(c->type); + return; + } return; } // Prefer a get on the right. |