Skip to content

Commit 7e8a482

Browse files
committed
[MIPS]Optimize ((signext (xor (trunc X), imm)) to (xor (X, imm")
Fix llvm#99783
1 parent f322f4a commit 7e8a482

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
519519
setOperationAction(ISD::TRAP, MVT::Other, Legal);
520520

521521
setTargetDAGCombine({ISD::SDIVREM, ISD::UDIVREM, ISD::SELECT, ISD::AND,
522-
ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL});
522+
ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext,
523+
ISD::SHL, ISD::SIGN_EXTEND});
523524

524525
if (Subtarget.isGP64bit())
525526
setMaxAtomicSizeInBitsSupported(64);
@@ -1213,6 +1214,23 @@ static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
12131214
DAG.getConstant(SMSize, DL, MVT::i32));
12141215
}
12151216

1217+
static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG,
1218+
TargetLowering::DAGCombinerInfo &DCI,
1219+
const MipsSubtarget &Subtarget) {
1220+
SDValue N0 = N->getOperand(0);
1221+
EVT VT = N->getValueType(0);
1222+
1223+
// For MIPS64, xor instruction can use with 64 bit arithmetic.
1224+
// (sext (xor (trunc X), imm)) => (xor (X, imm"))
1225+
if (N0.getOpcode() == ISD::XOR &&
1226+
N0.getOperand(0).getOpcode() == ISD::TRUNCATE &&
1227+
N0.getOperand(1).getOpcode() == ISD::Constant) {
1228+
SDValue X0 = N0.getOperand(0).getOperand(0);
1229+
return DAG.getNode(ISD::XOR, SDLoc(N0), VT, X0,
1230+
DAG.getTargetConstant(-1, SDLoc(N0), VT));
1231+
}
1232+
}
1233+
12161234
SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
12171235
const {
12181236
SelectionDAG &DAG = DCI.DAG;
@@ -1238,6 +1256,8 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
12381256
return performSHLCombine(N, DAG, DCI, Subtarget);
12391257
case ISD::SUB:
12401258
return performSUBCombine(N, DAG, DCI, Subtarget);
1259+
case ISD::SIGN_EXTEND:
1260+
return performSignExtendCombine(N, DAG, DCI, Subtarget);
12411261
}
12421262

12431263
return SDValue();

llvm/test/CodeGen/Mips/xor-and.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
; RUN: llc -O3 -mcpu=mips64r6 -mtriple=mips64el-unknown-linux-gnuabi64 < %s -o - | FileCheck %s
22

3-
; This test shows the unoptimized result with unnecessary SLLs.
43
define noundef signext i32 @xor_and(i32 noundef signext %a, i32 noundef signext %b) local_unnamed_addr {
54
; CHECK-LABEL: xor_and:
65
; CHECK: # %bb.0: # %entry
76
; CHECK-NEXT: and $1, $5, $4
8-
; CHECK-NEXT: sll $1, $1, 0
9-
; CHECK-NEXT: not $1, $1
107
; CHECK-NEXT: jr $ra
11-
; CHECK-NEXT: sll $2, $1, 0
8+
; CHECK-NEXT: xor $2, $1, -1
129

1310
entry:
1411
%0 = and i32 %b, %a

0 commit comments

Comments
 (0)