[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