[compiler-rt] ff14585 - [builtins] Avoid undefined behavior when calculating absolute value in floatsidf.c and floatsisf.c
Karl-Johan Karlsson via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 22 23:58:49 PDT 2023
Author: Karl-Johan Karlsson
Date: 2023-08-23T08:57:18+02:00
New Revision: ff14585eb02f96b78a2544f8bcddd2685202cc56
URL: https://github.com/llvm/llvm-project/commit/ff14585eb02f96b78a2544f8bcddd2685202cc56
DIFF: https://github.com/llvm/llvm-project/commit/ff14585eb02f96b78a2544f8bcddd2685202cc56.diff
LOG: [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
Added:
Modified:
compiler-rt/lib/builtins/floatsidf.c
compiler-rt/lib/builtins/floatsisf.c
compiler-rt/lib/builtins/floatsitf.c
Removed:
################################################################################
diff --git a/compiler-rt/lib/builtins/floatsidf.c b/compiler-rt/lib/builtins/floatsidf.c
index 28cf32f6388b50..a23b31e7bc7ef0 100644
--- a/compiler-rt/lib/builtins/floatsidf.c
+++ b/compiler-rt/lib/builtins/floatsidf.c
@@ -27,20 +27,21 @@ COMPILER_RT_ABI fp_t __floatsidf(si_int a) {
// All other cases begin by extracting the sign and absolute value of a
rep_t sign = 0;
+ su_int aAbs = (su_int)a;
if (a < 0) {
sign = signBit;
- a = -a;
+ aAbs = -aAbs;
}
// Exponent of (fp_t)a is the width of abs(a).
- const int exponent = (aWidth - 1) - clzsi(a);
+ const int exponent = (aWidth - 1) - clzsi(aAbs);
rep_t result;
// Shift a into the significand field and clear the implicit bit. Extra
// cast to unsigned int is necessary to get the correct behavior for
// the input INT_MIN.
const int shift = significandBits - exponent;
- result = (rep_t)(su_int)a << shift ^ implicitBit;
+ result = (rep_t)aAbs << shift ^ implicitBit;
// Insert the exponent
result += (rep_t)(exponent + exponentBias) << significandBits;
diff --git a/compiler-rt/lib/builtins/floatsisf.c b/compiler-rt/lib/builtins/floatsisf.c
index c01f81e41e8eaa..5ede30b703e086 100644
--- a/compiler-rt/lib/builtins/floatsisf.c
+++ b/compiler-rt/lib/builtins/floatsisf.c
@@ -27,23 +27,24 @@ COMPILER_RT_ABI fp_t __floatsisf(si_int a) {
// All other cases begin by extracting the sign and absolute value of a
rep_t sign = 0;
+ su_int aAbs = (su_int)a;
if (a < 0) {
sign = signBit;
- a = -a;
+ aAbs = -aAbs;
}
// Exponent of (fp_t)a is the width of abs(a).
- const int exponent = (aWidth - 1) - clzsi(a);
+ const int exponent = (aWidth - 1) - clzsi(aAbs);
rep_t result;
// Shift a into the significand field, rounding if it is a right-shift
if (exponent <= significandBits) {
const int shift = significandBits - exponent;
- result = (rep_t)a << shift ^ implicitBit;
+ result = (rep_t)aAbs << shift ^ implicitBit;
} else {
const int shift = exponent - significandBits;
- result = (rep_t)a >> shift ^ implicitBit;
- rep_t round = (rep_t)a << (typeWidth - shift);
+ result = (rep_t)aAbs >> shift ^ implicitBit;
+ rep_t round = (rep_t)aAbs << (typeWidth - shift);
if (round > signBit)
result++;
if (round == signBit)
diff --git a/compiler-rt/lib/builtins/floatsitf.c b/compiler-rt/lib/builtins/floatsitf.c
index 4d5b52f4ed9199..314a8a7bbdfe39 100644
--- a/compiler-rt/lib/builtins/floatsitf.c
+++ b/compiler-rt/lib/builtins/floatsitf.c
@@ -29,7 +29,7 @@ COMPILER_RT_ABI fp_t __floatsitf(si_int a) {
su_int aAbs = (su_int)a;
if (a < 0) {
sign = signBit;
- aAbs = ~(su_int)a + (su_int)1U;
+ aAbs = -aAbs;
}
// Exponent of (fp_t)a is the width of abs(a).
More information about the llvm-commits
mailing list