================
@@ -2236,51 +2257,68 @@ void 
AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
   if (!ImmToReg<AArch64::ZT0, 0>(Node->getOperand(2), ZtValue))
     return;
 
-  SDValue Chain = Node->getOperand(0);
-  SDValue Ops[] = {ZtValue, Node->getOperand(3), Node->getOperand(4), Chain};
-  SDLoc DL(Node);
-  EVT VT = Node->getValueType(0);
-
-  SDNode *Instruction =
-      CurDAG->getMachineNode(Opc, DL, {MVT::Untyped, MVT::Other}, Ops);
-  SDValue SuperReg = SDValue(Instruction, 0);
+  SDValue Ops[] = {ZtValue, Node->getOperand(3), Node->getOperand(4)};
+  EmitMultiVectorLutiLane(Node, NumOutVecs, Opc, Ops, /*HasChain=*/true);
+}
 
-  for (unsigned I = 0; I < NumOutVecs; ++I)
-    ReplaceUses(SDValue(Node, I), CurDAG->getTargetExtractSubreg(
-                                      AArch64::zsub0 + I, DL, VT, SuperReg));
+void AArch64DAGToDAGISel::SelectMultiVectorLutiLaneTuple(SDNode *Node,
+                                                         unsigned NumOutVecs,
+                                                         unsigned Opc,
+                                                         uint32_t MaxImm) {
+  SDValue ImmVal = Node->getOperand(5);
+  if (auto *Imm = dyn_cast<ConstantSDNode>(ImmVal))
+    if (Imm->getZExtValue() > MaxImm)
+      return;
 
-  // Copy chain
-  unsigned ChainIdx = NumOutVecs;
-  ReplaceUses(SDValue(Node, ChainIdx), SDValue(Instruction, 1));
-  CurDAG->RemoveDeadNode(Node);
+  SmallVector<SDValue, 4> Ops = {
+      createZTuple({Node->getOperand(1), Node->getOperand(2)}),
+      createZTuple({Node->getOperand(3), Node->getOperand(4)}),
+      Node->getOperand(5),
+  };
+  EmitMultiVectorLutiLane(Node, NumOutVecs, Opc, Ops, /*HasChain=*/false);
 }
 
 void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
                                                 unsigned NumOutVecs,
-                                                unsigned Opc) {
+                                                unsigned Opc,
+                                                unsigned NumInVecs) {
+  const unsigned ChainOp = 0;
+  const unsigned ZtOp = 2;
+  const unsigned FirstVecOp = 3;
+
   SDValue ZtValue;
-  if (!ImmToReg<AArch64::ZT0, 0>(Node->getOperand(2), ZtValue))
+  if (!ImmToReg<AArch64::ZT0, 0>(Node->getOperand(ZtOp), ZtValue))
     return;
 
-  SDValue Chain = Node->getOperand(0);
-  SDValue Ops[] = {ZtValue,
-                   createZMulTuple({Node->getOperand(3), Node->getOperand(4)}),
-                   Chain};
+  SDValue ZTuple;
+  switch (NumInVecs) {
+  case 2:
+    ZTuple = createZMulTuple(
+        {Node->getOperand(FirstVecOp), Node->getOperand(FirstVecOp + 1)});
+    break;
+  case 3:
+    ZTuple = createZTuple({Node->getOperand(FirstVecOp),
+                           Node->getOperand(FirstVecOp + 1),
+                           Node->getOperand(FirstVecOp + 2)});
+    break;
+  default:
+    llvm_unreachable("unexpected LUTI ZT tuple width");
+  }
+
+  SDValue Ops[] = {ZtValue, ZTuple, Node->getOperand(ChainOp)};
----------------
kmclaughlin-arm wrote:

Maybe this can be done in a similar way to `SelectClamp`? i.e.

```suggestion
  SmallVector<SDValue, 4> Regs(Node->ops().slice(3, NumInVecs));
  SDValue ZTuple = NumInVecs == 2 ? createZMulTuple(Regs)
                                  : createZTuple(Regs);
  SDValue Ops[] = {ZtValue, ZTuple, Node->getOperand(0)};
```

https://github.com/llvm/llvm-project/pull/187046
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to