Skip to content

Commit 4c73b1a

Browse files
authored
[LoongArch] Recommit "Remove spurious mask operations from andn->icmp on 16 and 8 bit values" (#99798)
recommit of #99272
1 parent 36d384b commit 4c73b1a

File tree

2 files changed

+182
-41
lines changed

2 files changed

+182
-41
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
25322696
static 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

Comments
 (0)