@@ -516,6 +516,44 @@ void RISCVDAGToDAGISel::selectVSETVLI(SDNode *Node) {
516516 CurDAG->getMachineNode (Opcode, DL, XLenVT, VLOperand, VTypeIOp));
517517}
518518
519+ void RISCVDAGToDAGISel::selectXSfmmVSET (SDNode *Node) {
520+ if (!Subtarget->hasVendorXSfmmbase ())
521+ return ;
522+
523+ assert (Node->getOpcode () == ISD::INTRINSIC_WO_CHAIN && " Unexpected opcode" );
524+
525+ SDLoc DL (Node);
526+ MVT XLenVT = Subtarget->getXLenVT ();
527+
528+ unsigned IntNo = Node->getConstantOperandVal (0 );
529+
530+ assert ((IntNo == Intrinsic::riscv_sf_vsettnt ||
531+ IntNo == Intrinsic::riscv_sf_vsettm ||
532+ IntNo == Intrinsic::riscv_sf_vsettk) &&
533+ " Unexpected XSfmm vset intrinsic" );
534+
535+ unsigned SEW = RISCVVType::decodeVSEW (Node->getConstantOperandVal (2 ));
536+ unsigned Widen = RISCVVType::decodeTWiden (Node->getConstantOperandVal (3 ));
537+ unsigned PseudoOpCode =
538+ IntNo == Intrinsic::riscv_sf_vsettnt ? RISCV::PseudoSF_VSETTNT
539+ : IntNo == Intrinsic::riscv_sf_vsettm ? RISCV::PseudoSF_VSETTM
540+ : RISCV::PseudoSF_VSETTK;
541+
542+ if (IntNo == Intrinsic::riscv_sf_vsettnt) {
543+ unsigned VTypeI = RISCVVType::encodeXSfmmVType (SEW, Widen, 0 );
544+ SDValue VTypeIOp = CurDAG->getTargetConstant (VTypeI, DL, XLenVT);
545+
546+ ReplaceNode (Node, CurDAG->getMachineNode (PseudoOpCode, DL, XLenVT,
547+ Node->getOperand (1 ), VTypeIOp));
548+ } else {
549+ SDValue Log2SEW = CurDAG->getTargetConstant (Log2_32 (SEW), DL, XLenVT);
550+ SDValue TWiden = CurDAG->getTargetConstant (Widen, DL, XLenVT);
551+ ReplaceNode (Node,
552+ CurDAG->getMachineNode (PseudoOpCode, DL, XLenVT,
553+ Node->getOperand (1 ), Log2SEW, TWiden));
554+ }
555+ }
556+
519557bool RISCVDAGToDAGISel::tryShrinkShlLogicImm (SDNode *Node) {
520558 MVT VT = Node->getSimpleValueType (0 );
521559 unsigned Opcode = Node->getOpcode ();
@@ -847,6 +885,11 @@ bool RISCVDAGToDAGISel::tryIndexedLoad(SDNode *Node) {
847885 return true ;
848886}
849887
888+ static Register getTileReg (uint64_t TileNum) {
889+ assert (TileNum <= 15 && " Invalid tile number" );
890+ return RISCV::T0 + TileNum;
891+ }
892+
850893void RISCVDAGToDAGISel::selectSF_VC_X_SE (SDNode *Node) {
851894 if (!Subtarget->hasVInstructions ())
852895 return ;
@@ -2035,6 +2078,10 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
20352078 case Intrinsic::riscv_vsetvli:
20362079 case Intrinsic::riscv_vsetvlimax:
20372080 return selectVSETVLI (Node);
2081+ case Intrinsic::riscv_sf_vsettnt:
2082+ case Intrinsic::riscv_sf_vsettm:
2083+ case Intrinsic::riscv_sf_vsettk:
2084+ return selectXSfmmVSET (Node);
20382085 }
20392086 break ;
20402087 }
@@ -2458,6 +2505,142 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
24582505 case Intrinsic::riscv_sf_vc_i_se:
24592506 selectSF_VC_X_SE (Node);
24602507 return ;
2508+ case Intrinsic::riscv_sf_vlte8:
2509+ case Intrinsic::riscv_sf_vlte16:
2510+ case Intrinsic::riscv_sf_vlte32:
2511+ case Intrinsic::riscv_sf_vlte64: {
2512+ unsigned Log2SEW;
2513+ unsigned PseudoInst;
2514+ switch (IntNo) {
2515+ case Intrinsic::riscv_sf_vlte8:
2516+ PseudoInst = RISCV::PseudoSF_VLTE8;
2517+ Log2SEW = 3 ;
2518+ break ;
2519+ case Intrinsic::riscv_sf_vlte16:
2520+ PseudoInst = RISCV::PseudoSF_VLTE16;
2521+ Log2SEW = 4 ;
2522+ break ;
2523+ case Intrinsic::riscv_sf_vlte32:
2524+ PseudoInst = RISCV::PseudoSF_VLTE32;
2525+ Log2SEW = 5 ;
2526+ break ;
2527+ case Intrinsic::riscv_sf_vlte64:
2528+ PseudoInst = RISCV::PseudoSF_VLTE64;
2529+ Log2SEW = 6 ;
2530+ break ;
2531+ }
2532+
2533+ SDValue SEWOp = CurDAG->getTargetConstant (Log2SEW, DL, XLenVT);
2534+ SDValue TWidenOp = CurDAG->getTargetConstant (1 , DL, XLenVT);
2535+ SDValue Operands[] = {Node->getOperand (2 ),
2536+ Node->getOperand (3 ),
2537+ Node->getOperand (4 ),
2538+ SEWOp,
2539+ TWidenOp,
2540+ Node->getOperand (0 )};
2541+
2542+ MachineSDNode *TileLoad =
2543+ CurDAG->getMachineNode (PseudoInst, DL, Node->getVTList (), Operands);
2544+ if (auto *MemOp = dyn_cast<MemSDNode>(Node))
2545+ CurDAG->setNodeMemRefs (TileLoad, {MemOp->getMemOperand ()});
2546+
2547+ ReplaceNode (Node, TileLoad);
2548+ return ;
2549+ }
2550+ case Intrinsic::riscv_sf_mm_s_s:
2551+ case Intrinsic::riscv_sf_mm_s_u:
2552+ case Intrinsic::riscv_sf_mm_u_s:
2553+ case Intrinsic::riscv_sf_mm_u_u:
2554+ case Intrinsic::riscv_sf_mm_e5m2_e5m2:
2555+ case Intrinsic::riscv_sf_mm_e5m2_e4m3:
2556+ case Intrinsic::riscv_sf_mm_e4m3_e5m2:
2557+ case Intrinsic::riscv_sf_mm_e4m3_e4m3:
2558+ case Intrinsic::riscv_sf_mm_f_f: {
2559+ bool HasFRM = false ;
2560+ unsigned PseudoInst;
2561+ switch (IntNo) {
2562+ case Intrinsic::riscv_sf_mm_s_s:
2563+ PseudoInst = RISCV::PseudoSF_MM_S_S;
2564+ break ;
2565+ case Intrinsic::riscv_sf_mm_s_u:
2566+ PseudoInst = RISCV::PseudoSF_MM_S_U;
2567+ break ;
2568+ case Intrinsic::riscv_sf_mm_u_s:
2569+ PseudoInst = RISCV::PseudoSF_MM_U_S;
2570+ break ;
2571+ case Intrinsic::riscv_sf_mm_u_u:
2572+ PseudoInst = RISCV::PseudoSF_MM_U_U;
2573+ break ;
2574+ case Intrinsic::riscv_sf_mm_e5m2_e5m2:
2575+ PseudoInst = RISCV::PseudoSF_MM_E5M2_E5M2;
2576+ HasFRM = true ;
2577+ break ;
2578+ case Intrinsic::riscv_sf_mm_e5m2_e4m3:
2579+ PseudoInst = RISCV::PseudoSF_MM_E5M2_E4M3;
2580+ HasFRM = true ;
2581+ break ;
2582+ case Intrinsic::riscv_sf_mm_e4m3_e5m2:
2583+ PseudoInst = RISCV::PseudoSF_MM_E4M3_E5M2;
2584+ HasFRM = true ;
2585+ break ;
2586+ case Intrinsic::riscv_sf_mm_e4m3_e4m3:
2587+ PseudoInst = RISCV::PseudoSF_MM_E4M3_E4M3;
2588+ HasFRM = true ;
2589+ break ;
2590+ case Intrinsic::riscv_sf_mm_f_f:
2591+ if (Node->getOperand (3 ).getValueType ().getScalarType () == MVT::bf16 )
2592+ PseudoInst = RISCV::PseudoSF_MM_F_F_ALT;
2593+ else
2594+ PseudoInst = RISCV::PseudoSF_MM_F_F;
2595+ HasFRM = true ;
2596+ break ;
2597+ }
2598+ uint64_t TileNum = Node->getConstantOperandVal (2 );
2599+ SDValue Op1 = Node->getOperand (3 );
2600+ SDValue Op2 = Node->getOperand (4 );
2601+ MVT VT = Op1->getSimpleValueType (0 );
2602+ unsigned Log2SEW = Log2_32 (VT.getScalarSizeInBits ());
2603+ SDValue TmOp = Node->getOperand (5 );
2604+ SDValue TnOp = Node->getOperand (6 );
2605+ SDValue TkOp = Node->getOperand (7 );
2606+ SDValue TWidenOp = Node->getOperand (8 );
2607+ SDValue Chain = Node->getOperand (0 );
2608+
2609+ // sf.mm.f.f with sew=32, twiden=2 is invalid
2610+ if (IntNo == Intrinsic::riscv_sf_mm_f_f && Log2SEW == 5 &&
2611+ TWidenOp->getAsZExtVal () == 2 )
2612+ reportFatalUsageError (" sf.mm.f.f doesn't support (sew=32, twiden=2)" );
2613+
2614+ SmallVector<SDValue, 10 > Operands (
2615+ {CurDAG->getRegister (getTileReg (TileNum), XLenVT), Op1, Op2});
2616+ if (HasFRM)
2617+ Operands.push_back (
2618+ CurDAG->getTargetConstant (RISCVFPRndMode::DYN, DL, XLenVT));
2619+ Operands.append ({TmOp, TnOp, TkOp,
2620+ CurDAG->getTargetConstant (Log2SEW, DL, XLenVT), TWidenOp,
2621+ Chain});
2622+
2623+ auto *NewNode =
2624+ CurDAG->getMachineNode (PseudoInst, DL, Node->getVTList (), Operands);
2625+
2626+ ReplaceNode (Node, NewNode);
2627+ return ;
2628+ }
2629+ case Intrinsic::riscv_sf_vtzero_t : {
2630+ uint64_t TileNum = Node->getConstantOperandVal (2 );
2631+ SDValue Tm = Node->getOperand (3 );
2632+ SDValue Tn = Node->getOperand (4 );
2633+ SDValue Log2SEW = Node->getOperand (5 );
2634+ SDValue TWiden = Node->getOperand (6 );
2635+ SDValue Chain = Node->getOperand (0 );
2636+ auto *NewNode = CurDAG->getMachineNode (
2637+ RISCV::PseudoSF_VTZERO_T, DL, Node->getVTList (),
2638+ {CurDAG->getRegister (getTileReg (TileNum), XLenVT), Tm, Tn, Log2SEW,
2639+ TWiden, Chain});
2640+
2641+ ReplaceNode (Node, NewNode);
2642+ return ;
2643+ }
24612644 }
24622645 break ;
24632646 }
0 commit comments