@@ -521,7 +521,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
521521 setOperationAction (ISD::TRAP, MVT::Other, Legal);
522522
523523 setTargetDAGCombine ({ISD::SDIVREM, ISD::UDIVREM, ISD::SELECT, ISD::AND,
524- ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL});
524+ ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL,
525+ ISD::SIGN_EXTEND});
525526
526527 if (Subtarget.isGP64bit ())
527528 setMaxAtomicSizeInBitsSupported (64 );
@@ -1221,6 +1222,37 @@ static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
12211222 DAG.getConstant (SMSize, DL, MVT::i32 ));
12221223}
12231224
1225+ static SDValue performSignExtendCombine (SDNode *N, SelectionDAG &DAG,
1226+ TargetLowering::DAGCombinerInfo &DCI,
1227+ const MipsSubtarget &Subtarget) {
1228+ if (DCI.Level != AfterLegalizeDAG || !Subtarget.isGP64bit ()) {
1229+ return SDValue ();
1230+ }
1231+
1232+ SDValue N0 = N->getOperand (0 );
1233+ EVT VT = N->getValueType (0 );
1234+
1235+ // Pattern match XOR.
1236+ // $dst = sign_extend (xor (trunc $src, i32), imm)
1237+ // => $dst = xor (signext_inreg $src, i32), imm
1238+ if (N0.getOpcode () == ISD::XOR &&
1239+ N0.getOperand (0 ).getOpcode () == ISD::TRUNCATE &&
1240+ N0.getOperand (1 ).getOpcode () == ISD::Constant) {
1241+ SDValue TruncateSource = N0.getOperand (0 ).getOperand (0 );
1242+ auto *ConstantOperand = dyn_cast<ConstantSDNode>(N0->getOperand (1 ));
1243+
1244+ SDValue FirstOperand =
1245+ DAG.getNode (ISD::SIGN_EXTEND_INREG, SDLoc (N0), VT, TruncateSource,
1246+ DAG.getValueType (N0.getOperand (0 ).getValueType ()));
1247+
1248+ int64_t ConstImm = ConstantOperand->getSExtValue ();
1249+ return DAG.getNode (ISD::XOR, SDLoc (N0), VT, FirstOperand,
1250+ DAG.getConstant (ConstImm, SDLoc (N0), VT));
1251+ }
1252+
1253+ return SDValue ();
1254+ }
1255+
12241256SDValue MipsTargetLowering::PerformDAGCombine (SDNode *N, DAGCombinerInfo &DCI)
12251257 const {
12261258 SelectionDAG &DAG = DCI.DAG ;
@@ -1246,6 +1278,8 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
12461278 return performSHLCombine (N, DAG, DCI, Subtarget);
12471279 case ISD::SUB:
12481280 return performSUBCombine (N, DAG, DCI, Subtarget);
1281+ case ISD::SIGN_EXTEND:
1282+ return performSignExtendCombine (N, DAG, DCI, Subtarget);
12491283 }
12501284
12511285 return SDValue ();
0 commit comments