Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -345,6 +345,7 @@ // Check if an addition can be broken to a pair of ADDI. def AddiPair : ComplexPattern; +def Addi32Pair : ComplexPattern; // Return imm/2. def AddiPairImmA : SDNodeXForm; +def add_oneuse : PatFrag<(ops node:$A, node:$B), (add node:$A, node:$B), [{ + return N->hasOneUse(); +}]>; + /// Simple arithmetic operations def : PatGprGpr; @@ -1299,6 +1304,12 @@ (ADDI (ADDI GPR:$rs1, (AddiPairImmB GPR:$rs2)), (AddiPairImmA GPR:$rs2))>; +let Predicates = [IsRV64] in { +def : Pat<(sext_inreg (add_oneuse GPR:$rs1, (Addi32Pair GPR:$rs2)), i32), + (ADDIW (ADDIW GPR:$rs1, (AddiPairImmB GPR:$rs2)), + (AddiPairImmA GPR:$rs2))>; +} + //===----------------------------------------------------------------------===// // Standard extensions //===----------------------------------------------------------------------===// Index: llvm/test/CodeGen/RISCV/add-imm.ll =================================================================== --- llvm/test/CodeGen/RISCV/add-imm.ll +++ llvm/test/CodeGen/RISCV/add-imm.ll @@ -159,14 +159,37 @@ ; ; RV64I-LABEL: add32_sext_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a1, 1 -; RV64I-NEXT: addiw a1, a1, -1097 -; RV64I-NEXT: addw a0, a0, a1 +; RV64I-NEXT: addiw a0, a0, 1500 +; RV64I-NEXT: addiw a0, a0, 1499 ; RV64I-NEXT: ret %1 = add i32 %a, 2999 ret i32 %1 } +@gv0 = global i32 0, align 4 +define signext i32 @add32_sext_reject_on_rv64(i32 signext %a) nounwind { +; RV32I-LABEL: add32_sext_reject_on_rv64: +; RV32I: # %bb.0: +; RV32I-NEXT: addi a0, a0, 1500 +; RV32I-NEXT: addi a0, a0, 1500 +; RV32I-NEXT: lui a1, %hi(gv0) +; RV32I-NEXT: sw a0, %lo(gv0)(a1) +; RV32I-NEXT: ret +; +; RV64I-LABEL: add32_sext_reject_on_rv64: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 1 +; RV64I-NEXT: addiw a1, a1, -1096 +; RV64I-NEXT: add a2, a0, a1 +; RV64I-NEXT: lui a3, %hi(gv0) +; RV64I-NEXT: addw a0, a0, a1 +; RV64I-NEXT: sw a2, %lo(gv0)(a3) +; RV64I-NEXT: ret + %b = add nsw i32 %a, 3000 + store i32 %b, i32* @gv0, align 4 + ret i32 %b +} + define i64 @add64_accept(i64 %a) nounwind { ; RV32I-LABEL: add64_accept: ; RV32I: # %bb.0: