@@ -111,6 +111,13 @@ 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+
114121 bool SelectAddrMode2OffsetReg (SDNode *Op, SDValue N,
115122 SDValue &Offset, SDValue &Opc);
116123 bool SelectAddrMode2OffsetImm (SDNode *Op, SDValue N,
@@ -4116,15 +4123,17 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41164123 SDValue Chain = N->getOperand (0 );
41174124 SDValue N1 = N->getOperand (1 );
41184125 SDValue N2 = N->getOperand (2 );
4119- SDValue Flags = N->getOperand (3 );
4126+ SDValue N3 = N->getOperand (3 );
4127+ SDValue InGlue = N->getOperand (4 );
41204128 assert (N1.getOpcode () == ISD::BasicBlock);
41214129 assert (N2.getOpcode () == ISD::Constant);
4130+ assert (N3.getOpcode () == ISD::Register);
41224131
41234132 unsigned CC = (unsigned )N2->getAsZExtVal ();
41244133
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 );
41284137 uint64_t ID = Int->getConstantOperandVal (1 );
41294138
41304139 // Handle low-overhead loops.
@@ -4146,15 +4155,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41464155
41474156 ReplaceUses (N, LoopEnd);
41484157 CurDAG->RemoveDeadNode (N);
4149- CurDAG->RemoveDeadNode (Flags .getNode ());
4158+ CurDAG->RemoveDeadNode (InGlue .getNode ());
41504159 CurDAG->RemoveDeadNode (Int.getNode ());
41514160 return ;
41524161 }
41534162 }
41544163
41554164 bool SwitchEQNEToPLMI;
4156- SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4157- Flags = N->getOperand (3 );
4165+ SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
4166+ InGlue = N->getOperand (4 );
41584167
41594168 if (SwitchEQNEToPLMI) {
41604169 switch ((ARMCC::CondCodes)CC) {
@@ -4170,18 +4179,25 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
41704179 }
41714180
41724181 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);
41774193 return ;
41784194 }
41794195
41804196 case ARMISD::CMPZ: {
41814197 // select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
41824198 // 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.
41854201 SDValue X = N->getOperand (0 );
41864202 auto *C = dyn_cast<ConstantSDNode>(N->getOperand (1 ).getNode ());
41874203 if (C && C->getSExtValue () < 0 && Subtarget->isThumb ()) {
@@ -4208,19 +4224,19 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
42084224 }
42094225 if (Add) {
42104226 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);
42124228 }
42134229 }
42144230 // Other cases are autogenerated.
42154231 break ;
42164232 }
42174233
42184234 case ARMISD::CMOV: {
4219- SDValue Flags = N->getOperand (3 );
4235+ SDValue InGlue = N->getOperand (4 );
42204236
4221- if (Flags .getOpcode () == ARMISD::CMPZ) {
4237+ if (InGlue .getOpcode () == ARMISD::CMPZ) {
42224238 bool SwitchEQNEToPLMI;
4223- SelectCMPZ (Flags .getNode (), SwitchEQNEToPLMI);
4239+ SelectCMPZ (InGlue .getNode (), SwitchEQNEToPLMI);
42244240
42254241 if (SwitchEQNEToPLMI) {
42264242 SDValue ARMcc = N->getOperand (2 );
@@ -4237,9 +4253,10 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
42374253 }
42384254 SDValue NewARMcc = CurDAG->getConstant ((unsigned )CC, dl, MVT::i32 );
42394255 SDValue Ops[] = {N->getOperand (0 ), N->getOperand (1 ), NewARMcc,
4240- N->getOperand (3 )};
4256+ N->getOperand (3 ), N-> getOperand ( 4 ) };
42414257 CurDAG->MorphNodeTo (N, ARMISD::CMOV, N->getVTList (), Ops);
42424258 }
4259+
42434260 }
42444261 // Other cases are autogenerated.
42454262 break ;
0 commit comments