Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit cdbc2c0

Browse files
committed
Use logical operations in and let compiler to optimize.
At least Clang knows `(a < 0) != (b < 0)` pattern. The only possible shortcoming of this change is that use of logical operators currently causes compilers to emit two conditional jumps instead of one for bitwise operations.
1 parent ff2838f commit cdbc2c0

File tree

1 file changed

+12
-19
lines changed

1 file changed

+12
-19
lines changed

src/core/checkedint.d

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ pragma(inline, true)
5050
int adds(int x, int y, ref bool overflow)
5151
{
5252
const r = x + y;
53-
if ( ~x._differentSign(y) // x and y has the same sign
54-
& x._differentSign(r)) // result has different sign
53+
if ( !x._differentSign(y) // x and y has the same sign
54+
&& x._differentSign(r)) // result has different sign
5555
overflow = true;
5656
return r;
5757
}
@@ -79,8 +79,8 @@ pragma(inline, true)
7979
long adds(long x, long y, ref bool overflow)
8080
{
8181
const r = x + y;
82-
if ( ~x._differentSign(y) // x and y has the same sign
83-
& x._differentSign(r)) // result has different sign
82+
if ( !x._differentSign(y) // x and y has the same sign
83+
&& x._differentSign(r)) // result has different sign
8484
overflow = true;
8585
return r;
8686
}
@@ -190,8 +190,8 @@ pragma(inline, true)
190190
int subs(int x, int y, ref bool overflow)
191191
{
192192
const r = x - y;
193-
if ( x._differentSign(y) // x and y has different sign
194-
& x._differentSign(r)) // result and x has different sign
193+
if ( x._differentSign(y) // x and y has different sign
194+
&& x._differentSign(r)) // result and x has different sign
195195
overflow = true;
196196
return r;
197197
}
@@ -219,8 +219,8 @@ pragma(inline, true)
219219
long subs(long x, long y, ref bool overflow)
220220
{
221221
const r = x - y;
222-
if ( x._differentSign(y) // x and y has different sign
223-
& x._differentSign(r)) // result and x has different sign
222+
if ( x._differentSign(y) // x and y has different sign
223+
&& x._differentSign(r)) // result and x has different sign
224224
overflow = true;
225225
return r;
226226
}
@@ -418,8 +418,8 @@ pragma(inline, true)
418418
long muls(long x, long y, ref bool overflow)
419419
{
420420
const r = x * y;
421-
if ( ~x._differentSign(y) // x and y has the same sign
422-
& r._signBit // and result is negative (covers min * -1)
421+
if ( !x._differentSign(y) // x and y has the same sign
422+
&& r < 0 // and result is negative (covers min * -1)
423423
|| x && r / x != y) // or perform simple check for x != 0
424424
overflow = true;
425425
return r;
@@ -525,15 +525,8 @@ unittest
525525
private:
526526

527527
pragma(inline, true)
528-
@property size_t _signBit(T)(in T n)
528+
bool _differentSign(T)(in T a, in T b)
529529
if(is(T == int) || is(T == long))
530530
{
531-
return cast(size_t) (n >>> T.sizeof * 8 - 1);
532-
}
533-
534-
pragma(inline, true)
535-
size_t _differentSign(T)(in T a, in T b)
536-
if(is(T == int) || is(T == long))
537-
{
538-
return (a ^ b)._signBit;
531+
return (a < 0) != (b < 0);
539532
}

0 commit comments

Comments
 (0)