Skip to content

Commit

Permalink
[LoongArch] Recommit "Remove spurious mask operations from andn->icmp…
Browse files Browse the repository at this point in the history
… on 16 and 8 bit values" (#99798)

Summary: recommit of #99272

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251358
  • Loading branch information
heiher authored and yuxuanchen1997 committed Jul 25, 2024
1 parent 35dda53 commit 3762a1b
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 41 deletions.
166 changes: 166 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setTargetDAGCombine(ISD::AND);
setTargetDAGCombine(ISD::OR);
setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::SETCC);

// Set DAG combine for 'LSX' feature.

Expand Down Expand Up @@ -2528,6 +2529,169 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}

static bool checkValueWidth(SDValue V, ISD::LoadExtType &ExtType) {
ExtType = ISD::NON_EXTLOAD;

switch (V.getNode()->getOpcode()) {
case ISD::LOAD: {
LoadSDNode *LoadNode = cast<LoadSDNode>(V.getNode());
if ((LoadNode->getMemoryVT() == MVT::i8) ||
(LoadNode->getMemoryVT() == MVT::i16)) {
ExtType = LoadNode->getExtensionType();
return true;
}
return false;
}
case ISD::AssertSext: {
VTSDNode *TypeNode = cast<VTSDNode>(V.getNode()->getOperand(1));
if ((TypeNode->getVT() == MVT::i8) || (TypeNode->getVT() == MVT::i16)) {
ExtType = ISD::SEXTLOAD;
return true;
}
return false;
}
case ISD::AssertZext: {
VTSDNode *TypeNode = cast<VTSDNode>(V.getNode()->getOperand(1));
if ((TypeNode->getVT() == MVT::i8) || (TypeNode->getVT() == MVT::i16)) {
ExtType = ISD::ZEXTLOAD;
return true;
}
return false;
}
default:
return false;
}

return false;
}

// Eliminate redundant truncation and zero-extension nodes.
// * Case 1:
// +------------+ +------------+ +------------+
// | Input1 | | Input2 | | CC |
// +------------+ +------------+ +------------+
// | | |
// V V +----+
// +------------+ +------------+ |
// | TRUNCATE | | TRUNCATE | |
// +------------+ +------------+ |
// | | |
// V V |
// +------------+ +------------+ |
// | ZERO_EXT | | ZERO_EXT | |
// +------------+ +------------+ |
// | | |
// | +-------------+ |
// V V | |
// +----------------+ | |
// | AND | | |
// +----------------+ | |
// | | |
// +---------------+ | |
// | | |
// V V V
// +-------------+
// | CMP |
// +-------------+
// * Case 2:
// +------------+ +------------+ +-------------+ +------------+ +------------+
// | Input1 | | Input2 | | Constant -1 | | Constant 0 | | CC |
// +------------+ +------------+ +-------------+ +------------+ +------------+
// | | | | |
// V | | | |
// +------------+ | | | |
// | XOR |<---------------------+ | |
// +------------+ | | |
// | | | |
// V V +---------------+ |
// +------------+ +------------+ | |
// | TRUNCATE | | TRUNCATE | | +-------------------------+
// +------------+ +------------+ | |
// | | | |
// V V | |
// +------------+ +------------+ | |
// | ZERO_EXT | | ZERO_EXT | | |
// +------------+ +------------+ | |
// | | | |
// V V | |
// +----------------+ | |
// | AND | | |
// +----------------+ | |
// | | |
// +---------------+ | |
// | | |
// V V V
// +-------------+
// | CMP |
// +-------------+
static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const LoongArchSubtarget &Subtarget) {
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();

SDNode *AndNode = N->getOperand(0).getNode();
if (AndNode->getOpcode() != ISD::AND)
return SDValue();

SDValue AndInputValue2 = AndNode->getOperand(1);
if (AndInputValue2.getOpcode() != ISD::ZERO_EXTEND)
return SDValue();

SDValue CmpInputValue = N->getOperand(1);
SDValue AndInputValue1 = AndNode->getOperand(0);
if (AndInputValue1.getOpcode() == ISD::XOR) {
if (CC != ISD::SETEQ && CC != ISD::SETNE)
return SDValue();
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(AndInputValue1.getOperand(1));
if (!CN || CN->getSExtValue() != -1)
return SDValue();
CN = dyn_cast<ConstantSDNode>(CmpInputValue);
if (!CN || CN->getSExtValue() != 0)
return SDValue();
AndInputValue1 = AndInputValue1.getOperand(0);
if (AndInputValue1.getOpcode() != ISD::ZERO_EXTEND)
return SDValue();
} else if (AndInputValue1.getOpcode() == ISD::ZERO_EXTEND) {
if (AndInputValue2 != CmpInputValue)
return SDValue();
} else {
return SDValue();
}

SDValue TruncValue1 = AndInputValue1.getNode()->getOperand(0);
if (TruncValue1.getOpcode() != ISD::TRUNCATE)
return SDValue();

SDValue TruncValue2 = AndInputValue2.getNode()->getOperand(0);
if (TruncValue2.getOpcode() != ISD::TRUNCATE)
return SDValue();

SDValue TruncInputValue1 = TruncValue1.getNode()->getOperand(0);
SDValue TruncInputValue2 = TruncValue2.getNode()->getOperand(0);
ISD::LoadExtType ExtType1;
ISD::LoadExtType ExtType2;

if (!checkValueWidth(TruncInputValue1, ExtType1) ||
!checkValueWidth(TruncInputValue2, ExtType2))
return SDValue();

if (TruncInputValue1->getValueType(0) != TruncInputValue2->getValueType(0) ||
AndNode->getValueType(0) != TruncInputValue1->getValueType(0))
return SDValue();

if ((ExtType2 != ISD::ZEXTLOAD) &&
((ExtType2 != ISD::SEXTLOAD) && (ExtType1 != ISD::SEXTLOAD)))
return SDValue();

// These truncation and zero-extension nodes are not necessary, remove them.
SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N), AndNode->getValueType(0),
TruncInputValue1, TruncInputValue2);
SDValue NewSetCC =
DAG.getSetCC(SDLoc(N), N->getValueType(0), NewAnd, TruncInputValue2, CC);
DAG.ReplaceAllUsesWith(N, NewSetCC.getNode());
return SDValue(N, 0);
}

// Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
Expand Down Expand Up @@ -3155,6 +3319,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
return performANDCombine(N, DAG, DCI, Subtarget);
case ISD::OR:
return performORCombine(N, DAG, DCI, Subtarget);
case ISD::SETCC:
return performSETCCCombine(N, DAG, DCI, Subtarget);
case ISD::SRL:
return performSRLCombine(N, DAG, DCI, Subtarget);
case LoongArchISD::BITREV_W:
Expand Down
Loading

0 comments on commit 3762a1b

Please sign in to comment.