Skip to content

Commit e0ed033

Browse files
authored
Reland "[ARM] Stop gluing ALU nodes to branches / selects" (#118887)
Re-landing #116970 after fixing miscompilation error. The original change made it possible for CMPZ to have multiple uses; `ARMDAGToDAGISel::SelectCMPZ` was not prepared for this. Pull Request: #118887 Original commit message: Following #116547 and #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.
1 parent 37606b4 commit e0ed033

File tree

84 files changed

+10078
-11289
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+10078
-11289
lines changed

llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,6 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
111111
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
112112
bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);
113113

114-
bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
115-
const ConstantSDNode *CN = cast<ConstantSDNode>(N);
116-
Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32);
117-
Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32);
118-
return true;
119-
}
120-
121114
bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
122115
SDValue &Offset, SDValue &Opc);
123116
bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N,
@@ -3596,7 +3589,11 @@ void ARMDAGToDAGISel::SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI) {
35963589
ReplaceNode(And.getNode(), NewN);
35973590
} else if (Range->first == Range->second) {
35983591
// 3. Only one bit is set. We can shift this into the sign bit and use a
3599-
// PL/MI comparison.
3592+
// PL/MI comparison. This is not safe if CMPZ has multiple uses because
3593+
// only one of them (the one currently being selected) will be switched
3594+
// to use the new condition code.
3595+
if (!N->hasOneUse())
3596+
return;
36003597
NewN = EmitShift(ARM::tLSLri, X, 31 - Range->first);
36013598
ReplaceNode(And.getNode(), NewN);
36023599

@@ -4123,17 +4120,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41234120
SDValue Chain = N->getOperand(0);
41244121
SDValue N1 = N->getOperand(1);
41254122
SDValue N2 = N->getOperand(2);
4126-
SDValue N3 = N->getOperand(3);
4127-
SDValue InGlue = N->getOperand(4);
4123+
SDValue Flags = N->getOperand(3);
41284124
assert(N1.getOpcode() == ISD::BasicBlock);
41294125
assert(N2.getOpcode() == ISD::Constant);
4130-
assert(N3.getOpcode() == ISD::Register);
41314126

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

4134-
if (InGlue.getOpcode() == ARMISD::CMPZ) {
4135-
if (InGlue.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
4136-
SDValue Int = InGlue.getOperand(0);
4129+
if (Flags.getOpcode() == ARMISD::CMPZ) {
4130+
if (Flags.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
4131+
SDValue Int = Flags.getOperand(0);
41374132
uint64_t ID = Int->getConstantOperandVal(1);
41384133

41394134
// Handle low-overhead loops.
@@ -4155,15 +4150,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41554150

41564151
ReplaceUses(N, LoopEnd);
41574152
CurDAG->RemoveDeadNode(N);
4158-
CurDAG->RemoveDeadNode(InGlue.getNode());
4153+
CurDAG->RemoveDeadNode(Flags.getNode());
41594154
CurDAG->RemoveDeadNode(Int.getNode());
41604155
return;
41614156
}
41624157
}
41634158

41644159
bool SwitchEQNEToPLMI;
4165-
SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
4166-
InGlue = N->getOperand(4);
4160+
SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);
4161+
Flags = N->getOperand(3);
41674162

41684163
if (SwitchEQNEToPLMI) {
41694164
switch ((ARMCC::CondCodes)CC) {
@@ -4179,25 +4174,18 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41794174
}
41804175

41814176
SDValue Tmp2 = CurDAG->getTargetConstant(CC, dl, MVT::i32);
4182-
SDValue Ops[] = { N1, Tmp2, N3, Chain, InGlue };
4183-
SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
4184-
MVT::Glue, Ops);
4185-
Chain = SDValue(ResNode, 0);
4186-
if (N->getNumValues() == 2) {
4187-
InGlue = SDValue(ResNode, 1);
4188-
ReplaceUses(SDValue(N, 1), InGlue);
4189-
}
4190-
ReplaceUses(SDValue(N, 0),
4191-
SDValue(Chain.getNode(), Chain.getResNo()));
4192-
CurDAG->RemoveDeadNode(N);
4177+
Chain = CurDAG->getCopyToReg(Chain, dl, ARM::CPSR, Flags, SDValue());
4178+
SDValue Ops[] = {N1, Tmp2, CurDAG->getRegister(ARM::CPSR, MVT::i32), Chain,
4179+
Chain.getValue(1)};
4180+
CurDAG->SelectNodeTo(N, Opc, MVT::Other, Ops);
41934181
return;
41944182
}
41954183

41964184
case ARMISD::CMPZ: {
41974185
// select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
41984186
// This allows us to avoid materializing the expensive negative constant.
4199-
// The CMPZ #0 is useless and will be peepholed away but we need to keep it
4200-
// for its glue output.
4187+
// The CMPZ #0 is useless and will be peepholed away but we need to keep
4188+
// it for its flags output.
42014189
SDValue X = N->getOperand(0);
42024190
auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1).getNode());
42034191
if (C && C->getSExtValue() < 0 && Subtarget->isThumb()) {
@@ -4224,19 +4212,19 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
42244212
}
42254213
if (Add) {
42264214
SDValue Ops2[] = {SDValue(Add, 0), CurDAG->getConstant(0, dl, MVT::i32)};
4227-
CurDAG->MorphNodeTo(N, ARMISD::CMPZ, CurDAG->getVTList(MVT::Glue), Ops2);
4215+
CurDAG->MorphNodeTo(N, ARMISD::CMPZ, N->getVTList(), Ops2);
42284216
}
42294217
}
42304218
// Other cases are autogenerated.
42314219
break;
42324220
}
42334221

42344222
case ARMISD::CMOV: {
4235-
SDValue InGlue = N->getOperand(4);
4223+
SDValue Flags = N->getOperand(3);
42364224

4237-
if (InGlue.getOpcode() == ARMISD::CMPZ) {
4225+
if (Flags.getOpcode() == ARMISD::CMPZ) {
42384226
bool SwitchEQNEToPLMI;
4239-
SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
4227+
SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);
42404228

42414229
if (SwitchEQNEToPLMI) {
42424230
SDValue ARMcc = N->getOperand(2);
@@ -4253,10 +4241,9 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
42534241
}
42544242
SDValue NewARMcc = CurDAG->getConstant((unsigned)CC, dl, MVT::i32);
42554243
SDValue Ops[] = {N->getOperand(0), N->getOperand(1), NewARMcc,
4256-
N->getOperand(3), N->getOperand(4)};
4244+
N->getOperand(3)};
42574245
CurDAG->MorphNodeTo(N, ARMISD::CMOV, N->getVTList(), Ops);
42584246
}
4259-
42604247
}
42614248
// Other cases are autogenerated.
42624249
break;

0 commit comments

Comments
 (0)