[llvm] [KnownBits] Make `clmul` optimal (PR #177916)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 26 02:54:19 PST 2026


================
@@ -603,38 +604,26 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS,
 }
 
 KnownBits KnownBits::clmul(const KnownBits &LHS, const KnownBits &RHS) {
-  unsigned BitWidth = LHS.getBitWidth();
-
-  // An m*n result will always fit in m+n-1 bits since there are no carries.
-  // If either input is to be zero, the result is zero.
-  unsigned ActiveBitsLHS = LHS.countMaxActiveBits();
-  unsigned ActiveBitsRHS = RHS.countMaxActiveBits();
-  unsigned ActiveBits;
-  if (ActiveBitsLHS == 0 || ActiveBitsRHS == 0)
-    ActiveBits = 0;
-  else
-    ActiveBits = std::min(BitWidth, ActiveBitsLHS + ActiveBitsRHS - 1);
-
-  // The result of the bottom bits of a clmul can be inferred by looking at the
-  // bottom bits of both operands and carryless multiplying them together. The
-  // number of bits we can determine follows the same logic as KnownBits::mul.
-  unsigned TrailBitsKnownLHS = (LHS.Zero | LHS.One).countr_one();
-  unsigned TrailBitsKnownRHS = (RHS.Zero | RHS.One).countr_one();
-  unsigned TrailZeroLHS = LHS.countMinTrailingZeros();
-  unsigned TrailZeroRHS = RHS.countMinTrailingZeros();
-  unsigned TrailZ = TrailZeroLHS + TrailZeroRHS;
-
-  // Figure out the fewest known-bits operand.
-  unsigned SmallestOperand = std::min(TrailBitsKnownLHS - TrailZeroLHS,
-                                      TrailBitsKnownRHS - TrailZeroRHS);
-  unsigned ResultBitsKnown = std::min(SmallestOperand + TrailZ, BitWidth);
-
-  APInt BottomKnown = APIntOps::clmul(LHS.One, RHS.One);
+  KnownBits Res = makeConstant(APIntOps::clmul(LHS.getMinValue(),
+                                               RHS.getMinValue()));
+
+  // This is the same operation as clmul except it accumulates the result with
+  // an OR instead of an XOR.
+  auto ClMulOr = [](const APInt &LHS, const APInt &RHS){
----------------
RKSimon wrote:

```suggestion
  auto ClMulOr = [](const APInt &LHS, const APInt &RHS) {
```

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


More information about the llvm-commits mailing list