diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -419,7 +419,9 @@ }]>; // Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), -// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. +// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0 +// as large as possible and imm1 as small as possible so that we might be able +// to use c.addi for the small immediate. def AddiPair : PatLeaf<(imm), [{ if (!N->hasOneUse()) return false; @@ -428,16 +430,19 @@ return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); }]>; -// Return imm/2. -def AddiPairImmA : SDNodeXFormgetTargetConstant(N->getSExtValue() / 2, SDLoc(N), +// Return imm - (imm < 0 ? -2048 : 2047). +def AddiPairImmSmall : SDNodeXFormgetSExtValue(); + int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047; + return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N), N->getValueType(0)); }]>; -// Return imm - imm/2. -def AddiPairImmB : SDNodeXFormgetSExtValue(); - return CurDAG->getTargetConstant(Imm - Imm / 2, SDLoc(N), +// Return -2048 if immediate is negative or 2047 if positive. These are the +// largest simm12 values. +def AddiPairImmLarge : SDNodeXFormgetSExtValue() < 0 ? -2048 : 2047; + return CurDAG->getTargetConstant(Imm, SDLoc(N), N->getValueType(0)); }]>; @@ -1651,14 +1656,14 @@ /// Simple optimization def : Pat<(add GPR:$rs1, (AddiPair:$rs2)), - (ADDI (ADDI GPR:$rs1, (AddiPairImmB AddiPair:$rs2)), - (AddiPairImmA GPR:$rs2))>; + (ADDI (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)), + (AddiPairImmSmall GPR:$rs2))>; let Predicates = [IsRV64] in { // Select W instructions if only the lower 32-bits of the result are used. def : Pat<(binop_allwusers GPR:$rs1, (AddiPair:$rs2)), - (ADDIW (ADDIW GPR:$rs1, (AddiPairImmB AddiPair:$rs2)), - (AddiPairImmA AddiPair:$rs2))>; + (ADDIW (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)), + (AddiPairImmSmall AddiPair:$rs2))>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/RISCV/add-imm.ll b/llvm/test/CodeGen/RISCV/add-imm.ll --- a/llvm/test/CodeGen/RISCV/add-imm.ll +++ b/llvm/test/CodeGen/RISCV/add-imm.ll @@ -23,14 +23,14 @@ define i32 @add_positive_low_bound_accept(i32 %a) nounwind { ; RV32I-LABEL: add_positive_low_bound_accept: ; RV32I: # %bb.0: -; RV32I-NEXT: addi a0, a0, 1024 -; RV32I-NEXT: addi a0, a0, 1024 +; RV32I-NEXT: addi a0, a0, 2047 +; RV32I-NEXT: addi a0, a0, 1 ; RV32I-NEXT: ret ; ; RV64I-LABEL: add_positive_low_bound_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: addiw a0, a0, 1024 -; RV64I-NEXT: addiw a0, a0, 1024 +; RV64I-NEXT: addiw a0, a0, 2047 +; RV64I-NEXT: addiw a0, a0, 1 ; RV64I-NEXT: ret %1 = add i32 %a, 2048 ret i32 %1 @@ -87,14 +87,14 @@ define i32 @add_negative_high_bound_accept(i32 %a) nounwind { ; RV32I-LABEL: add_negative_high_bound_accept: ; RV32I: # %bb.0: -; RV32I-NEXT: addi a0, a0, -1025 -; RV32I-NEXT: addi a0, a0, -1024 +; RV32I-NEXT: addi a0, a0, -2048 +; RV32I-NEXT: addi a0, a0, -1 ; RV32I-NEXT: ret ; ; RV64I-LABEL: add_negative_high_bound_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: addiw a0, a0, -1025 -; RV64I-NEXT: addiw a0, a0, -1024 +; RV64I-NEXT: addiw a0, a0, -2048 +; RV64I-NEXT: addiw a0, a0, -1 ; RV64I-NEXT: ret %1 = add i32 %a, -2049 ret i32 %1 @@ -137,14 +137,14 @@ define i32 @add32_accept(i32 %a) nounwind { ; RV32I-LABEL: add32_accept: ; RV32I: # %bb.0: -; RV32I-NEXT: addi a0, a0, 1500 -; RV32I-NEXT: addi a0, a0, 1499 +; RV32I-NEXT: addi a0, a0, 2047 +; RV32I-NEXT: addi a0, a0, 952 ; RV32I-NEXT: ret ; ; RV64I-LABEL: add32_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: addiw a0, a0, 1500 -; RV64I-NEXT: addiw a0, a0, 1499 +; RV64I-NEXT: addiw a0, a0, 2047 +; RV64I-NEXT: addiw a0, a0, 952 ; RV64I-NEXT: ret %1 = add i32 %a, 2999 ret i32 %1 @@ -153,14 +153,14 @@ define signext i32 @add32_sext_accept(i32 signext %a) nounwind { ; RV32I-LABEL: add32_sext_accept: ; RV32I: # %bb.0: -; RV32I-NEXT: addi a0, a0, 1500 -; RV32I-NEXT: addi a0, a0, 1499 +; RV32I-NEXT: addi a0, a0, 2047 +; RV32I-NEXT: addi a0, a0, 952 ; RV32I-NEXT: ret ; ; RV64I-LABEL: add32_sext_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: addiw a0, a0, 1500 -; RV64I-NEXT: addiw a0, a0, 1499 +; RV64I-NEXT: addiw a0, a0, 2047 +; RV64I-NEXT: addiw a0, a0, 952 ; RV64I-NEXT: ret %1 = add i32 %a, 2999 ret i32 %1 @@ -170,16 +170,16 @@ 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: addi a0, a0, 2047 +; RV32I-NEXT: addi a0, a0, 953 ; 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: addiw a0, a0, 1500 -; RV64I-NEXT: addiw a0, a0, 1500 +; RV64I-NEXT: addiw a0, a0, 2047 +; RV64I-NEXT: addiw a0, a0, 953 ; RV64I-NEXT: lui a1, %hi(gv0) ; RV64I-NEXT: sw a0, %lo(gv0)(a1) ; RV64I-NEXT: ret @@ -191,8 +191,8 @@ define i64 @add64_accept(i64 %a) nounwind { ; RV32I-LABEL: add64_accept: ; RV32I: # %bb.0: -; RV32I-NEXT: addi a2, a0, 1500 -; RV32I-NEXT: addi a2, a2, 1499 +; RV32I-NEXT: addi a2, a0, 2047 +; RV32I-NEXT: addi a2, a2, 952 ; RV32I-NEXT: sltu a0, a2, a0 ; RV32I-NEXT: add a1, a1, a0 ; RV32I-NEXT: mv a0, a2 @@ -200,8 +200,8 @@ ; ; RV64I-LABEL: add64_accept: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a0, a0, 1500 -; RV64I-NEXT: addi a0, a0, 1499 +; RV64I-NEXT: addi a0, a0, 2047 +; RV64I-NEXT: addi a0, a0, 952 ; RV64I-NEXT: ret %1 = add i64 %a, 2999 ret i64 %1 diff --git a/llvm/test/CodeGen/RISCV/addimm-mulimm.ll b/llvm/test/CodeGen/RISCV/addimm-mulimm.ll --- a/llvm/test/CodeGen/RISCV/addimm-mulimm.ll +++ b/llvm/test/CodeGen/RISCV/addimm-mulimm.ll @@ -551,8 +551,8 @@ ; RV32IMB-NEXT: sh3add a1, a1, a2 ; RV32IMB-NEXT: sh1add a0, a0, a0 ; RV32IMB-NEXT: slli a2, a0, 3 -; RV32IMB-NEXT: addi a0, a2, 1024 -; RV32IMB-NEXT: addi a0, a0, 1024 +; RV32IMB-NEXT: addi a0, a2, 2047 +; RV32IMB-NEXT: addi a0, a0, 1 ; RV32IMB-NEXT: sltu a2, a0, a2 ; RV32IMB-NEXT: add a1, a1, a2 ; RV32IMB-NEXT: ret 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 @@ -4094,8 +4094,8 @@ ; RV32-LABEL: uaddo.i64.constant_2048: ; RV32: # %bb.0: # %entry ; RV32-NEXT: mv a3, a0 -; RV32-NEXT: addi a0, a0, 1024 -; RV32-NEXT: addi a4, a0, 1024 +; RV32-NEXT: addi a0, a0, 2047 +; RV32-NEXT: addi a4, a0, 1 ; RV32-NEXT: sltu a0, a4, a3 ; RV32-NEXT: add a5, a1, a0 ; RV32-NEXT: bgeu a4, a3, .LBB67_2 @@ -4108,8 +4108,8 @@ ; ; RV64-LABEL: uaddo.i64.constant_2048: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addi a2, a0, 1024 -; RV64-NEXT: addi a2, a2, 1024 +; RV64-NEXT: addi a2, a0, 2047 +; RV64-NEXT: addi a2, a2, 1 ; RV64-NEXT: sltu a0, a2, a0 ; RV64-NEXT: sd a2, 0(a1) ; RV64-NEXT: ret @@ -4117,8 +4117,8 @@ ; RV32ZBA-LABEL: uaddo.i64.constant_2048: ; RV32ZBA: # %bb.0: # %entry ; RV32ZBA-NEXT: mv a3, a0 -; RV32ZBA-NEXT: addi a0, a0, 1024 -; RV32ZBA-NEXT: addi a4, a0, 1024 +; RV32ZBA-NEXT: addi a0, a0, 2047 +; RV32ZBA-NEXT: addi a4, a0, 1 ; RV32ZBA-NEXT: sltu a0, a4, a3 ; RV32ZBA-NEXT: add a5, a1, a0 ; RV32ZBA-NEXT: bgeu a4, a3, .LBB67_2 @@ -4131,8 +4131,8 @@ ; ; RV64ZBA-LABEL: uaddo.i64.constant_2048: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, a0, 1024 -; RV64ZBA-NEXT: addi a2, a2, 1024 +; RV64ZBA-NEXT: addi a2, a0, 2047 +; RV64ZBA-NEXT: addi a2, a2, 1 ; RV64ZBA-NEXT: sltu a0, a2, a0 ; RV64ZBA-NEXT: sd a2, 0(a1) ; RV64ZBA-NEXT: ret @@ -4148,8 +4148,8 @@ ; RV32-LABEL: uaddo.i64.constant_2049: ; RV32: # %bb.0: # %entry ; RV32-NEXT: mv a3, a0 -; RV32-NEXT: addi a0, a0, 1025 -; RV32-NEXT: addi a4, a0, 1024 +; RV32-NEXT: addi a0, a0, 2047 +; RV32-NEXT: addi a4, a0, 2 ; RV32-NEXT: sltu a0, a4, a3 ; RV32-NEXT: add a5, a1, a0 ; RV32-NEXT: bgeu a4, a3, .LBB68_2 @@ -4162,8 +4162,8 @@ ; ; RV64-LABEL: uaddo.i64.constant_2049: ; RV64: # %bb.0: # %entry -; RV64-NEXT: addi a2, a0, 1025 -; RV64-NEXT: addi a2, a2, 1024 +; RV64-NEXT: addi a2, a0, 2047 +; RV64-NEXT: addi a2, a2, 2 ; RV64-NEXT: sltu a0, a2, a0 ; RV64-NEXT: sd a2, 0(a1) ; RV64-NEXT: ret @@ -4171,8 +4171,8 @@ ; RV32ZBA-LABEL: uaddo.i64.constant_2049: ; RV32ZBA: # %bb.0: # %entry ; RV32ZBA-NEXT: mv a3, a0 -; RV32ZBA-NEXT: addi a0, a0, 1025 -; RV32ZBA-NEXT: addi a4, a0, 1024 +; RV32ZBA-NEXT: addi a0, a0, 2047 +; RV32ZBA-NEXT: addi a4, a0, 2 ; RV32ZBA-NEXT: sltu a0, a4, a3 ; RV32ZBA-NEXT: add a5, a1, a0 ; RV32ZBA-NEXT: bgeu a4, a3, .LBB68_2 @@ -4185,8 +4185,8 @@ ; ; RV64ZBA-LABEL: uaddo.i64.constant_2049: ; RV64ZBA: # %bb.0: # %entry -; RV64ZBA-NEXT: addi a2, a0, 1025 -; RV64ZBA-NEXT: addi a2, a2, 1024 +; RV64ZBA-NEXT: addi a2, a0, 2047 +; RV64ZBA-NEXT: addi a2, a2, 2 ; RV64ZBA-NEXT: sltu a0, a2, a0 ; RV64ZBA-NEXT: sd a2, 0(a1) ; RV64ZBA-NEXT: ret