Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Commit de7dcbe

Browse files
alexcrichtonTimNN
authored andcommitted
Merge pull request #24 from pnkfelix/well-define-negate-of-int-min
Remove UB from int-to-float conversion for INT_MIN.
2 parents 1fdc27d + 5864420 commit de7dcbe

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

lib/builtins/floatsidf.c

+6-7
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,26 @@ COMPILER_RT_ABI fp_t
2424
__floatsidf(int a) {
2525

2626
const int aWidth = sizeof a * CHAR_BIT;
27-
27+
2828
// Handle zero as a special case to protect clz
2929
if (a == 0)
3030
return fromRep(0);
3131

3232
// All other cases begin by extracting the sign and absolute value of a
3333
rep_t sign = 0;
34+
unsigned aAbs = (unsigned)a;
3435
if (a < 0) {
3536
sign = signBit;
36-
a = -a;
37+
aAbs = ~(unsigned)a + 1U;
3738
}
3839

3940
// Exponent of (fp_t)a is the width of abs(a).
40-
const int exponent = (aWidth - 1) - __builtin_clz(a);
41+
const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
4142
rep_t result;
4243

43-
// Shift a into the significand field and clear the implicit bit. Extra
44-
// cast to unsigned int is necessary to get the correct behavior for
45-
// the input INT_MIN.
44+
// Shift a into the significand field and clear the implicit bit.
4645
const int shift = significandBits - exponent;
47-
result = (rep_t)(unsigned int)a << shift ^ implicitBit;
46+
result = (rep_t)aAbs << shift ^ implicitBit;
4847

4948
// Insert the exponent
5049
result += (rep_t)(exponent + exponentBias) << significandBits;

lib/builtins/floatsisf.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,31 @@ COMPILER_RT_ABI fp_t
2424
__floatsisf(int a) {
2525

2626
const int aWidth = sizeof a * CHAR_BIT;
27-
27+
2828
// Handle zero as a special case to protect clz
2929
if (a == 0)
3030
return fromRep(0);
3131

3232
// All other cases begin by extracting the sign and absolute value of a
3333
rep_t sign = 0;
34+
unsigned aAbs = (unsigned)a;
3435
if (a < 0) {
3536
sign = signBit;
36-
a = -a;
37+
aAbs = ~(unsigned)a + 1U;
3738
}
3839

3940
// Exponent of (fp_t)a is the width of abs(a).
40-
const int exponent = (aWidth - 1) - __builtin_clz(a);
41+
const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
4142
rep_t result;
4243

4344
// Shift a into the significand field, rounding if it is a right-shift
4445
if (exponent <= significandBits) {
4546
const int shift = significandBits - exponent;
46-
result = (rep_t)a << shift ^ implicitBit;
47+
result = (rep_t)aAbs << shift ^ implicitBit;
4748
} else {
4849
const int shift = exponent - significandBits;
49-
result = (rep_t)a >> shift ^ implicitBit;
50-
rep_t round = (rep_t)a << (typeWidth - shift);
50+
result = (rep_t)aAbs >> shift ^ implicitBit;
51+
rep_t round = (rep_t)aAbs << (typeWidth - shift);
5152
if (round > signBit) result++;
5253
if (round == signBit) result += result & 1;
5354
}

0 commit comments

Comments
 (0)