[llvm] [Xtensa] Implement lowering Mul/Div/Shift operations. (PR #99981)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 12 00:49:40 PDT 2024


================
@@ -125,12 +125,81 @@ FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM,
 
 void XtensaDAGToDAGISel::Select(SDNode *Node) {
   SDLoc DL(Node);
+  EVT VT = Node->getValueType(0);
 
   // If we have a custom node, we already have selected!
   if (Node->isMachineOpcode()) {
     Node->setNodeId(-1);
     return;
   }
 
+  switch (Node->getOpcode()) {
+  case ISD::SHL: {
+    SDValue N0 = Node->getOperand(0);
+    SDValue N1 = Node->getOperand(1);
+    auto *C = dyn_cast<ConstantSDNode>(N1);
+    // If C is constant in range [1..31] then we can generate SLLI
+    // instruction using pattern matching, otherwise generate SLL
+    if (!C || !(isUInt<5>(C->getZExtValue()) && !C->isZero())) {
+      SDNode *SSL = CurDAG->getMachineNode(Xtensa::SSL, DL, MVT::Glue, N1);
+      SDNode *SLL =
+          CurDAG->getMachineNode(Xtensa::SLL, DL, VT, N0, SDValue(SSL, 0));
+      ReplaceNode(Node, SLL);
+      return;
+    }
+    break;
+  }
+  case ISD::SRL: {
+    SDValue N0 = Node->getOperand(0);
+    SDValue N1 = Node->getOperand(1);
+    auto *C = dyn_cast<ConstantSDNode>(N1);
+    // If C is constant in range [0..15] then we can generate SRLI
+    // instruction using pattern matching, otherwise generate SRL
+    if (!C || !isUInt<4>(C->getZExtValue())) {
+      SDNode *SSR = CurDAG->getMachineNode(Xtensa::SSR, DL, MVT::Glue, N1);
+      SDNode *SRL =
+          CurDAG->getMachineNode(Xtensa::SRL, DL, VT, N0, SDValue(SSR, 0));
+      ReplaceNode(Node, SRL);
+      return;
+    }
+    break;
+  }
+  case ISD::SRA: {
+    SDValue N0 = Node->getOperand(0);
+    SDValue N1 = Node->getOperand(1);
+    auto *C = dyn_cast<ConstantSDNode>(N1);
+    // If C is constant in range [0..31] then we can generate SRAI
+    // instruction using pattern matching, otherwise generate SRA
+    if (!C || !isUInt<5>(C->getZExtValue())) {
+      SDNode *SSR = CurDAG->getMachineNode(Xtensa::SSR, DL, MVT::Glue, N1);
+      SDNode *SRA =
+          CurDAG->getMachineNode(Xtensa::SRA, DL, VT, N0, SDValue(SSR, 0));
+      ReplaceNode(Node, SRA);
+      return;
+    }
+    break;
+  }
+  case XtensaISD::SRCL: {
+    SDValue N0 = Node->getOperand(0);
+    SDValue N1 = Node->getOperand(1);
+    SDValue N2 = Node->getOperand(2);
+    SDNode *SSL = CurDAG->getMachineNode(Xtensa::SSL, DL, MVT::Glue, N2);
+    SDNode *SRC =
+        CurDAG->getMachineNode(Xtensa::SRC, DL, VT, N0, N1, SDValue(SSL, 0));
+    ReplaceNode(Node, SRC);
+    return;
+  }
+  case XtensaISD::SRCR: {
+    SDValue N0 = Node->getOperand(0);
+    SDValue N1 = Node->getOperand(1);
+    SDValue N2 = Node->getOperand(2);
+    SDNode *SSR = CurDAG->getMachineNode(Xtensa::SSR, DL, MVT::Glue, N2);
+    SDNode *SRC =
+        CurDAG->getMachineNode(Xtensa::SRC, DL, VT, N0, N1, SDValue(SSR, 0));
----------------
arsenm wrote:

Seems surprising to me to handle this as a function of selection, and not legalization but it's fine

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


More information about the llvm-commits mailing list