Skip to content

Commit

Permalink
[ARM] Stop gluing ALU nodes to branches / selects (llvm#116970)
Browse files Browse the repository at this point in the history
Following llvm#116547 and llvm#116676, this PR changes the type of results and
operands of some nodes to accept / return a normal type instead of Glue.

Unfortunately, changing the result type of one node requires changing
the operand types of all potential consumer nodes, which in turn
requires changing the result types of all other possible producer nodes.
So this is a bulk change.

Pull Request: llvm#116970
  • Loading branch information
s-barannikov authored Nov 30, 2024
1 parent 691e556 commit a348f22
Show file tree
Hide file tree
Showing 83 changed files with 10,027 additions and 11,288 deletions.
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

0 comments on commit a348f22

Please sign in to comment.