diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4605,10 +4605,16 @@ if (C->isOpaque()) break; LLVM_FALLTHROUGH; - case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT, C->isTargetOpcode(), C->isOpaque()); + case ISD::ANY_EXTEND: + // Some targets like RISCV prefer to sign extend some types. + if (TLI->isSExtCheaperThanZExt(Operand.getValueType(), VT)) + return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), DL, VT, + C->isTargetOpcode(), C->isOpaque()); + return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), DL, VT, + C->isTargetOpcode(), C->isOpaque()); case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: { APFloat apf(EVTToAPFloatSemantics(VT), 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 @@ -4732,12 +4732,11 @@ // SLLW/DIVUW/.../*W later one because the fact the operation was originally of // type i8/i16/i32 is lost. static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, - unsigned ExtOpc0 = ISD::ANY_EXTEND, - unsigned ExtOpc1 = ISD::ANY_EXTEND) { + unsigned ExtOpc = ISD::ANY_EXTEND) { SDLoc DL(N); RISCVISD::NodeType WOpcode = getRISCVWOpcode(N->getOpcode()); - SDValue NewOp0 = DAG.getNode(ExtOpc0, DL, MVT::i64, N->getOperand(0)); - SDValue NewOp1 = DAG.getNode(ExtOpc1, DL, MVT::i64, N->getOperand(1)); + SDValue NewOp0 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(0)); + SDValue NewOp1 = DAG.getNode(ExtOpc, DL, MVT::i64, N->getOperand(1)); 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); @@ -4902,17 +4901,12 @@ // If the input is i32, use ANY_EXTEND since the W instructions don't read // the upper 32 bits. For other types we need to sign or zero extend // based on the opcode. - unsigned ExtOpc0 = ISD::ANY_EXTEND, ExtOpc1 = ISD::ANY_EXTEND; - if (VT != MVT::i32) { - ExtOpc0 = N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND - : ISD::ZERO_EXTEND; - ExtOpc1 = ExtOpc0; - } else if (N->getOperand(0).getOpcode() == ISD::Constant) { - // Sign extend i32 constants to improve materialization. - ExtOpc0 = ISD::SIGN_EXTEND; - } + unsigned ExtOpc = ISD::ANY_EXTEND; + if (VT != MVT::i32) + ExtOpc = N->getOpcode() == ISD::SDIV ? ISD::SIGN_EXTEND + : ISD::ZERO_EXTEND; - Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc0, ExtOpc1)); + Results.push_back(customLegalizeToWOp(N, DAG, ExtOpc)); break; } case ISD::UADDO: 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,35 +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, -2 -; RV64IB-NEXT: zext.w a1, a1 ; 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) @@ -358,35 +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, -2 -; RV64IB-NEXT: zext.w a1, a1 ; 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,12 +417,10 @@ ; ; RV64ZBA-LABEL: uaddo.i32.constant: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, zero, -2 -; RV64ZBA-NEXT: zext.w a3, a2 -; 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 @@ -685,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 @@ -705,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 @@ -735,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 @@ -757,8 +744,7 @@ ; ; RV64ZBA-LABEL: usubo.i32.constant.lhs: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, zero, -2 -; RV64ZBA-NEXT: zext.w a3, a2 +; RV64ZBA-NEXT: addi a3, zero, -2 ; RV64ZBA-NEXT: subw a2, a3, a0 ; RV64ZBA-NEXT: addi a2, a2, 1 ; RV64ZBA-NEXT: seqz a2, a2