diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-03-09 16:46:38 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-09 16:46:38 -0800 |
commit | d79d71ac7dfe807a5e98b94c9d1f67df4da7998a (patch) | |
tree | a795b28fd5ca074c7a901ede07dcaa0fc571bdc0 /src/passes/OptimizeInstructions.cpp | |
parent | be4be557567251a73f40bfd7a48220b33f5ddc58 (diff) | |
download | binaryen-d79d71ac7dfe807a5e98b94c9d1f67df4da7998a.tar.gz binaryen-d79d71ac7dfe807a5e98b94c9d1f67df4da7998a.tar.bz2 binaryen-d79d71ac7dfe807a5e98b94c9d1f67df4da7998a.zip |
fix sign-ext opt issues (#935)
* fix a bug where compared sign-exts of different sizes were turned into zero-exts
* fix a bug where we consider an almost sign-ext as ok to change the sign of a load inside it, ignoring that the load has the extra shifting
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 02475e4dc..ad828dafc 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -404,13 +404,15 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, if (auto* ext = Properties::getAlmostSignExt(binary)) { Index extraShifts; auto bits = Properties::getAlmostSignExtBits(binary, extraShifts); - if (auto* load = getFallthrough(ext)->dynCast<Load>()) { - // pattern match a load of 8 bits and a sign extend using a shl of 24 then shr_s of 24 as well, etc. - if ((load->bytes == 1 && bits == 8) || (load->bytes == 2 && bits == 16)) { - // if the value falls through, we can't alter the load, as it might be captured in a tee - if (load->signed_ == true || load == ext) { - load->signed_ = true; - return removeAlmostSignExt(binary); + if (extraShifts == 0) { + if (auto* load = getFallthrough(ext)->dynCast<Load>()) { + // pattern match a load of 8 bits and a sign extend using a shl of 24 then shr_s of 24 as well, etc. + if ((load->bytes == 1 && bits == 8) || (load->bytes == 2 && bits == 16)) { + // if the value falls through, we can't alter the load, as it might be captured in a tee + if (load->signed_ == true || load == ext) { + load->signed_ = true; + return ext; + } } } } @@ -435,11 +437,13 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, } } else if (auto* left = Properties::getSignExtValue(binary->left)) { if (auto* right = Properties::getSignExtValue(binary->right)) { - // we are comparing two sign-exts, so we may as well replace both with cheaper zexts auto bits = Properties::getSignExtBits(binary->left); - binary->left = makeZeroExt(left, bits); - binary->right = makeZeroExt(right, bits); - return binary; + if (Properties::getSignExtBits(binary->right) == bits) { + // we are comparing two sign-exts with the same bits, so we may as well replace both with cheaper zexts + binary->left = makeZeroExt(left, bits); + binary->right = makeZeroExt(right, bits); + return binary; + } } else if (auto* load = binary->right->dynCast<Load>()) { // we are comparing a load to a sign-ext, we may be able to switch to zext auto leftBits = Properties::getSignExtBits(binary->left); |