[llvm] [SelectionDAG] Expand CTTZ_ELTS[_ZERO_POISON] and handle splitting (PR #185605)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 24 01:06:00 PDT 2026


================
@@ -4828,6 +4832,26 @@ SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) {
   return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
 }
 
+SDValue DAGTypeLegalizer::SplitVecOp_CttzElts(SDNode *N) {
+  SDLoc DL(N);
+  EVT ResVT = N->getValueType(0);
+
+  SDValue Lo, Hi;
+  SDValue VecOp = N->getOperand(0);
+  GetSplitVector(VecOp, Lo, Hi);
+
+  // if CTTZ_ELTS(Lo) != VL => CTTZ_ELTS(Lo).
+  // else => VL + (CTTZ_ELTS(Hi) or CTTZ_ELTS_ZERO_UNDEF(Hi)).
+  SDValue ResLo = DAG.getNode(ISD::CTTZ_ELTS, DL, ResVT, Lo);
----------------
lukel97 wrote:

I see what you mean, but with VECREDUCE_OR we might also run into the same problem where the target needs to expand the reduction. And we would still need a separate CTTZ_ELTS_ZERO_POISON to use for the case where the first active lane is in the first half.

Both of these scenarios shouldn't happen in-tree today though. The only targets that support legal or custom lowering for cttz_elts/cttz_elts_zero_poison are AArch64 and RISC-V, and both targets support both nodes. So I'm not sure if we'll be able to write a test for this scenario currently.

If a target does come along that only lowers one type of cttz_elts I guess it can account for it in its cost model. 

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


More information about the llvm-commits mailing list