[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