Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 18 additions & 35 deletions llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,6 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);

bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
const ConstantSDNode *CN = cast<ConstantSDNode>(N);
Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32);
Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32);
return true;
}

bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N,
Expand Down Expand Up @@ -4123,17 +4116,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue N1 = N->getOperand(1);
SDValue N2 = N->getOperand(2);
SDValue N3 = N->getOperand(3);
SDValue InGlue = N->getOperand(4);
SDValue Flags = N->getOperand(3);
assert(N1.getOpcode() == ISD::BasicBlock);
assert(N2.getOpcode() == ISD::Constant);
assert(N3.getOpcode() == ISD::Register);

unsigned CC = (unsigned)N2->getAsZExtVal();

if (InGlue.getOpcode() == ARMISD::CMPZ) {
if (InGlue.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
SDValue Int = InGlue.getOperand(0);
if (Flags.getOpcode() == ARMISD::CMPZ) {
if (Flags.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
SDValue Int = Flags.getOperand(0);
uint64_t ID = Int->getConstantOperandVal(1);

// Handle low-overhead loops.
Expand All @@ -4155,15 +4146,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {

ReplaceUses(N, LoopEnd);
CurDAG->RemoveDeadNode(N);
CurDAG->RemoveDeadNode(InGlue.getNode());
CurDAG->RemoveDeadNode(Flags.getNode());
CurDAG->RemoveDeadNode(Int.getNode());
return;
}
}

bool SwitchEQNEToPLMI;
SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
InGlue = N->getOperand(4);
SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);
Flags = N->getOperand(3);

if (SwitchEQNEToPLMI) {
switch ((ARMCC::CondCodes)CC) {
Expand All @@ -4179,25 +4170,18 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}

SDValue Tmp2 = CurDAG->getTargetConstant(CC, dl, MVT::i32);
SDValue Ops[] = { N1, Tmp2, N3, Chain, InGlue };
SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
MVT::Glue, Ops);
Chain = SDValue(ResNode, 0);
if (N->getNumValues() == 2) {
InGlue = SDValue(ResNode, 1);
ReplaceUses(SDValue(N, 1), InGlue);
}
ReplaceUses(SDValue(N, 0),
SDValue(Chain.getNode(), Chain.getResNo()));
CurDAG->RemoveDeadNode(N);
Chain = CurDAG->getCopyToReg(Chain, dl, ARM::CPSR, Flags, SDValue());
SDValue Ops[] = {N1, Tmp2, CurDAG->getRegister(ARM::CPSR, MVT::i32), Chain,
Chain.getValue(1)};
CurDAG->SelectNodeTo(N, Opc, MVT::Other, Ops);
return;
}

case ARMISD::CMPZ: {
// select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
// This allows us to avoid materializing the expensive negative constant.
// The CMPZ #0 is useless and will be peepholed away but we need to keep it
// for its glue output.
// The CMPZ #0 is useless and will be peepholed away but we need to keep
// it for its flags output.
SDValue X = N->getOperand(0);
auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1).getNode());
if (C && C->getSExtValue() < 0 && Subtarget->isThumb()) {
Expand All @@ -4224,19 +4208,19 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
if (Add) {
SDValue Ops2[] = {SDValue(Add, 0), CurDAG->getConstant(0, dl, MVT::i32)};
CurDAG->MorphNodeTo(N, ARMISD::CMPZ, CurDAG->getVTList(MVT::Glue), Ops2);
CurDAG->MorphNodeTo(N, ARMISD::CMPZ, N->getVTList(), Ops2);
}
}
// Other cases are autogenerated.
break;
}

case ARMISD::CMOV: {
SDValue InGlue = N->getOperand(4);
SDValue Flags = N->getOperand(3);

if (InGlue.getOpcode() == ARMISD::CMPZ) {
if (Flags.getOpcode() == ARMISD::CMPZ) {
bool SwitchEQNEToPLMI;
SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);

if (SwitchEQNEToPLMI) {
SDValue ARMcc = N->getOperand(2);
Expand All @@ -4253,10 +4237,9 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
SDValue NewARMcc = CurDAG->getConstant((unsigned)CC, dl, MVT::i32);
SDValue Ops[] = {N->getOperand(0), N->getOperand(1), NewARMcc,
N->getOperand(3), N->getOperand(4)};
N->getOperand(3)};
CurDAG->MorphNodeTo(N, ARMISD::CMOV, N->getVTList(), Ops);
}

}
// Other cases are autogenerated.
break;
Expand Down
Loading
Loading