diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4705,6 +4705,16 @@ } } +// Helper function to use sign extension instead of zero extension for +// any_extend of i32 constants to improve constant materialization. +static SDValue extendValue(unsigned ExtOpc, const SDLoc &DL, EVT VT, SDValue V, + SelectionDAG &DAG) { + if (ExtOpc == ISD::ANY_EXTEND && V.getValueType() == MVT::i32 && + isa(V)) + ExtOpc = ISD::SIGN_EXTEND; + return DAG.getNode(ExtOpc, DL, VT, V); +} + // Converts the given 32-bit operation to a target-specific SelectionDAG node. // Because i32 isn't a legal type for RV64, these operations would otherwise // be promoted to i64, making it difficult to select the SLLW/DIVUW/.../*W @@ -4714,8 +4724,8 @@ unsigned ExtOpc = ISD::ANY_EXTEND) { SDLoc DL(N); RISCVISD::NodeType WOpcode = getRISCVWOpcode(N->getOpcode()); - SDValue NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0)); - SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1)); + SDValue NewOp0 = extendValue(ExtOpc, DL, MVT::i64, N->getOperand(0), DAG); + SDValue NewOp1 = extendValue(ExtOpc, DL, MVT::i64, N->getOperand(1), DAG); SDValue NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1); // ReplaceNodeResults requires we maintain the same type for the return value. return DAG.getNode(ISD::TRUNCATE, DL, N->getValueType(0), NewRes); @@ -4725,8 +4735,10 @@ // 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 NewOp0 = + extendValue(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0), DAG); + SDValue NewOp1 = + extendValue(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1), DAG); 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)); @@ -4892,8 +4904,10 @@ "Unexpected custom legalisation"); bool IsAdd = N->getOpcode() == ISD::UADDO; // Create an ADDW or SUBW. - SDValue LHS = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0)); - SDValue RHS = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1)); + SDValue LHS = + extendValue(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0), DAG); + SDValue RHS = + extendValue(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1), DAG); SDValue Res = DAG.getNode(IsAdd ? ISD::ADD : ISD::SUB, DL, MVT::i64, LHS, RHS); Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, Res, diff --git a/llvm/test/CodeGen/RISCV/alu32.ll b/llvm/test/CodeGen/RISCV/alu32.ll --- a/llvm/test/CodeGen/RISCV/alu32.ll +++ b/llvm/test/CodeGen/RISCV/alu32.ll @@ -198,9 +198,7 @@ ; ; RV64I-LABEL: sub_negative_constant_lhs: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a1, zero, 1 -; RV64I-NEXT: slli a1, a1, 32 -; RV64I-NEXT: addi a1, a1, -2 +; RV64I-NEXT: addi a1, zero, -2 ; RV64I-NEXT: subw a0, a1, a0 ; RV64I-NEXT: ret %1 = sub i32 -2, %a @@ -231,7 +229,6 @@ ; RV64I-LABEL: sll_negative_constant_lhs: ; RV64I: # %bb.0: ; RV64I-NEXT: addi a1, zero, -1 -; RV64I-NEXT: srli a1, a1, 32 ; RV64I-NEXT: sllw a0, a1, a0 ; RV64I-NEXT: ret %1 = shl i32 -1, %a @@ -310,7 +307,6 @@ ; RV64I-LABEL: srl_negative_constant_lhs: ; RV64I: # %bb.0: ; RV64I-NEXT: addi a1, zero, -1 -; RV64I-NEXT: srli a1, a1, 32 ; RV64I-NEXT: srlw a0, a1, a0 ; RV64I-NEXT: ret %1 = lshr i32 -1, %a @@ -340,8 +336,7 @@ ; ; RV64I-LABEL: sra_negative_constant_lhs: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a1, zero, 1 -; RV64I-NEXT: slli a1, a1, 31 +; RV64I-NEXT: lui a1, 524288 ; RV64I-NEXT: sraw a0, a1, a0 ; RV64I-NEXT: ret %1 = ashr i32 2147483648, %a diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll --- a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll @@ -229,36 +229,28 @@ define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind { ; RV64I-LABEL: rol_i32_neg_constant_rhs: ; RV64I: # %bb.0: -; RV64I-NEXT: neg a1, a0 -; RV64I-NEXT: addi a2, zero, 1 -; RV64I-NEXT: slli a2, a2, 32 -; RV64I-NEXT: addi a2, a2, -2 -; RV64I-NEXT: srlw a1, a2, a1 -; RV64I-NEXT: sllw a0, a2, a0 -; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: addi a1, zero, -2 +; RV64I-NEXT: sllw a2, a1, a0 +; RV64I-NEXT: neg a0, a0 +; RV64I-NEXT: srlw a0, a1, a0 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64IB-LABEL: rol_i32_neg_constant_rhs: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a1, zero, 1 -; RV64IB-NEXT: slli a1, a1, 32 -; RV64IB-NEXT: addi a1, a1, -2 +; RV64IB-NEXT: addi a1, zero, -2 ; RV64IB-NEXT: rolw a0, a1, a0 ; RV64IB-NEXT: ret ; ; RV64IBB-LABEL: rol_i32_neg_constant_rhs: ; RV64IBB: # %bb.0: -; RV64IBB-NEXT: addi a1, zero, 1 -; RV64IBB-NEXT: slli a1, a1, 32 -; RV64IBB-NEXT: addi a1, a1, -2 +; RV64IBB-NEXT: addi a1, zero, -2 ; RV64IBB-NEXT: rolw a0, a1, a0 ; RV64IBB-NEXT: ret ; ; RV64IBP-LABEL: rol_i32_neg_constant_rhs: ; RV64IBP: # %bb.0: -; RV64IBP-NEXT: addi a1, zero, 1 -; RV64IBP-NEXT: slli a1, a1, 32 -; RV64IBP-NEXT: addi a1, a1, -2 +; RV64IBP-NEXT: addi a1, zero, -2 ; RV64IBP-NEXT: rolw a0, a1, a0 ; RV64IBP-NEXT: ret %1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a) @@ -359,36 +351,28 @@ define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind { ; RV64I-LABEL: ror_i32_neg_constant_rhs: ; RV64I: # %bb.0: -; RV64I-NEXT: neg a1, a0 -; RV64I-NEXT: addi a2, zero, 1 -; RV64I-NEXT: slli a2, a2, 32 -; RV64I-NEXT: addi a2, a2, -2 -; RV64I-NEXT: sllw a1, a2, a1 -; RV64I-NEXT: srlw a0, a2, a0 -; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: addi a1, zero, -2 +; RV64I-NEXT: srlw a2, a1, a0 +; RV64I-NEXT: neg a0, a0 +; RV64I-NEXT: sllw a0, a1, a0 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64IB-LABEL: ror_i32_neg_constant_rhs: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a1, zero, 1 -; RV64IB-NEXT: slli a1, a1, 32 -; RV64IB-NEXT: addi a1, a1, -2 +; RV64IB-NEXT: addi a1, zero, -2 ; RV64IB-NEXT: rorw a0, a1, a0 ; RV64IB-NEXT: ret ; ; RV64IBB-LABEL: ror_i32_neg_constant_rhs: ; RV64IBB: # %bb.0: -; RV64IBB-NEXT: addi a1, zero, 1 -; RV64IBB-NEXT: slli a1, a1, 32 -; RV64IBB-NEXT: addi a1, a1, -2 +; RV64IBB-NEXT: addi a1, zero, -2 ; RV64IBB-NEXT: rorw a0, a1, a0 ; RV64IBB-NEXT: ret ; ; RV64IBP-LABEL: ror_i32_neg_constant_rhs: ; RV64IBP: # %bb.0: -; RV64IBP-NEXT: addi a1, zero, 1 -; RV64IBP-NEXT: slli a1, a1, 32 -; RV64IBP-NEXT: addi a1, a1, -2 +; RV64IBP-NEXT: addi a1, zero, -2 ; RV64IBP-NEXT: rorw a0, a1, a0 ; RV64IBP-NEXT: ret %1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a) diff --git a/llvm/test/CodeGen/RISCV/xaluo.ll b/llvm/test/CodeGen/RISCV/xaluo.ll --- a/llvm/test/CodeGen/RISCV/xaluo.ll +++ b/llvm/test/CodeGen/RISCV/xaluo.ll @@ -400,13 +400,10 @@ ; ; RV64-LABEL: uaddo.i32.constant: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addi a2, zero, 1 -; RV64-NEXT: slli a2, a2, 32 -; RV64-NEXT: addi a3, a2, -2 -; RV64-NEXT: addw a2, a0, a3 -; RV64-NEXT: sext.w a4, a0 -; RV64-NEXT: sltu a2, a2, a4 -; RV64-NEXT: add a0, a0, a3 +; RV64-NEXT: sext.w a2, a0 +; RV64-NEXT: addiw a3, a0, -2 +; RV64-NEXT: sltu a2, a3, a2 +; RV64-NEXT: addi a0, a0, -2 ; RV64-NEXT: sw a0, 0(a1) ; RV64-NEXT: mv a0, a2 ; RV64-NEXT: ret @@ -420,13 +417,10 @@ ; ; RV64ZBA-LABEL: uaddo.i32.constant: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, zero, 1 -; RV64ZBA-NEXT: slli a2, a2, 32 -; RV64ZBA-NEXT: addi a3, a2, -2 -; RV64ZBA-NEXT: addw a2, a0, a3 -; RV64ZBA-NEXT: sext.w a4, a0 -; RV64ZBA-NEXT: sltu a2, a2, a4 -; RV64ZBA-NEXT: add a0, a0, a3 +; RV64ZBA-NEXT: sext.w a2, a0 +; RV64ZBA-NEXT: addiw a3, a0, -2 +; RV64ZBA-NEXT: sltu a2, a3, a2 +; RV64ZBA-NEXT: addi a0, a0, -2 ; RV64ZBA-NEXT: sw a0, 0(a1) ; RV64ZBA-NEXT: mv a0, a2 ; RV64ZBA-NEXT: ret @@ -686,13 +680,10 @@ ; ; RV64-LABEL: usubo.i32.constant.rhs: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addi a2, zero, -1 -; RV64-NEXT: slli a2, a2, 32 -; RV64-NEXT: addi a3, a2, 2 -; RV64-NEXT: addw a2, a0, a3 -; RV64-NEXT: sext.w a4, a0 -; RV64-NEXT: sltu a2, a4, a2 -; RV64-NEXT: add a0, a0, a3 +; RV64-NEXT: addiw a2, a0, 2 +; RV64-NEXT: sext.w a3, a0 +; RV64-NEXT: sltu a2, a3, a2 +; RV64-NEXT: addi a0, a0, 2 ; RV64-NEXT: sw a0, 0(a1) ; RV64-NEXT: mv a0, a2 ; RV64-NEXT: ret @@ -706,13 +697,10 @@ ; ; RV64ZBA-LABEL: usubo.i32.constant.rhs: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, zero, -1 -; RV64ZBA-NEXT: slli a2, a2, 32 -; RV64ZBA-NEXT: addi a3, a2, 2 -; RV64ZBA-NEXT: addw a2, a0, a3 -; RV64ZBA-NEXT: sext.w a4, a0 -; RV64ZBA-NEXT: sltu a2, a4, a2 -; RV64ZBA-NEXT: add a0, a0, a3 +; RV64ZBA-NEXT: addiw a2, a0, 2 +; RV64ZBA-NEXT: sext.w a3, a0 +; RV64ZBA-NEXT: sltu a2, a3, a2 +; RV64ZBA-NEXT: addi a0, a0, 2 ; RV64ZBA-NEXT: sw a0, 0(a1) ; RV64ZBA-NEXT: mv a0, a2 ; RV64ZBA-NEXT: ret @@ -736,9 +724,7 @@ ; ; RV64-LABEL: usubo.i32.constant.lhs: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addi a2, zero, 1 -; RV64-NEXT: slli a2, a2, 32 -; RV64-NEXT: addi a3, a2, -2 +; RV64-NEXT: addi a3, zero, -2 ; RV64-NEXT: subw a2, a3, a0 ; RV64-NEXT: addi a2, a2, 1 ; RV64-NEXT: seqz a2, a2 @@ -758,9 +744,7 @@ ; ; RV64ZBA-LABEL: usubo.i32.constant.lhs: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, zero, 1 -; RV64ZBA-NEXT: slli a2, a2, 32 -; RV64ZBA-NEXT: addi a3, a2, -2 +; RV64ZBA-NEXT: addi a3, zero, -2 ; RV64ZBA-NEXT: subw a2, a3, a0 ; RV64ZBA-NEXT: addi a2, a2, 1 ; RV64ZBA-NEXT: seqz a2, a2