@@ -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,43 @@ 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), i64)
1237+ // => $dst = (xor (signext_inreg $src, i32), imm as i64)
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+ // Remove the unnecessary truncate + signext, and perform the operation
1245+ // using the initial sign-extended i64 values, with the constant also sign
1246+ // extended to i64. Note: ConstImm is either passed as a 32-bit immediate to
1247+ // xori, or gets "assembled" to anoter register and a xor is emitted, if
1248+ // ConstImm can't fit in 32 bits.
1249+ if (VT == MVT::i64 && VT == TruncateSource.getValueType ()) {
1250+ SDValue FirstOperand =
1251+ DAG.getNode (ISD::SIGN_EXTEND_INREG, SDLoc (N0), VT, TruncateSource,
1252+ DAG.getValueType (MVT::i32 ));
1253+ APInt ConstImm (64 , ConstantOperand->getSExtValue (), true );
1254+ return DAG.getNode (ISD::XOR, SDLoc (N0), VT, FirstOperand,
1255+ DAG.getConstant (ConstImm, SDLoc (N0), VT));
1256+ }
1257+ }
1258+
1259+ return SDValue ();
1260+ }
1261+
12241262SDValue MipsTargetLowering::PerformDAGCombine (SDNode *N, DAGCombinerInfo &DCI)
12251263 const {
12261264 SelectionDAG &DAG = DCI.DAG ;
@@ -1246,6 +1284,8 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
12461284 return performSHLCombine (N, DAG, DCI, Subtarget);
12471285 case ISD::SUB:
12481286 return performSUBCombine (N, DAG, DCI, Subtarget);
1287+ case ISD::SIGN_EXTEND:
1288+ return performSignExtendCombine (N, DAG, DCI, Subtarget);
12491289 }
12501290
12511291 return SDValue ();
0 commit comments