diff options
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 20cdeee19..003f204a9 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -210,7 +210,7 @@ struct OptimizeInstructions return nullptr; } if (auto* binary = curr->dynCast<Binary>()) { - if (isSymmetric(binary)) { + if (isSymmetricOrRelational(binary)) { canonicalize(binary); } } @@ -895,9 +895,12 @@ private: // Canonicalizing the order of a symmetric binary helps us // write more concise pattern matching code elsewhere. void canonicalize(Binary* binary) { - assert(isSymmetric(binary)); + assert(isSymmetricOrRelational(binary)); auto swap = [&]() { assert(canReorder(binary->left, binary->right)); + if (binary->isRelational()) { + binary->op = reverseRelationalOp(binary->op); + } std::swap(binary->left, binary->right); }; auto maybeSwap = [&]() { @@ -2183,6 +2186,81 @@ private: } } + BinaryOp reverseRelationalOp(BinaryOp op) { + switch (op) { + case EqInt32: + return EqInt32; + case NeInt32: + return NeInt32; + case LtSInt32: + return GtSInt32; + case LtUInt32: + return GtUInt32; + case LeSInt32: + return GeSInt32; + case LeUInt32: + return GeUInt32; + case GtSInt32: + return LtSInt32; + case GtUInt32: + return LtUInt32; + case GeSInt32: + return LeSInt32; + case GeUInt32: + return LeUInt32; + + case EqInt64: + return EqInt64; + case NeInt64: + return NeInt64; + case LtSInt64: + return GtSInt64; + case LtUInt64: + return GtUInt64; + case LeSInt64: + return GeSInt64; + case LeUInt64: + return GeUInt64; + case GtSInt64: + return LtSInt64; + case GtUInt64: + return LtUInt64; + case GeSInt64: + return LeSInt64; + case GeUInt64: + return LeUInt64; + + case EqFloat32: + return EqFloat32; + case NeFloat32: + return NeFloat32; + case LtFloat32: + return GtFloat32; + case LeFloat32: + return GeFloat32; + case GtFloat32: + return LtFloat32; + case GeFloat32: + return LeFloat32; + + case EqFloat64: + return EqFloat64; + case NeFloat64: + return NeFloat64; + case LtFloat64: + return GtFloat64; + case LeFloat64: + return GeFloat64; + case GtFloat64: + return LtFloat64; + case GeFloat64: + return LeFloat64; + + default: + return InvalidBinary; + } + } + BinaryOp makeUnsignedBinaryOp(BinaryOp op) { switch (op) { case DivSInt32: @@ -2220,8 +2298,8 @@ private: } } - bool isSymmetric(Binary* binary) { - if (Properties::isSymmetric(binary)) { + bool isSymmetricOrRelational(Binary* binary) { + if (Properties::isSymmetric(binary) || binary->isRelational()) { return true; } switch (binary->op) { |