diff options
author | hev <wangrui@loongson.cn> | 2024-06-03 13:23:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-03 13:23:35 +0800 |
commit | 718331f55529469586c99a55e4b382a1c7485842 (patch) | |
tree | d9d1ad52695ecd24aa6610992d2dde9544acfa85 /llvm/lib/Target/LoongArch | |
parent | e12bf36d237f8ef16c25c266785f6d01fb50dbc1 (diff) | |
download | llvm-718331f55529469586c99a55e4b382a1c7485842.zip llvm-718331f55529469586c99a55e4b382a1c7485842.tar.gz llvm-718331f55529469586c99a55e4b382a1c7485842.tar.bz2 |
[LoongArch] Custom legalize i32 operations for LA64 to reduce signed extensions (#93811)
Diffstat (limited to 'llvm/lib/Target/LoongArch')
-rw-r--r-- | llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 5 |
2 files changed, 21 insertions, 4 deletions
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 8a87c82..51384f2 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -121,6 +121,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, // Set operations for LA64 only. if (Subtarget.is64Bit()) { + setOperationAction(ISD::ADD, MVT::i32, Custom); + setOperationAction(ISD::SUB, MVT::i32, Custom); setOperationAction(ISD::SHL, MVT::i32, Custom); setOperationAction(ISD::SRA, MVT::i32, Custom); setOperationAction(ISD::SRL, MVT::i32, Custom); @@ -1723,6 +1725,18 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp, return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes); } +// Converts the given 32-bit operation to a i64 operation with signed extension +// semantic to reduce the signed extension instructions. +static SDValue customLegalizeToWOpWithSExt(SDNode *N, SelectionDAG &DAG) { + SDLoc DL(N); + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0)); + SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1)); + SDValue NewWOp = DAG.getNode(N->getOpcode(), DL, MVT::i64, NewOp0, NewOp1); + SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, NewWOp, + DAG.getValueType(MVT::i32)); + return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes); +} + // Helper function that emits error message for intrinsics with/without chain // and return a UNDEF or and the chain as the results. static void emitErrorAndReplaceIntrinsicResults( @@ -1846,6 +1860,12 @@ void LoongArchTargetLowering::ReplaceNodeResults( switch (N->getOpcode()) { default: llvm_unreachable("Don't know how to legalize this operation"); + case ISD::ADD: + case ISD::SUB: + assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && + "Unexpected custom legalisation"); + Results.push_back(customLegalizeToWOpWithSExt(N, DAG)); + break; case ISD::UDIV: case ISD::UREM: assert(VT == MVT::i32 && Subtarget.is64Bit() && diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 35ea9f0..66bd74e 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -441,7 +441,7 @@ def simm16_lsl16 : Operand<GRLenVT>, // A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for // use in additions. def simm32_hi16_lo12: Operand<GRLenVT>, ImmLeaf<GRLenVT, [{ - return isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm)); + return !isInt<12>(Imm) && isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm)); }]>; def BareSymbol : AsmOperandClass { @@ -1106,11 +1106,8 @@ foreach Idx = 1...3 in { let Predicates = [IsLA64] in { def : PatGprGpr<add, ADD_D>; -def : PatGprGpr_32<add, ADD_W>; def : PatGprImm<add, ADDI_D, simm12>; -def : PatGprImm_32<add, ADDI_W, simm12>; def : PatGprGpr<sub, SUB_D>; -def : PatGprGpr_32<sub, SUB_W>; def : PatGprGpr<sdiv, DIV_D>; def : PatGprGpr_32<sdiv, DIV_W>; def : PatGprGpr<udiv, DIV_DU>; |