diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-04-24 16:09:03 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-04-24 16:09:03 -0700 |
commit | a81c27d892bf51f6f472c96c44833c0ff5393745 (patch) | |
tree | 2b90d87e32ffacd229b28a1676d5eb59d5840371 | |
parent | 73afeab08ce9f7166da1c85590d2d22a4a53055e (diff) | |
parent | c8eeaf336ff6b82664da34b04d06ba7283a9f262 (diff) |
Merge pull request #1088 from juj/branchless_i64_ops
Remove 'if()' branches from i64 add and subtract code.
-rw-r--r-- | src/library.js | 17 | ||||
-rw-r--r-- | tests/cases/uadd_overflow_64_ta2.ll | 6 | ||||
-rw-r--r-- | tests/cases/uadd_overflow_64_ta2.txt | 1 |
3 files changed, 12 insertions, 12 deletions
diff --git a/src/library.js b/src/library.js index ae0c845c..5bbf4204 100644 --- a/src/library.js +++ b/src/library.js @@ -7511,10 +7511,7 @@ LibraryManager.library = { a = a|0; b = b|0; c = c|0; d = d|0; var l = 0, h = 0; l = (a + c)>>>0; - h = (b + d)>>>0; - if ((l>>>0) < (a>>>0)) { // iff we overflowed - h = (h+1)>>>0; - } + h = (((b + d)>>>0) + (((l>>>0) < (a>>>0))>>>0))>>>0; // Add carry from low word to high word on overflow. {{{ makeStructuralReturn(['l|0', 'h'], true) }}}; }, llvm_uadd_with_overflow_i64__asm: true, @@ -7524,11 +7521,9 @@ LibraryManager.library = { var l = 0, h = 0, overflow = 0; l = (a + c)>>>0; h = (b + d)>>>0; - if ((h>>>0) < (b>>>0)) overflow = 1; - if ((l>>>0) < (a>>>0)) { - h = (h+1)>>>0; - if ((h>>>0) == 0) overflow = 1; // two possibilities to overflow here - } + overflow = ((h>>>0) < (b>>>0))>>>0; // Return whether addition overflowed even the high word. + h = h + (((l>>>0) < (a>>>0))>>>0)>>>0; // Add carry from low word to high word on overflow. + overflow = overflow | (h == 0); // Check again for overflow. {{{ makeStructuralReturn(['l|0', 'h', 'overflow'], true) }}}; }, @@ -7539,9 +7534,7 @@ LibraryManager.library = { var l = 0, h = 0; l = (a - c)>>>0; h = (b - d)>>>0; - if ((l>>>0) > (a>>>0)) { // iff we overflowed - h = (h-1)>>>0; - } + h = (((b - d)>>>0) - (((c>>>0) > (a>>>0))>>>0))>>>0; // Borrow one from high word to low word on underflow. {{{ makeStructuralReturn(['l|0', 'h'], true) }}}; }, diff --git a/tests/cases/uadd_overflow_64_ta2.ll b/tests/cases/uadd_overflow_64_ta2.ll index a4f3e40b..6dfbc1e5 100644 --- a/tests/cases/uadd_overflow_64_ta2.ll +++ b/tests/cases/uadd_overflow_64_ta2.ll @@ -19,6 +19,12 @@ entry: %b2 = zext i1 %b1 to i32 call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str2, i32 0, i32 0), i64 %b0, i32 %b2) ; [#uses=0] + %uadd3 = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 4294967297, i64 18446744073709551615) + %c0 = extractvalue { i64, i1 } %uadd3, 0 + %c1 = extractvalue { i64, i1 } %uadd3, 1 + %c2 = zext i1 %c1 to i32 + call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str2, i32 0, i32 0), i64 %c0, i32 %c2) ; [#uses=0] + ret i32 1 } diff --git a/tests/cases/uadd_overflow_64_ta2.txt b/tests/cases/uadd_overflow_64_ta2.txt index f5711309..2abb084c 100644 --- a/tests/cases/uadd_overflow_64_ta2.txt +++ b/tests/cases/uadd_overflow_64_ta2.txt @@ -1,2 +1,3 @@ *2705,1* *10c6f7a0dcfc,0* +*100000000,1*
\ No newline at end of file |