aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-02-02 16:05:57 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-02-02 16:05:57 -0800
commitd1155beddaf5d755ee8deff80fbd787a3d09cfb3 (patch)
treeedccdb6f85f08f7b846ab021c18a576a2c708098
parent364948c9a25be1896bdbdf02b9d708bd7972436c (diff)
fix negative i64 comparisons
-rw-r--r--src/parseTools.js24
-rwxr-xr-xtests/runner.py31
2 files changed, 47 insertions, 8 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index f1413c1c..6986d1c1 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1661,14 +1661,22 @@ function processMathop(item) {
case 'fptoui': case 'fptosi': return splitI64(ident1);
case 'icmp': {
switch (variant) {
- case 'uge': case 'sge': return ident1 + '[1] >= ' + ident2 + '[1] && (' + ident1 + '[1] > ' + ident2 + '[1] || ' +
- ident1 + '[0] >= ' + ident2 + '[0])';
- case 'ule': case 'sle': return ident1 + '[1] <= ' + ident2 + '[1] && (' + ident1 + '[1] < ' + ident2 + '[1] || ' +
- ident1 + '[0] <= ' + ident2 + '[0])';
- case 'ugt': case 'sgt': return ident1 + '[1] > ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
- ident1 + '[0] > ' + ident2 + '[0])';
- case 'ult': case 'slt': return ident1 + '[1] < ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
- ident1 + '[0] < ' + ident2 + '[0])';
+ case 'uge': return ident1 + '[1] >= ' + ident2 + '[1] && (' + ident1 + '[1] > ' + ident2 + '[1] || ' +
+ ident1 + '[0] >= ' + ident2 + '[0])';
+ case 'sge': return '(' + ident1 + '[1]|0) >= (' + ident2 + '[1]|0) && ((' + ident1 + '[1]|0) > (' + ident2 + '[1]|0) || ' +
+ '(' + ident1 + '[0]|0) >= (' + ident2 + '[0]|0))';
+ case 'ule': return ident1 + '[1] <= ' + ident2 + '[1] && (' + ident1 + '[1] < ' + ident2 + '[1] || ' +
+ ident1 + '[0] <= ' + ident2 + '[0])';
+ case 'sle': return '(' + ident1 + '[1]|0) <= (' + ident2 + '[1]|0) && ((' + ident1 + '[1]|0) < (' + ident2 + '[1]|0) || ' +
+ '(' + ident1 + '[0]|0) <= (' + ident2 + '[0]|0))';
+ case 'ugt': return ident1 + '[1] > ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
+ ident1 + '[0] > ' + ident2 + '[0])';
+ case 'sgt': return '(' + ident1 + '[1]|0) > (' + ident2 + '[1]|0) || ((' + ident1 + '[1]|0) == (' + ident2 + '[1]|0) && ' +
+ '(' + ident1 + '[0]|0) > (' + ident2 + '[0]|0))';
+ case 'ult': return ident1 + '[1] < ' + ident2 + '[1] || (' + ident1 + '[1] == ' + ident2 + '[1] && ' +
+ ident1 + '[0] < ' + ident2 + '[0])';
+ case 'slt': return '(' + ident1 + '[1]|0) < (' + ident2 + '[1]|0) || ((' + ident1 + '[1]|0) == (' + ident2 + '[1]|0) && ' +
+ '(' + ident1 + '[0]|0) < (' + ident2 + '[0]|0))';
case 'ne': case 'eq': {
// We must sign them, so we do not compare -1 to 255 (could have unsigned them both too)
// since LLVM tells us if <=, >= etc. comparisons are signed, but not == and !=.
diff --git a/tests/runner.py b/tests/runner.py
index 4a1443e1..fdfafbc8 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -583,6 +583,37 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv):
'*-1,34359738367,4294967295,1073741823*\n' +
'*prod:34*')
+ src = r'''
+ #include <stdio.h>
+ #include <limits>
+
+ int main()
+ {
+ long long i,j,k;
+
+ i = 0;
+ j = -1,
+ k = 1;
+
+ printf( "*\n" );
+ printf( "%s\n", i > j ? "Ok": "Fail" );
+ printf( "%s\n", k > i ? "Ok": "Fail" );
+ printf( "%s\n", k > j ? "Ok": "Fail" );
+ printf( "%s\n", i < j ? "Fail": "Ok" );
+ printf( "%s\n", k < i ? "Fail": "Ok" );
+ printf( "%s\n", k < j ? "Fail": "Ok" );
+ printf( "%s\n", (i-j) >= k ? "Ok": "Fail" );
+ printf( "%s\n", (i-j) <= k ? "Ok": "Fail" );
+ printf( "%s\n", i > std::numeric_limits<long long>::min() ? "Ok": "Fail" );
+ printf( "%s\n", i < std::numeric_limits<long long>::max() ? "Ok": "Fail" );
+ printf( "*\n" );
+ }
+ '''
+
+ self.do_run(src, '*\nOk\nOk\nOk\nOk\nOk\nOk\nOk\nOk\nOk\nOk\n*')
+
+ # stuff that also needs sign corrections
+
Settings.CORRECT_SIGNS = 1
src = r'''