@@ -335,6 +335,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
335
335
setTargetDAGCombine (ISD::AND);
336
336
setTargetDAGCombine (ISD::OR);
337
337
setTargetDAGCombine (ISD::SRL);
338
+ setTargetDAGCombine (ISD::SETCC);
338
339
339
340
// Set DAG combine for 'LSX' feature.
340
341
@@ -2528,6 +2529,169 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
2528
2529
return SDValue ();
2529
2530
}
2530
2531
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
+
2531
2695
// Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
2532
2696
static SDValue performBITREV_WCombine (SDNode *N, SelectionDAG &DAG,
2533
2697
TargetLowering::DAGCombinerInfo &DCI,
@@ -3155,6 +3319,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
3155
3319
return performANDCombine (N, DAG, DCI, Subtarget);
3156
3320
case ISD::OR:
3157
3321
return performORCombine (N, DAG, DCI, Subtarget);
3322
+ case ISD::SETCC:
3323
+ return performSETCCCombine (N, DAG, DCI, Subtarget);
3158
3324
case ISD::SRL:
3159
3325
return performSRLCombine (N, DAG, DCI, Subtarget);
3160
3326
case LoongArchISD::BITREV_W:
0 commit comments