@@ -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