fix UB
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 27 Apr 2022 01:25:34 +0000 (18:25 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 27 Apr 2022 01:25:34 +0000 (18:25 -0700)
openpower/sv/biginteger/analysis.mdwn
openpower/sv/biginteger/divgnu64.c
openpower/sv/biginteger/divmnu64.c

index 28f535db4524689ac060d77d592454577c7fa54b..703f512350dcb68b88ecc77efaf2d7722129a1bc 100644 (file)
@@ -112,7 +112,7 @@ that when Vectorised are exactly what is needed.
 void biglsh(unsigned s, unsigned vn[], unsigned const v[], int n)
 {
     for (int i = n - 1; i > 0; i--)
-        vn[i] = (v[i] << s) | ((unsigned long long)v[i - 1] >> (32 - s));
+        vn[i] = ((unsigned long long)v[i] << s) | (v[i - 1] >> (32 - s));
     vn[0] = v[0] << s;
 }
 ```
@@ -356,7 +356,7 @@ the digits are 32 bit and, special-casing the overflow, a 64/32 divide is suffic
         uint64_t dig2 = ((uint64_t)un[j + n] << 32) | un[j + n - 1];
         if (un[j+n] >= vn[n-1]) {
             // rhat can be bigger than 32-bit when the division overflows,
-            rhat = dig2 - UINT32_MAX * vn[n - 1];
+            rhat = dig2 - (uint64_t)UINT32_MAX * vn[n - 1];
         } else {
             qhat = dig2 / vn[n - 1]; // 64/32 divide
             rhat = dig2 % vn[n - 1]; // 64/32 modulo
index f2422933d661bb41740e1b72834f6f7a83ced28d..649143963fd489e203ddf144c2878d71b556eb89 100644 (file)
@@ -70,9 +70,9 @@ void biglsh(unsigned s, unsigned vn[], unsigned const v[], int n)
     vn[0] = v[0] << s;
 }
 
-long bigdiv(unsigned v, unsigned q[], unsigned const u[], int m)
+unsigned long bigdiv(unsigned v, unsigned q[], unsigned const u[], int m)
 {
-    long long k = 0; // the case of a
+    unsigned long long k = 0; // the case of a
     for (int j = m - 1; j >= 0; j--)
     { // single-digit
         unsigned long d2 = (k << 32) | u[j];
@@ -168,7 +168,6 @@ int divmnu(unsigned q[], unsigned r[], const unsigned u[], const unsigned v[],
     unsigned *un, *vn;                      // Normalized form of u, v.
     unsigned long long qhat;                // Estimated quotient digit.
     unsigned long long rhat;                // A remainder.
-    long long k;
     int s, j;
 
     if (m < n || n <= 0 || v[n - 1] == 0)
@@ -176,7 +175,7 @@ int divmnu(unsigned q[], unsigned r[], const unsigned u[], const unsigned v[],
 
     if (n == 1)
     { // Take care of
-        k = bigdiv(v[0], q, u, m);
+        unsigned long k = bigdiv(v[0], q, u, m);
         if (r != NULL)
             r[0] = k;
         return 0;
index 330e06d1ab3baa59f2609799325f80cec8a6c130..10b05d5aba2a857fac55f5873734a9f7fae257d3 100644 (file)
@@ -207,7 +207,7 @@ int divmnu(unsigned q[], unsigned r[], const unsigned u[], const unsigned v[],
         {
             // rhat can be bigger than 32-bit when the division overflows,
             // so rhat's computation can't be folded into divrem_64_by_32
-            rhat = dig2 - qr.q * vn[n - 1];
+            rhat = dig2 - (uint64_t)qr.q * vn[n - 1];
         }
     again:
         // use 3rd-from-top digit to obtain better accuracy