@@ -111,6 +111,13 @@ 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
+
114
121
bool SelectAddrMode2OffsetReg (SDNode *Op, SDValue N,
115
122
SDValue &Offset, SDValue &Opc);
116
123
bool SelectAddrMode2OffsetImm (SDNode *Op, SDValue N,
@@ -4116,15 +4123,17 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4116
4123
SDValue Chain = N->getOperand (0 );
4117
4124
SDValue N1 = N->getOperand (1 );
4118
4125
SDValue N2 = N->getOperand (2 );
4119
- SDValue Flags = N->getOperand (3 );
4126
+ SDValue N3 = N->getOperand (3 );
4127
+ SDValue InGlue = N->getOperand (4 );
4120
4128
assert (N1.getOpcode () == ISD::BasicBlock);
4121
4129
assert (N2.getOpcode () == ISD::Constant);
4130
+ assert (N3.getOpcode () == ISD::Register);
4122
4131
4123
4132
unsigned CC = (unsigned )N2->getAsZExtVal ();
4124
4133
4125
- if (Flags .getOpcode () == ARMISD::CMPZ) {
4126
- if (Flags .getOperand (0 ).getOpcode () == ISD::INTRINSIC_W_CHAIN) {
4127
- SDValue Int = Flags .getOperand (0 );
4134
+ if (InGlue .getOpcode () == ARMISD::CMPZ) {
4135
+ if (InGlue .getOperand (0 ).getOpcode () == ISD::INTRINSIC_W_CHAIN) {
4136
+ SDValue Int = InGlue .getOperand (0 );
4128
4137
uint64_t ID = Int->getConstantOperandVal (1 );
4129
4138
4130
4139
// Handle low-overhead loops.
@@ -4146,15 +4155,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4146
4155
4147
4156
ReplaceUses (N, LoopEnd);
4148
4157
CurDAG->RemoveDeadNode (N);
4149
- CurDAG->RemoveDeadNode (Flags .getNode ());
4158
+ CurDAG->RemoveDeadNode (InGlue .getNode ());
4150
4159
CurDAG->RemoveDeadNode (Int.getNode ());
4151
4160
return ;
4152
4161
}
4153
4162
}
4154
4163
4155
4164
bool SwitchEQNEToPLMI;
4156
- SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4157
- Flags = N->getOperand (3 );
4165
+ SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
4166
+ InGlue = N->getOperand (4 );
4158
4167
4159
4168
if (SwitchEQNEToPLMI) {
4160
4169
switch ((ARMCC::CondCodes)CC) {
@@ -4170,18 +4179,25 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4170
4179
}
4171
4180
4172
4181
SDValue Tmp2 = CurDAG->getTargetConstant (CC, dl, MVT::i32);
4173
- Chain = CurDAG->getCopyToReg (Chain, dl, ARM::CPSR, Flags, SDValue ());
4174
- SDValue Ops[] = {N1, Tmp2, CurDAG->getRegister (ARM::CPSR, MVT::i32), Chain,
4175
- Chain.getValue (1 )};
4176
- CurDAG->SelectNodeTo (N, Opc, MVT::Other, Ops);
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
4193
return ;
4178
4194
}
4179
4195
4180
4196
case ARMISD::CMPZ: {
4181
4197
// select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
4182
4198
// This allows us to avoid materializing the expensive negative constant.
4183
- // The CMPZ #0 is useless and will be peepholed away but we need to keep
4184
- // it for its flags output.
4199
+ // The CMPZ #0 is useless and will be peepholed away but we need to keep it
4200
+ // for its glue output.
4185
4201
SDValue X = N->getOperand (0 );
4186
4202
auto *C = dyn_cast<ConstantSDNode>(N->getOperand (1 ).getNode ());
4187
4203
if (C && C->getSExtValue () < 0 && Subtarget->isThumb ()) {
@@ -4208,19 +4224,19 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4208
4224
}
4209
4225
if (Add) {
4210
4226
SDValue Ops2[] = {SDValue (Add, 0 ), CurDAG->getConstant (0 , dl, MVT::i32)};
4211
- CurDAG->MorphNodeTo (N, ARMISD::CMPZ, N ->getVTList (), Ops2);
4227
+ CurDAG->MorphNodeTo (N, ARMISD::CMPZ, CurDAG ->getVTList (MVT::Glue ), Ops2);
4212
4228
}
4213
4229
}
4214
4230
// Other cases are autogenerated.
4215
4231
break ;
4216
4232
}
4217
4233
4218
4234
case ARMISD::CMOV: {
4219
- SDValue Flags = N->getOperand (3 );
4235
+ SDValue InGlue = N->getOperand (4 );
4220
4236
4221
- if (Flags .getOpcode () == ARMISD::CMPZ) {
4237
+ if (InGlue .getOpcode () == ARMISD::CMPZ) {
4222
4238
bool SwitchEQNEToPLMI;
4223
- SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4239
+ SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
4224
4240
4225
4241
if (SwitchEQNEToPLMI) {
4226
4242
SDValue ARMcc = N->getOperand (2 );
@@ -4237,9 +4253,10 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
4237
4253
}
4238
4254
SDValue NewARMcc = CurDAG->getConstant ((unsigned )CC, dl, MVT::i32);
4239
4255
SDValue Ops[] = {N->getOperand (0 ), N->getOperand (1 ), NewARMcc,
4240
- N->getOperand (3 )};
4256
+ N->getOperand (3 ), N-> getOperand ( 4 ) };
4241
4257
CurDAG->MorphNodeTo (N, ARMISD::CMOV, N->getVTList (), Ops);
4242
4258
}
4259
+
4243
4260
}
4244
4261
// Other cases are autogenerated.
4245
4262
break ;
0 commit comments