@@ -111,13 +111,6 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
111
111
bool SelectAddrModeImm12 (SDValue N, SDValue &Base, SDValue &OffImm);
112
112
bool SelectLdStSOReg (SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);
113
113
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
-
121
114
bool SelectAddrMode2OffsetReg (SDNode *Op, SDValue N,
122
115
SDValue &Offset, SDValue &Opc);
123
116
bool SelectAddrMode2OffsetImm (SDNode *Op, SDValue N,
@@ -3596,7 +3589,11 @@ void ARMDAGToDAGISel::SelectCMPZ(SDNode *N, bool &SwitchEQNEToPLMI) {
3596
3589
ReplaceNode (And.getNode (), NewN);
3597
3590
} else if (Range->first == Range->second ) {
3598
3591
// 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 ;
3600
3597
NewN = EmitShift (ARM::tLSLri, X, 31 - Range->first );
3601
3598
ReplaceNode (And.getNode (), NewN);
3602
3599
@@ -4123,17 +4120,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4123
4120
SDValue Chain = N->getOperand (0 );
4124
4121
SDValue N1 = N->getOperand (1 );
4125
4122
SDValue N2 = N->getOperand (2 );
4126
- SDValue N3 = N->getOperand (3 );
4127
- SDValue InGlue = N->getOperand (4 );
4123
+ SDValue Flags = N->getOperand (3 );
4128
4124
assert (N1.getOpcode () == ISD::BasicBlock);
4129
4125
assert (N2.getOpcode () == ISD::Constant);
4130
- assert (N3.getOpcode () == ISD::Register);
4131
4126
4132
4127
unsigned CC = (unsigned )N2->getAsZExtVal ();
4133
4128
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 );
4137
4132
uint64_t ID = Int->getConstantOperandVal (1 );
4138
4133
4139
4134
// Handle low-overhead loops.
@@ -4155,15 +4150,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4155
4150
4156
4151
ReplaceUses (N, LoopEnd);
4157
4152
CurDAG->RemoveDeadNode (N);
4158
- CurDAG->RemoveDeadNode (InGlue .getNode ());
4153
+ CurDAG->RemoveDeadNode (Flags .getNode ());
4159
4154
CurDAG->RemoveDeadNode (Int.getNode ());
4160
4155
return ;
4161
4156
}
4162
4157
}
4163
4158
4164
4159
bool SwitchEQNEToPLMI;
4165
- SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
4166
- InGlue = N->getOperand (4 );
4160
+ SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4161
+ Flags = N->getOperand (3 );
4167
4162
4168
4163
if (SwitchEQNEToPLMI) {
4169
4164
switch ((ARMCC::CondCodes)CC) {
@@ -4179,25 +4174,18 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4179
4174
}
4180
4175
4181
4176
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);
4193
4181
return ;
4194
4182
}
4195
4183
4196
4184
case ARMISD::CMPZ: {
4197
4185
// select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
4198
4186
// 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.
4201
4189
SDValue X = N->getOperand (0 );
4202
4190
auto *C = dyn_cast<ConstantSDNode>(N->getOperand (1 ).getNode ());
4203
4191
if (C && C->getSExtValue () < 0 && Subtarget->isThumb ()) {
@@ -4224,19 +4212,19 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4224
4212
}
4225
4213
if (Add) {
4226
4214
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);
4228
4216
}
4229
4217
}
4230
4218
// Other cases are autogenerated.
4231
4219
break ;
4232
4220
}
4233
4221
4234
4222
case ARMISD::CMOV: {
4235
- SDValue InGlue = N->getOperand (4 );
4223
+ SDValue Flags = N->getOperand (3 );
4236
4224
4237
- if (InGlue .getOpcode () == ARMISD::CMPZ) {
4225
+ if (Flags .getOpcode () == ARMISD::CMPZ) {
4238
4226
bool SwitchEQNEToPLMI;
4239
- SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
4227
+ SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4240
4228
4241
4229
if (SwitchEQNEToPLMI) {
4242
4230
SDValue ARMcc = N->getOperand (2 );
@@ -4253,10 +4241,9 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4253
4241
}
4254
4242
SDValue NewARMcc = CurDAG->getConstant ((unsigned )CC, dl, MVT::i32 );
4255
4243
SDValue Ops[] = {N->getOperand (0 ), N->getOperand (1 ), NewARMcc,
4256
- N->getOperand (3 ), N-> getOperand ( 4 ) };
4244
+ N->getOperand (3 )};
4257
4245
CurDAG->MorphNodeTo (N, ARMISD::CMOV, N->getVTList (), Ops);
4258
4246
}
4259
-
4260
4247
}
4261
4248
// Other cases are autogenerated.
4262
4249
break ;
0 commit comments