Skip to content

Commit ff14585

Browse files
committed
[builtins] Avoid undefined behavior when calculating absolute value in floatsidf.c and floatsisf.c
When compiling compiler-rt with -fsanitize=undefined and running testcases you end up with the following warning: UBSan: floatsidf.c:32:9: negation of -2147483648 cannot be represented in type 'si_int' (aka 'long'); cast to an unsigned type to negate this value to itself The same kind of pattern exists in floatsisf.c This was found in an out of tree target. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D146123
1 parent 34e3bc0 commit ff14585

File tree

3 files changed

+11
-9
lines changed

3 files changed

+11
-9
lines changed

compiler-rt/lib/builtins/floatsidf.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,21 @@ COMPILER_RT_ABI fp_t __floatsidf(si_int a) {
2727

2828
// All other cases begin by extracting the sign and absolute value of a
2929
rep_t sign = 0;
30+
su_int aAbs = (su_int)a;
3031
if (a < 0) {
3132
sign = signBit;
32-
a = -a;
33+
aAbs = -aAbs;
3334
}
3435

3536
// Exponent of (fp_t)a is the width of abs(a).
36-
const int exponent = (aWidth - 1) - clzsi(a);
37+
const int exponent = (aWidth - 1) - clzsi(aAbs);
3738
rep_t result;
3839

3940
// Shift a into the significand field and clear the implicit bit. Extra
4041
// cast to unsigned int is necessary to get the correct behavior for
4142
// the input INT_MIN.
4243
const int shift = significandBits - exponent;
43-
result = (rep_t)(su_int)a << shift ^ implicitBit;
44+
result = (rep_t)aAbs << shift ^ implicitBit;
4445

4546
// Insert the exponent
4647
result += (rep_t)(exponent + exponentBias) << significandBits;

compiler-rt/lib/builtins/floatsisf.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,24 @@ COMPILER_RT_ABI fp_t __floatsisf(si_int a) {
2727

2828
// All other cases begin by extracting the sign and absolute value of a
2929
rep_t sign = 0;
30+
su_int aAbs = (su_int)a;
3031
if (a < 0) {
3132
sign = signBit;
32-
a = -a;
33+
aAbs = -aAbs;
3334
}
3435

3536
// Exponent of (fp_t)a is the width of abs(a).
36-
const int exponent = (aWidth - 1) - clzsi(a);
37+
const int exponent = (aWidth - 1) - clzsi(aAbs);
3738
rep_t result;
3839

3940
// Shift a into the significand field, rounding if it is a right-shift
4041
if (exponent <= significandBits) {
4142
const int shift = significandBits - exponent;
42-
result = (rep_t)a << shift ^ implicitBit;
43+
result = (rep_t)aAbs << shift ^ implicitBit;
4344
} else {
4445
const int shift = exponent - significandBits;
45-
result = (rep_t)a >> shift ^ implicitBit;
46-
rep_t round = (rep_t)a << (typeWidth - shift);
46+
result = (rep_t)aAbs >> shift ^ implicitBit;
47+
rep_t round = (rep_t)aAbs << (typeWidth - shift);
4748
if (round > signBit)
4849
result++;
4950
if (round == signBit)

compiler-rt/lib/builtins/floatsitf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ COMPILER_RT_ABI fp_t __floatsitf(si_int a) {
2929
su_int aAbs = (su_int)a;
3030
if (a < 0) {
3131
sign = signBit;
32-
aAbs = ~(su_int)a + (su_int)1U;
32+
aAbs = -aAbs;
3333
}
3434

3535
// Exponent of (fp_t)a is the width of abs(a).

0 commit comments

Comments
 (0)