[llvm] [DAG] TargetLowering::expandCLMUL - avoid ISD::MUL if target hasBitTest (PR #177566)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 9 03:56:39 PST 2026


================
@@ -8432,12 +8432,34 @@ SDValue TargetLowering::expandCLMUL(SDNode *Node, SelectionDAG &DAG) const {
     // calculation in BasicTTIImpl::getTypeBasedIntrinsicInstrCost for
     // Intrinsic::clmul.
     SDValue Res = DAG.getConstant(0, DL, VT);
+    SDValue Zero = DAG.getConstant(0, DL, VT);
+
+    EVT SetCCVT =
+        getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+
+    // For targets with a fast bit test instruction (e.g., x86 BT), use a
+    // shift-based expansion to avoid expensive MUL instructions.
+    // Pattern: Res ^= (Y & (1<<I)) ? (X<<I) : 0
     for (unsigned I = 0; I < BW; ++I) {
+      SDValue ShiftAmt = DAG.getShiftAmountConstant(I, VT, DL);
       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);
+
+      if (hasBitTest(Y, Mask)) {
+        // Canonical bit test: (Y & (1 << I)) != 0
+        SDValue BitTest = DAG.getNode(ISD::AND, DL, VT, Y, Mask);
+        SDValue Cond = DAG.getSetCC(DL, SetCCVT, BitTest, Zero, ISD::SETNE);
+
+        SDValue Shifted = DAG.getNode(ISD::SHL, DL, VT, X, ShiftAmt);
----------------
jayfoad wrote:

You might get neater codegen if you take the Shifted value from the previous iteration and SHL by 1 here. Hmm, but that would only work if we know we're taking the hasBitTest path for every iteration...

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


More information about the llvm-commits mailing list