@@ -335,6 +335,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
335335 setTargetDAGCombine (ISD::AND);
336336 setTargetDAGCombine (ISD::OR);
337337 setTargetDAGCombine (ISD::SRL);
338+ setTargetDAGCombine (ISD::SETCC);
338339
339340 // Set DAG combine for 'LSX' feature.
340341
@@ -2528,6 +2529,169 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
25282529 return SDValue ();
25292530}
25302531
2532+ static bool checkValueWidth (SDValue V, ISD::LoadExtType &ExtType) {
2533+ ExtType = ISD::NON_EXTLOAD;
2534+
2535+ switch (V.getNode ()->getOpcode ()) {
2536+ case ISD::LOAD: {
2537+ LoadSDNode *LoadNode = cast<LoadSDNode>(V.getNode ());
2538+ if ((LoadNode->getMemoryVT () == MVT::i8 ) ||
2539+ (LoadNode->getMemoryVT () == MVT::i16 )) {
2540+ ExtType = LoadNode->getExtensionType ();
2541+ return true ;
2542+ }
2543+ return false ;
2544+ }
2545+ case ISD::AssertSext: {
2546+ VTSDNode *TypeNode = cast<VTSDNode>(V.getNode ()->getOperand (1 ));
2547+ if ((TypeNode->getVT () == MVT::i8 ) || (TypeNode->getVT () == MVT::i16 )) {
2548+ ExtType = ISD::SEXTLOAD;
2549+ return true ;
2550+ }
2551+ return false ;
2552+ }
2553+ case ISD::AssertZext: {
2554+ VTSDNode *TypeNode = cast<VTSDNode>(V.getNode ()->getOperand (1 ));
2555+ if ((TypeNode->getVT () == MVT::i8 ) || (TypeNode->getVT () == MVT::i16 )) {
2556+ ExtType = ISD::ZEXTLOAD;
2557+ return true ;
2558+ }
2559+ return false ;
2560+ }
2561+ default :
2562+ return false ;
2563+ }
2564+
2565+ return false ;
2566+ }
2567+
2568+ // Eliminate redundant truncation and zero-extension nodes.
2569+ // * Case 1:
2570+ // +------------+ +------------+ +------------+
2571+ // | Input1 | | Input2 | | CC |
2572+ // +------------+ +------------+ +------------+
2573+ // | | |
2574+ // V V +----+
2575+ // +------------+ +------------+ |
2576+ // | TRUNCATE | | TRUNCATE | |
2577+ // +------------+ +------------+ |
2578+ // | | |
2579+ // V V |
2580+ // +------------+ +------------+ |
2581+ // | ZERO_EXT | | ZERO_EXT | |
2582+ // +------------+ +------------+ |
2583+ // | | |
2584+ // | +-------------+ |
2585+ // V V | |
2586+ // +----------------+ | |
2587+ // | AND | | |
2588+ // +----------------+ | |
2589+ // | | |
2590+ // +---------------+ | |
2591+ // | | |
2592+ // V V V
2593+ // +-------------+
2594+ // | CMP |
2595+ // +-------------+
2596+ // * Case 2:
2597+ // +------------+ +------------+ +-------------+ +------------+ +------------+
2598+ // | Input1 | | Input2 | | Constant -1 | | Constant 0 | | CC |
2599+ // +------------+ +------------+ +-------------+ +------------+ +------------+
2600+ // | | | | |
2601+ // V | | | |
2602+ // +------------+ | | | |
2603+ // | XOR |<---------------------+ | |
2604+ // +------------+ | | |
2605+ // | | | |
2606+ // V V +---------------+ |
2607+ // +------------+ +------------+ | |
2608+ // | TRUNCATE | | TRUNCATE | | +-------------------------+
2609+ // +------------+ +------------+ | |
2610+ // | | | |
2611+ // V V | |
2612+ // +------------+ +------------+ | |
2613+ // | ZERO_EXT | | ZERO_EXT | | |
2614+ // +------------+ +------------+ | |
2615+ // | | | |
2616+ // V V | |
2617+ // +----------------+ | |
2618+ // | AND | | |
2619+ // +----------------+ | |
2620+ // | | |
2621+ // +---------------+ | |
2622+ // | | |
2623+ // V V V
2624+ // +-------------+
2625+ // | CMP |
2626+ // +-------------+
2627+ static SDValue performSETCCCombine (SDNode *N, SelectionDAG &DAG,
2628+ TargetLowering::DAGCombinerInfo &DCI,
2629+ const LoongArchSubtarget &Subtarget) {
2630+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand (2 ))->get ();
2631+
2632+ SDNode *AndNode = N->getOperand (0 ).getNode ();
2633+ if (AndNode->getOpcode () != ISD::AND)
2634+ return SDValue ();
2635+
2636+ SDValue AndInputValue2 = AndNode->getOperand (1 );
2637+ if (AndInputValue2.getOpcode () != ISD::ZERO_EXTEND)
2638+ return SDValue ();
2639+
2640+ SDValue CmpInputValue = N->getOperand (1 );
2641+ SDValue AndInputValue1 = AndNode->getOperand (0 );
2642+ if (AndInputValue1.getOpcode () == ISD::XOR) {
2643+ if (CC != ISD::SETEQ && CC != ISD::SETNE)
2644+ return SDValue ();
2645+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(AndInputValue1.getOperand (1 ));
2646+ if (!CN || CN->getSExtValue () != -1 )
2647+ return SDValue ();
2648+ CN = dyn_cast<ConstantSDNode>(CmpInputValue);
2649+ if (!CN || CN->getSExtValue () != 0 )
2650+ return SDValue ();
2651+ AndInputValue1 = AndInputValue1.getOperand (0 );
2652+ if (AndInputValue1.getOpcode () != ISD::ZERO_EXTEND)
2653+ return SDValue ();
2654+ } else if (AndInputValue1.getOpcode () == ISD::ZERO_EXTEND) {
2655+ if (AndInputValue2 != CmpInputValue)
2656+ return SDValue ();
2657+ } else {
2658+ return SDValue ();
2659+ }
2660+
2661+ SDValue TruncValue1 = AndInputValue1.getNode ()->getOperand (0 );
2662+ if (TruncValue1.getOpcode () != ISD::TRUNCATE)
2663+ return SDValue ();
2664+
2665+ SDValue TruncValue2 = AndInputValue2.getNode ()->getOperand (0 );
2666+ if (TruncValue2.getOpcode () != ISD::TRUNCATE)
2667+ return SDValue ();
2668+
2669+ SDValue TruncInputValue1 = TruncValue1.getNode ()->getOperand (0 );
2670+ SDValue TruncInputValue2 = TruncValue2.getNode ()->getOperand (0 );
2671+ ISD::LoadExtType ExtType1;
2672+ ISD::LoadExtType ExtType2;
2673+
2674+ if (!checkValueWidth (TruncInputValue1, ExtType1) ||
2675+ !checkValueWidth (TruncInputValue2, ExtType2))
2676+ return SDValue ();
2677+
2678+ if (TruncInputValue1->getValueType (0 ) != TruncInputValue2->getValueType (0 ) ||
2679+ AndNode->getValueType (0 ) != TruncInputValue1->getValueType (0 ))
2680+ return SDValue ();
2681+
2682+ if ((ExtType2 != ISD::ZEXTLOAD) &&
2683+ ((ExtType2 != ISD::SEXTLOAD) && (ExtType1 != ISD::SEXTLOAD)))
2684+ return SDValue ();
2685+
2686+ // These truncation and zero-extension nodes are not necessary, remove them.
2687+ SDValue NewAnd = DAG.getNode (ISD::AND, SDLoc (N), AndNode->getValueType (0 ),
2688+ TruncInputValue1, TruncInputValue2);
2689+ SDValue NewSetCC =
2690+ DAG.getSetCC (SDLoc (N), N->getValueType (0 ), NewAnd, TruncInputValue2, CC);
2691+ DAG.ReplaceAllUsesWith (N, NewSetCC.getNode ());
2692+ return SDValue (N, 0 );
2693+ }
2694+
25312695// Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
25322696static SDValue performBITREV_WCombine (SDNode *N, SelectionDAG &DAG,
25332697 TargetLowering::DAGCombinerInfo &DCI,
@@ -3155,6 +3319,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
31553319 return performANDCombine (N, DAG, DCI, Subtarget);
31563320 case ISD::OR:
31573321 return performORCombine (N, DAG, DCI, Subtarget);
3322+ case ISD::SETCC:
3323+ return performSETCCCombine (N, DAG, DCI, Subtarget);
31583324 case ISD::SRL:
31593325 return performSRLCombine (N, DAG, DCI, Subtarget);
31603326 case LoongArchISD::BITREV_W:
0 commit comments