[llvm] [APInt] Introduce carry-less multiply operation (PR #168527)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 18 05:30:37 PST 2025


================
@@ -3187,3 +3187,11 @@ APInt llvm::APIntOps::fshr(const APInt &Hi, const APInt &Lo,
     return Lo;
   return Hi.shl(Hi.getBitWidth() - ShiftAmt) | Lo.lshr(ShiftAmt);
 }
+
+APInt llvm::APIntOps::clmul(const APInt &LHS, const APInt &RHS) {
+  assert(LHS.getBitWidth() == RHS.getBitWidth());
+  APInt Result(LHS.getBitWidth(), 0);
+  for (unsigned I : seq<unsigned>(Result.getBitWidth()))
+    Result ^= LHS.shl(I) * (RHS.lshr(I) & 1);
----------------
dtcxzyw wrote:

```suggestion
    if (RHS[I])
      Result ^= LHS.shl(I);
```
Shifting is expensive for APInts with a large bitwidth. BTW, can we use the word-level clmul to calculate the result? For example, if `clmul(a, b)` produces hi and lo, `clmul(a << (64 * k1), b << (64 * k2))` will give a contribution with `((hi << 64) | lo) << (64 * (k1 + k2))`

https://github.com/llvm/llvm-project/pull/168527


More information about the llvm-commits mailing list