Skip to content

Commit 3b122b9

Browse files
committed
[MIPS]Optimize ((signext (xor (trunc X, i32), imm)) to (xor (signext_inreg X, i32), imm)
The constant operand of the XOR is an i32, which makes the two operands being truncated to i32, and sign extended to i64 afterwards. Since both of the i32 operands are sign extended to i64 before performing the TRUNCATE operation, we just remove the unnecessary TRUNCATE and SIGN_EXTEND. Fix #99783
1 parent a129ca7 commit 3b122b9

File tree

4 files changed

+310
-164
lines changed

4 files changed

+310
-164
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
if (VT == MVT::i64 && VT == TruncateSource.getValueType()) {
1244+
SDValue FirstOperand =
1245+
DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N0), VT, TruncateSource,
1246+
DAG.getValueType(MVT::i32));
1247+
int64_t ConstImm = ConstantOperand->getSExtValue();
1248+
return DAG.getNode(ISD::XOR, SDLoc(N0), VT, FirstOperand,
1249+
DAG.getConstant(ConstImm, SDLoc(N0), VT));
1250+
}
1251+
}
1252+
1253+
return SDValue();
1254+
}
1255+
12241256
SDValue 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

Comments
 (0)