[llvm] [IR] Add llvm.vector.shuffle intrinsic for vector shuffles with runtime masks Part 1. (PR #219259)

Oscar Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 22:35:52 PDT 2026


================
@@ -2911,6 +2921,88 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_COMPRESS(SDNode *N, SDValue &Lo,
   std::tie(Lo, Hi) = DAG.SplitVector(Compressed, DL);
 }
 
+void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE_VAR(SDNode *N, SDValue &Lo,
+                                                      SDValue &Hi) {
+  SDLoc DL(N);
+  SDValue Src = N->getOperand(0), Mask = N->getOperand(1);
+  EVT MaskVT = Mask.getValueType();
+  unsigned MaskEltBits = MaskVT.getScalarSizeInBits();
+
+  SDValue SrcLo, SrcHi;
+  if (getTypeAction(Src.getValueType()) == TargetLowering::TypeSplitVector)
+    GetSplitVector(Src, SrcLo, SrcHi);
+  else
+    std::tie(SrcLo, SrcHi) = DAG.SplitVector(Src, DL);
+
+  SDValue MaskLo, MaskHi;
+  if (getTypeAction(MaskVT) == TargetLowering::TypeSplitVector)
+    GetSplitVector(Mask, MaskLo, MaskHi);
+  else
+    std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
+
+  EVT HalfVT = SrcLo.getValueType();
+  EVT HalfMaskVT = MaskLo.getValueType();
+  ElementCount HalfEC = HalfVT.getVectorElementCount();
+  APInt MaxIdx = APInt::getMaxValue(MaskEltBits);
+
+  // Every index the mask element type can hold lands in the low half of the
+  // source, so the high half is unreachable and each result half is just a
+  // shuffle of the low source half.
+  if (MaxIdx.ult(HalfEC.getKnownMinValue())) {
----------------
oscardssmith wrote:

This is a correctness requirement. e.g. a <8 x i32> with an <8 x i2> mask (or much longer with a more typical i8 mask). Alternatively we could zext the mask in this case. Would you prefer that?

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


More information about the llvm-commits mailing list