[llvm] [IR] Add llvm `clmul` intrinsic (PR #140301)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed May 21 15:13:20 PDT 2025
================
@@ -5417,6 +5422,35 @@ void DAGTypeLegalizer::ExpandIntRes_FunnelShift(SDNode *N, SDValue &Lo,
Hi = DAG.getNode(Opc, DL, HalfVT, Select3, Select2, NewShAmt);
}
+void DAGTypeLegalizer::ExpandIntRes_CLMUL(SDNode *N, SDValue &Lo,
+ SDValue &Hi) {
+ // Values numbered from least significant to most significant.
+ SDValue In1, In2, In3, In4;
+ GetExpandedInteger(N->getOperand(0), In3, In4);
+ GetExpandedInteger(N->getOperand(1), In1, In2);
+ EVT HalfVT = In1.getValueType();
+ SDLoc DL(N);
+
+ // CLMUL is carryless so Lo is computed from the low half
+ Lo = DAG.getNode(ISD::CLMUL, DL, HalfVT, In1, In3);
+ // the high bits not included in CLMUL(A,B) can be computed by
+ // BITREVERSE(CLMUL(BITREVERSE(A), BITREVERSE(B))) >> 1
+ // Therefore we can compute the 2 hi/lo cross products
+ // and the the overflow of the low product
+ // and xor them together to compute HI
+ SDValue BitRevIn1 = DAG.getNode(ISD::BITREVERSE, DL, HalfVT, In1);
+ SDValue BitRevIn3 = DAG.getNode(ISD::BITREVERSE, DL, HalfVT, In3);
+ SDValue BitRevLoHi = DAG.getNode(ISD::CLMUL, DL, HalfVT, BitRevIn1, BitRevIn3);
+ SDValue LoHi = DAG.getNode(ISD::BITREVERSE, DL, HalfVT, BitRevLoHi);
+ SDValue One = DAG.getConstant(0, DL, HalfVT);
----------------
topperc wrote:
X86 for example always uses 8-bit shift amounts because the legacy shift by register instructions all use the CL register regardless of the data size.
https://github.com/llvm/llvm-project/pull/140301
More information about the llvm-commits
mailing list