[libc-commits] [PATCH] D131095: [libc] Prevent overflow from intermediate results when adding UInt<N> values.

Kirill Okhotnikov via Phabricator via libc-commits libc-commits at lists.llvm.org
Thu Aug 4 01:14:06 PDT 2022


orex added inline comments.


================
Comment at: libc/src/__support/CPP/UInt.h:74
   constexpr uint64_t add(const UInt<Bits> &x) {
-    uint64_t carry = 0;
+    bool carry = false;
     for (size_t i = 0; i < WordCount; ++i) {
----------------
Hi, Tue!

I was thinking about the implementation. I little bit worries about the performance. To many `if` here. I would like to propose you another solution. Of course it is up to you to accept it or not. The strongest point of the solution is slightly reduced number of arithmetic operations and only one "main" if. The second one triggered very rare.

```
    uint64_t carry = 0;
    for (size_t i = 0; i < WordCount; ++i) {
      // Will be wrapped if sum more than 2^(sizeof(x)) - 1
      val[i] += x.val[i];
      // If an overflow appears, the result is less than both of the initial
      // variables
      if (val[i] < x.val[i]) {
        // Add previous carry. Overflow is not possible.
        val[i] += carry;
        // Put 1 to the next digits.
        carry = 1;
      } else {
        val[i] += carry;
        // Likely no overflow.
        if (likely(val[i]) != 0)
          carry = 0;
        // else carry keeps value in case of carry = 0 it is simply 0 with
        // no overflow in case of 1 this made overflow and propagates next.
      }
    }
    return carry;
  }
```



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131095/new/

https://reviews.llvm.org/D131095



More information about the libc-commits mailing list