diff options
author | Alon Zakai <azakai@google.com> | 2020-11-12 06:46:22 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-12 06:46:22 -0800 |
commit | d41782f9cac8cb059ccc03f69e10d44849e3d10f (patch) | |
tree | 56fcb1ad85ccaae824aae777ea4318ba1449504f /src/passes/OptimizeInstructions.cpp | |
parent | 24bd9b984fc71c38d3d24c5f03fa81a15d591322 (diff) | |
download | binaryen-d41782f9cac8cb059ccc03f69e10d44849e3d10f.tar.gz binaryen-d41782f9cac8cb059ccc03f69e10d44849e3d10f.tar.bz2 binaryen-d41782f9cac8cb059ccc03f69e10d44849e3d10f.zip |
OptimizeInstructions: Fix regression from #3303 / #3275 (#3338)
X - Y <= 0
=>
X <= Y
That is true mathematically, but not in the case of an overflow, e.g.
X=10, Y=0x8000000000000000. X - Y is a negative number, so
X - Y <= 0 is true. But it is not true that X <= Y (as Y is negative, but
X is not).
See discussion in #3303 (comment)
The actual regression was in #3275, but the fuzzer had an easier time
finding it due to #3303
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 51a188c15..83bee9a0f 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1965,17 +1965,16 @@ private: curr->left = inner->left; return curr; } - // signed(x - y) <=> 0 => x <=> y + // x - y == 0 => x == y + // x - y != 0 => x != y + // This is not true for signed comparisons like x -y < 0 due to overflow + // effects (e.g. 8 - 0x80000000 < 0 is not the same as 8 < 0x80000000). if (matches(curr, binary(&op, binary(&inner, Abstract::Sub, any(), any()), ival(0))) && (op == Abstract::getBinary(type, Abstract::Eq) || - op == Abstract::getBinary(type, Abstract::Ne) || - op == Abstract::getBinary(type, Abstract::LeS) || - op == Abstract::getBinary(type, Abstract::LtS) || - op == Abstract::getBinary(type, Abstract::GeS) || - op == Abstract::getBinary(type, Abstract::GtS))) { + op == Abstract::getBinary(type, Abstract::Ne))) { curr->right = inner->right; curr->left = inner->left; return curr; |