[llvm] [ISel] Introduce llvm.clmul intrinsic (PR #168731)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 25 02:03:33 PST 2025
================
@@ -8302,6 +8302,54 @@ SDValue TargetLowering::expandFunnelShift(SDNode *Node,
return DAG.getNode(ISD::OR, DL, VT, ShX, ShY);
}
+SDValue TargetLowering::expandCLMUL(SDNode *Node, SelectionDAG &DAG) const {
+ SDLoc DL(Node);
+ EVT VT = Node->getValueType(0);
+ SDValue X = Node->getOperand(0);
+ SDValue Y = Node->getOperand(1);
+ unsigned BW = VT.getScalarSizeInBits();
+ unsigned Opcode = Node->getOpcode();
+
+ switch (Opcode) {
+ case ISD::CLMUL: {
+ SDValue Res = DAG.getConstant(0, DL, VT);
+ for (unsigned I = 0; I < BW; ++I) {
+ SDValue Mask = DAG.getConstant(APInt::getOneBitSet(BW, I), DL, VT);
+ SDValue YMasked = DAG.getNode(ISD::AND, DL, VT, Y, Mask);
+ SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, X, YMasked);
+ Res = DAG.getNode(ISD::XOR, DL, VT, Res, Mul);
+ }
+ return Res;
+ }
+ case ISD::CLMULR:
+ case ISD::CLMULH: {
+ EVT ExtVT =
+ VT.changeElementType(EVT::getIntegerVT(*DAG.getContext(), 2 * BW));
+ // For example, ExtVT = i64 based operations aren't legal on a 32-bit
+ // target; use bitreverse-based lowering in this case.
+ if (!isOperationLegalOrCustom(ISD::ZERO_EXTEND, ExtVT) ||
+ !isOperationLegalOrCustom(ISD::SRL, ExtVT)) {
+ SDValue XRev = DAG.getNode(ISD::BITREVERSE, DL, VT, X);
+ SDValue YRev = DAG.getNode(ISD::BITREVERSE, DL, VT, Y);
+ SDValue ClMul = DAG.getNode(ISD::CLMUL, DL, VT, XRev, YRev);
+ SDValue Res = DAG.getNode(ISD::BITREVERSE, DL, VT, ClMul);
+ if (Opcode == ISD::CLMULR)
----------------
pfusik wrote:
```suggestion
if (Opcode == ISD::CLMULH)
```
https://github.com/llvm/llvm-project/pull/168731
More information about the llvm-commits
mailing list