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

Commit ca75fb2

Browse files
committed
Merge pull request #24 from pnkfelix/well-define-negate-of-int-min
Remove UB from int-to-float conversion for INT_MIN.
2 parents e6bb43d + c3c411a commit ca75fb2

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
@@ -22,27 +22,26 @@ COMPILER_RT_ABI fp_t
2222
__floatsidf(int a) {
2323

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

3030
// All other cases begin by extracting the sign and absolute value of a
3131
rep_t sign = 0;
32+
unsigned aAbs = (unsigned)a;
3233
if (a < 0) {
3334
sign = signBit;
34-
a = -a;
35+
aAbs = ~(unsigned)a + 1U;
3536
}
3637

3738
// Exponent of (fp_t)a is the width of abs(a).
38-
const int exponent = (aWidth - 1) - __builtin_clz(a);
39+
const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
3940
rep_t result;
4041

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

4746
// Insert the exponent
4847
result += (rep_t)(exponent + exponentBias) << significandBits;

lib/builtins/floatsisf.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,31 @@ COMPILER_RT_ABI fp_t
2222
__floatsisf(int a) {
2323

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

3030
// All other cases begin by extracting the sign and absolute value of a
3131
rep_t sign = 0;
32+
unsigned aAbs = (unsigned)a;
3233
if (a < 0) {
3334
sign = signBit;
34-
a = -a;
35+
aAbs = ~(unsigned)a + 1U;
3536
}
3637

3738
// Exponent of (fp_t)a is the width of abs(a).
38-
const int exponent = (aWidth - 1) - __builtin_clz(a);
39+
const int exponent = (aWidth - 1) - __builtin_clz(aAbs);
3940
rep_t result;
4041

4142
// Shift a into the significand field, rounding if it is a right-shift
4243
if (exponent <= significandBits) {
4344
const int shift = significandBits - exponent;
44-
result = (rep_t)a << shift ^ implicitBit;
45+
result = (rep_t)aAbs << shift ^ implicitBit;
4546
} else {
4647
const int shift = exponent - significandBits;
47-
result = (rep_t)a >> shift ^ implicitBit;
48-
rep_t round = (rep_t)a << (typeWidth - shift);
48+
result = (rep_t)aAbs >> shift ^ implicitBit;
49+
rep_t round = (rep_t)aAbs << (typeWidth - shift);
4950
if (round > signBit) result++;
5051
if (round == signBit) result += result & 1;
5152
}

0 commit comments

Comments
 (0)