diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp index 6c5d0ad5b0927..dc00fdfc2146a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -257,10 +257,27 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) { assert(ActiveFeatures[RISCV::Feature64Bit] && "Expected RV32 to only need 2 instructions"); + // If the lower 13 bits are something like 0x17ff, try to add 1 to change the + // lower 13 bits to 0x1800. We can restore this with an ADDI of -1 at the end + // of the sequence. Call generateInstSeqImpl on the new constant which may + // subtract 0xfffffffffffff800 to create another ADDI. This will leave a + // constant with more than 12 trailing zeros for the next recursive step. + if ((Val & 0xfff) != 0 && (Val & 0x1800) == 0x1000) { + int64_t Imm12 = -(0x800 - (Val & 0xfff)); + int64_t AdjustedVal = Val - Imm12; + RISCVMatInt::InstSeq TmpSeq; + generateInstSeqImpl(AdjustedVal, ActiveFeatures, TmpSeq); + + // Keep the new sequence if it is an improvement. + if ((TmpSeq.size() + 1) < Res.size()) { + TmpSeq.emplace_back(RISCV::ADDI, Imm12); + Res = TmpSeq; + } + } + // If the constant is positive we might be able to generate a shifted constant // with no leading zeros and use a final SRLI to restore them. - if (Val > 0) { - assert(Res.size() > 2 && "Expected longer sequence"); + if (Val > 0 && Res.size() > 2) { generateInstSeqLeadingZeros(Val, ActiveFeatures, Res); } diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll index 307d19690bff0..ae66af7267975 100644 --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -1107,46 +1107,41 @@ define i64 @imm_end_2addi_1() nounwind { ; RV64I-LABEL: imm_end_2addi_1: ; RV64I: # %bb.0: ; RV64I-NEXT: li a0, -2047 -; RV64I-NEXT: slli a0, a0, 27 +; RV64I-NEXT: slli a0, a0, 39 +; RV64I-NEXT: addi a0, a0, -2048 ; RV64I-NEXT: addi a0, a0, -1 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, 2047 ; RV64I-NEXT: ret ; ; RV64IZBA-LABEL: imm_end_2addi_1: ; RV64IZBA: # %bb.0: ; RV64IZBA-NEXT: li a0, -2047 -; RV64IZBA-NEXT: slli a0, a0, 27 +; RV64IZBA-NEXT: slli a0, a0, 39 +; RV64IZBA-NEXT: addi a0, a0, -2048 ; RV64IZBA-NEXT: addi a0, a0, -1 -; RV64IZBA-NEXT: slli a0, a0, 12 -; RV64IZBA-NEXT: addi a0, a0, 2047 ; RV64IZBA-NEXT: ret ; ; RV64IZBB-LABEL: imm_end_2addi_1: ; RV64IZBB: # %bb.0: ; RV64IZBB-NEXT: li a0, -2047 -; RV64IZBB-NEXT: slli a0, a0, 27 +; RV64IZBB-NEXT: slli a0, a0, 39 +; RV64IZBB-NEXT: addi a0, a0, -2048 ; RV64IZBB-NEXT: addi a0, a0, -1 -; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, 2047 ; RV64IZBB-NEXT: ret ; ; RV64IZBS-LABEL: imm_end_2addi_1: ; RV64IZBS: # %bb.0: ; RV64IZBS-NEXT: li a0, -2047 -; RV64IZBS-NEXT: slli a0, a0, 27 +; RV64IZBS-NEXT: slli a0, a0, 39 +; RV64IZBS-NEXT: addi a0, a0, -2048 ; RV64IZBS-NEXT: addi a0, a0, -1 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 2047 ; RV64IZBS-NEXT: ret ; ; RV64IXTHEADBB-LABEL: imm_end_2addi_1: ; RV64IXTHEADBB: # %bb.0: ; RV64IXTHEADBB-NEXT: li a0, -2047 -; RV64IXTHEADBB-NEXT: slli a0, a0, 27 +; RV64IXTHEADBB-NEXT: slli a0, a0, 39 +; RV64IXTHEADBB-NEXT: addi a0, a0, -2048 ; RV64IXTHEADBB-NEXT: addi a0, a0, -1 -; RV64IXTHEADBB-NEXT: slli a0, a0, 12 -; RV64IXTHEADBB-NEXT: addi a0, a0, 2047 ; RV64IXTHEADBB-NEXT: ret ret i64 -1125350151030785 ; 0xFFFC_007F_FFFF_F7FF } @@ -2435,21 +2430,14 @@ define i64 @imm_12900925247761() { ; RV32I-NEXT: addi a1, a1, -1093 ; RV32I-NEXT: ret ; -; RV64-NOPOOL-LABEL: imm_12900925247761: -; RV64-NOPOOL: # %bb.0: -; RV64-NOPOOL-NEXT: lui a0, 188 -; RV64-NOPOOL-NEXT: addiw a0, a0, -1093 -; RV64-NOPOOL-NEXT: slli a0, a0, 12 -; RV64-NOPOOL-NEXT: addi a0, a0, 273 -; RV64-NOPOOL-NEXT: slli a0, a0, 12 -; RV64-NOPOOL-NEXT: addi a0, a0, 273 -; RV64-NOPOOL-NEXT: ret -; -; RV64I-POOL-LABEL: imm_12900925247761: -; RV64I-POOL: # %bb.0: -; RV64I-POOL-NEXT: lui a0, %hi(.LCPI52_0) -; RV64I-POOL-NEXT: ld a0, %lo(.LCPI52_0)(a0) -; RV64I-POOL-NEXT: ret +; RV64I-LABEL: imm_12900925247761: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a0, 384478 +; RV64I-NEXT: addiw a0, a0, -1911 +; RV64I-NEXT: slli a0, a0, 13 +; RV64I-NEXT: addi a0, a0, -2048 +; RV64I-NEXT: addi a0, a0, -1775 +; RV64I-NEXT: ret ; ; RV64IZBA-LABEL: imm_12900925247761: ; RV64IZBA: # %bb.0: @@ -2461,32 +2449,29 @@ define i64 @imm_12900925247761() { ; ; RV64IZBB-LABEL: imm_12900925247761: ; RV64IZBB: # %bb.0: -; RV64IZBB-NEXT: lui a0, 188 -; RV64IZBB-NEXT: addiw a0, a0, -1093 -; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, 273 -; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, 273 +; RV64IZBB-NEXT: lui a0, 384478 +; RV64IZBB-NEXT: addiw a0, a0, -1911 +; RV64IZBB-NEXT: slli a0, a0, 13 +; RV64IZBB-NEXT: addi a0, a0, -2048 +; RV64IZBB-NEXT: addi a0, a0, -1775 ; RV64IZBB-NEXT: ret ; ; RV64IZBS-LABEL: imm_12900925247761: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 188 -; RV64IZBS-NEXT: addiw a0, a0, -1093 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 273 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 273 +; RV64IZBS-NEXT: lui a0, 384478 +; RV64IZBS-NEXT: addiw a0, a0, -1911 +; RV64IZBS-NEXT: slli a0, a0, 13 +; RV64IZBS-NEXT: addi a0, a0, -2048 +; RV64IZBS-NEXT: addi a0, a0, -1775 ; RV64IZBS-NEXT: ret ; ; RV64IXTHEADBB-LABEL: imm_12900925247761: ; RV64IXTHEADBB: # %bb.0: -; RV64IXTHEADBB-NEXT: lui a0, 188 -; RV64IXTHEADBB-NEXT: addiw a0, a0, -1093 -; RV64IXTHEADBB-NEXT: slli a0, a0, 12 -; RV64IXTHEADBB-NEXT: addi a0, a0, 273 -; RV64IXTHEADBB-NEXT: slli a0, a0, 12 -; RV64IXTHEADBB-NEXT: addi a0, a0, 273 +; RV64IXTHEADBB-NEXT: lui a0, 384478 +; RV64IXTHEADBB-NEXT: addiw a0, a0, -1911 +; RV64IXTHEADBB-NEXT: slli a0, a0, 13 +; RV64IXTHEADBB-NEXT: addi a0, a0, -2048 +; RV64IXTHEADBB-NEXT: addi a0, a0, -1775 ; RV64IXTHEADBB-NEXT: ret ret i64 12900925247761 } diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s index 67533e944e86a..0102a6bbe1570 100644 --- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s @@ -161,15 +161,13 @@ li x9, 0x1000FFFFFFFD # CHECK-ALIAS-NEXT: not a0, a0 li x10, 0xE000000001FFFFFF # CHECK-INST: addi a1, zero, -2047 -# CHECK-INST-NEXT: slli a1, a1, 27 +# CHECK-INST-NEXT: slli a1, a1, 39 +# CHECK-INST-NEXT: addi a1, a1, -2048 # CHECK-INST-NEXT: addi a1, a1, -1 -# CHECK-INST-NEXT: slli a1, a1, 12 -# CHECK-INST-NEXT: addi a1, a1, 2047 # CHECK-ALIAS: li a1, -2047 -# CHECK-ALIAS-NEXT: slli a1, a1, 27 +# CHECK-ALIAS-NEXT: slli a1, a1, 39 +# CHECK-ALIAS-NEXT: addi a1, a1, -2048 # CHECK-ALIAS-NEXT: addi a1, a1, -1 -# CHECK-ALIAS-NEXT: slli a1, a1, 12 -# CHECK-ALIAS-NEXT: addi a1, a1, 2047 li x11, 0xFFFC007FFFFFF7FF # CHECK-INST: lui a2, 349525 @@ -398,15 +396,13 @@ lla x9, 0x1000FFFFFFFD la x10, 0xE000000001FFFFFF lla x10, 0xE000000001FFFFFF # CHECK-INST: addi a1, zero, -2047 -# CHECK-INST-NEXT: slli a1, a1, 27 +# CHECK-INST-NEXT: slli a1, a1, 39 +# CHECK-INST-NEXT: addi a1, a1, -2048 # CHECK-INST-NEXT: addi a1, a1, -1 -# CHECK-INST-NEXT: slli a1, a1, 12 -# CHECK-INST-NEXT: addi a1, a1, 2047 # CHECK-ALIAS: li a1, -2047 -# CHECK-ALIAS-NEXT: slli a1, a1, 27 +# CHECK-ALIAS-NEXT: slli a1, a1, 39 +# CHECK-ALIAS-NEXT: addi a1, a1, -2048 # CHECK-ALIAS-NEXT: addi a1, a1, -1 -# CHECK-ALIAS-NEXT: slli a1, a1, 12 -# CHECK-ALIAS-NEXT: addi a1, a1, 2047 la x11, 0xFFFC007FFFFFF7FF lla x11, 0xFFFC007FFFFFF7FF