diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -162,6 +162,24 @@ RISCVMatInt::InstSeq Res; generateInstSeqImpl(Val, ActiveFeatures, Res); + // If there are trailing zeros, try generating a sign extended constant with + // no trailing zeros and use a final SLLI to restore them. + if ((Val & 1) == 0 && Res.size() > 2) { + unsigned TrailingZeros = countTrailingZeros((uint64_t)Val); + int64_t ShiftedVal = Val >> TrailingZeros; + RISCVMatInt::InstSeq TmpSeq; + generateInstSeqImpl(ShiftedVal, ActiveFeatures, TmpSeq); + TmpSeq.push_back(RISCVMatInt::Inst(RISCV::SLLI, TrailingZeros)); + + // Keep the new sequence if it is an improvement. + if (TmpSeq.size() < Res.size()) { + Res = TmpSeq; + // A 2 instruction sequence is the best we can do. + if (Res.size() <= 2) + return Res; + } + } + // 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 && Res.size() > 2) { diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -601,14 +601,13 @@ ; ; RV64IZBA-LABEL: imm64_8: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 583 -; RV64IZBA-NEXT: addiw a0, a0, -1875 -; RV64IZBA-NEXT: slli a0, a0, 14 -; RV64IZBA-NEXT: addi a0, a0, -947 +; RV64IZBA-NEXT: lui a0, 596523 +; RV64IZBA-NEXT: addiw a0, a0, 965 +; RV64IZBA-NEXT: slli.uw a0, a0, 13 +; RV64IZBA-NEXT: addi a0, a0, -1347 ; RV64IZBA-NEXT: slli a0, a0, 12 -; RV64IZBA-NEXT: addi a0, a0, 1511 -; RV64IZBA-NEXT: slli a0, a0, 13 -; RV64IZBA-NEXT: addi a0, a0, -272 +; RV64IZBA-NEXT: addi a0, a0, -529 +; RV64IZBA-NEXT: slli a0, a0, 4 ; RV64IZBA-NEXT: ret ; ; RV64IZBB-LABEL: imm64_8: @@ -1723,32 +1722,30 @@ ; ; RV64I-LABEL: imm_2863311530: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 171 -; RV64I-NEXT: addiw a0, a0, -1365 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, -1366 +; RV64I-NEXT: lui a0, 349525 +; RV64I-NEXT: addiw a0, a0, 1365 +; RV64I-NEXT: slli a0, a0, 1 ; RV64I-NEXT: ret ; ; RV64IZBA-LABEL: imm_2863311530: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 699051 -; RV64IZBA-NEXT: addiw a0, a0, -1366 -; RV64IZBA-NEXT: zext.w a0, a0 +; RV64IZBA-NEXT: lui a0, 349525 +; RV64IZBA-NEXT: addiw a0, a0, 1365 +; RV64IZBA-NEXT: slli a0, a0, 1 ; RV64IZBA-NEXT: ret ; ; RV64IZBB-LABEL: imm_2863311530: ; RV64IZBB: # %bb.0: -; RV64IZBB-NEXT: lui a0, 171 -; RV64IZBB-NEXT: addiw a0, a0, -1365 -; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, -1366 +; RV64IZBB-NEXT: lui a0, 349525 +; RV64IZBB-NEXT: addiw a0, a0, 1365 +; RV64IZBB-NEXT: slli a0, a0, 1 ; RV64IZBB-NEXT: ret ; ; RV64IZBS-LABEL: imm_2863311530: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 174763 -; RV64IZBS-NEXT: addiw a0, a0, -1366 -; RV64IZBS-NEXT: bseti a0, a0, 31 +; RV64IZBS-NEXT: lui a0, 349525 +; RV64IZBS-NEXT: addiw a0, a0, 1365 +; RV64IZBS-NEXT: slli a0, a0, 1 ; RV64IZBS-NEXT: ret ret i64 2863311530 ; #0xaaaaaaaa } @@ -1763,32 +1760,30 @@ ; ; RV64I-LABEL: imm_neg_2863311530: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 1048405 -; RV64I-NEXT: addiw a0, a0, 1365 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, 1366 +; RV64I-NEXT: lui a0, 699051 +; RV64I-NEXT: addiw a0, a0, -1365 +; RV64I-NEXT: slli a0, a0, 1 ; RV64I-NEXT: ret ; ; RV64IZBA-LABEL: imm_neg_2863311530: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 908766 -; RV64IZBA-NEXT: addiw a0, a0, -546 -; RV64IZBA-NEXT: sh2add a0, a0, a0 +; RV64IZBA-NEXT: lui a0, 699051 +; RV64IZBA-NEXT: addiw a0, a0, -1365 +; RV64IZBA-NEXT: slli a0, a0, 1 ; RV64IZBA-NEXT: ret ; ; RV64IZBB-LABEL: imm_neg_2863311530: ; RV64IZBB: # %bb.0: -; RV64IZBB-NEXT: lui a0, 1048405 -; RV64IZBB-NEXT: addiw a0, a0, 1365 -; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, 1366 +; RV64IZBB-NEXT: lui a0, 699051 +; RV64IZBB-NEXT: addiw a0, a0, -1365 +; RV64IZBB-NEXT: slli a0, a0, 1 ; RV64IZBB-NEXT: ret ; ; RV64IZBS-LABEL: imm_neg_2863311530: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 873813 -; RV64IZBS-NEXT: addiw a0, a0, 1366 -; RV64IZBS-NEXT: bclri a0, a0, 31 +; RV64IZBS-NEXT: lui a0, 699051 +; RV64IZBS-NEXT: addiw a0, a0, -1365 +; RV64IZBS-NEXT: slli a0, a0, 1 ; RV64IZBS-NEXT: ret ret i64 -2863311530 ; #0xffffffff55555556 } @@ -2002,12 +1997,11 @@ ; ; RV64I-LABEL: imm_12900918536874: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 188 -; RV64I-NEXT: addiw a0, a0, -1093 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, -1365 +; RV64I-NEXT: lui a0, 384477 +; RV64I-NEXT: addiw a0, a0, 1365 ; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, -1366 +; RV64I-NEXT: addi a0, a0, 1365 +; RV64I-NEXT: slli a0, a0, 1 ; RV64I-NEXT: ret ; ; RV64IZBA-LABEL: imm_12900918536874: @@ -2020,22 +2014,20 @@ ; ; RV64IZBB-LABEL: imm_12900918536874: ; 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, -1365 +; RV64IZBB-NEXT: lui a0, 384477 +; RV64IZBB-NEXT: addiw a0, a0, 1365 ; RV64IZBB-NEXT: slli a0, a0, 12 -; RV64IZBB-NEXT: addi a0, a0, -1366 +; RV64IZBB-NEXT: addi a0, a0, 1365 +; RV64IZBB-NEXT: slli a0, a0, 1 ; RV64IZBB-NEXT: ret ; ; RV64IZBS-LABEL: imm_12900918536874: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 188 -; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 384477 +; RV64IZBS-NEXT: addiw a0, a0, 1365 ; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -1365 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -1366 +; RV64IZBS-NEXT: addi a0, a0, 1365 +; RV64IZBS-NEXT: slli a0, a0, 1 ; RV64IZBS-NEXT: ret ret i64 12900918536874 } diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -717,24 +717,6 @@ ret i64 4294967294 ; -2 in 32 bits. } -define i64 @imm_zextw2() nounwind { -; RV64I-LABEL: imm_zextw2: -; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 171 -; RV64I-NEXT: addiw a0, a0, -1365 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, -1366 -; RV64I-NEXT: ret -; -; RV64ZBA-LABEL: imm_zextw2: -; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: lui a0, 699051 -; RV64ZBA-NEXT: addiw a0, a0, -1366 -; RV64ZBA-NEXT: zext.w a0, a0 -; RV64ZBA-NEXT: ret - ret i64 2863311530 ; 0xAAAAAAAA -} - define i64 @mul11(i64 %a) { ; RV64I-LABEL: mul11: ; RV64I: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv64zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbp.ll --- a/llvm/test/CodeGen/RISCV/rv64zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbp.ll @@ -1635,14 +1635,11 @@ ; RV64I-NEXT: and a0, a0, a2 ; RV64I-NEXT: or a0, a1, a0 ; RV64I-NEXT: slli a1, a0, 4 -; RV64I-NEXT: lui a2, 241 -; RV64I-NEXT: addiw a2, a2, -241 -; RV64I-NEXT: slli a2, a2, 12 -; RV64I-NEXT: addi a2, a2, 240 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: srli a0, a0, 4 ; RV64I-NEXT: lui a2, 61681 ; RV64I-NEXT: addiw a2, a2, -241 +; RV64I-NEXT: slli a3, a2, 4 +; RV64I-NEXT: and a1, a1, a3 +; RV64I-NEXT: srli a0, a0, 4 ; RV64I-NEXT: and a0, a0, a2 ; RV64I-NEXT: or a0, a1, a0 ; RV64I-NEXT: ret @@ -3195,15 +3192,12 @@ ; RV64I-NEXT: and a1, a0, a1 ; RV64I-NEXT: slli a2, a0, 8 ; RV64I-NEXT: li a3, 255 -; RV64I-NEXT: slli a4, a3, 32 -; RV64I-NEXT: addi a4, a4, 255 -; RV64I-NEXT: slli a4, a4, 16 +; RV64I-NEXT: slli a3, a3, 32 +; RV64I-NEXT: addi a3, a3, 255 +; RV64I-NEXT: slli a4, a3, 16 ; RV64I-NEXT: and a2, a2, a4 ; RV64I-NEXT: srli a0, a0, 8 -; RV64I-NEXT: slli a3, a3, 24 -; RV64I-NEXT: addi a3, a3, 1 -; RV64I-NEXT: slli a3, a3, 16 -; RV64I-NEXT: addi a3, a3, -256 +; RV64I-NEXT: slli a3, a3, 8 ; RV64I-NEXT: and a0, a0, a3 ; RV64I-NEXT: or a0, a0, a1 ; RV64I-NEXT: or a0, a2, a0 diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll --- a/llvm/test/CodeGen/RISCV/vararg.ll +++ b/llvm/test/CodeGen/RISCV/vararg.ll @@ -1540,10 +1540,9 @@ ; LP64-LP64F-LP64D-FPELIM-NEXT: ld a2, %lo(.LCPI11_1)(a0) ; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, %hi(.LCPI11_2) ; LP64-LP64F-LP64D-FPELIM-NEXT: ld a3, %lo(.LCPI11_2)(a0) -; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 1192 -; LP64-LP64F-LP64D-FPELIM-NEXT: addiw a0, a0, 381 -; LP64-LP64F-LP64D-FPELIM-NEXT: slli a0, a0, 12 -; LP64-LP64F-LP64D-FPELIM-NEXT: addi a6, a0, -2048 +; LP64-LP64F-LP64D-FPELIM-NEXT: lui a0, 2384 +; LP64-LP64F-LP64D-FPELIM-NEXT: addiw a0, a0, 761 +; LP64-LP64F-LP64D-FPELIM-NEXT: slli a6, a0, 11 ; LP64-LP64F-LP64D-FPELIM-NEXT: li a0, 1 ; LP64-LP64F-LP64D-FPELIM-NEXT: li a1, 11 ; LP64-LP64F-LP64D-FPELIM-NEXT: li a4, 12 @@ -1573,10 +1572,9 @@ ; LP64-LP64F-LP64D-WITHFP-NEXT: ld a2, %lo(.LCPI11_1)(a0) ; LP64-LP64F-LP64D-WITHFP-NEXT: lui a0, %hi(.LCPI11_2) ; LP64-LP64F-LP64D-WITHFP-NEXT: ld a3, %lo(.LCPI11_2)(a0) -; LP64-LP64F-LP64D-WITHFP-NEXT: lui a0, 1192 -; LP64-LP64F-LP64D-WITHFP-NEXT: addiw a0, a0, 381 -; LP64-LP64F-LP64D-WITHFP-NEXT: slli a0, a0, 12 -; LP64-LP64F-LP64D-WITHFP-NEXT: addi a6, a0, -2048 +; LP64-LP64F-LP64D-WITHFP-NEXT: lui a0, 2384 +; LP64-LP64F-LP64D-WITHFP-NEXT: addiw a0, a0, 761 +; LP64-LP64F-LP64D-WITHFP-NEXT: slli a6, a0, 11 ; LP64-LP64F-LP64D-WITHFP-NEXT: li a0, 1 ; LP64-LP64F-LP64D-WITHFP-NEXT: li a1, 11 ; LP64-LP64F-LP64D-WITHFP-NEXT: li a4, 12 diff --git a/llvm/test/MC/RISCV/rv64i-aliases-valid.s b/llvm/test/MC/RISCV/rv64i-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64i-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64i-aliases-valid.s @@ -170,6 +170,22 @@ # CHECK-ALIAS-NEXT: addi a1, a1, 2047 li x11, 0xFFFC007FFFFFF7FF +# CHECK-INST: lui a2, 349525 +# CHECK-INST-NEXT: addiw a2, a2, 1365 +# CHECK-INST-NEXT: slli a2, a2, 1 +# CHECK-ALIAS: lui a2, 349525 +# CHECK-ALIAS-NEXT: addiw a2, a2, 1365 +# CHECK-ALIAS-NEXT: slli a2, a2, 1 +li x12, 0xaaaaaaaa + +# CHECK-INST: lui a3, 699051 +# CHECK-INST-NEXT: addiw a3, a3, -1365 +# CHECK-INST-NEXT: slli a3, a3, 1 +# CHECK-ALIAS: lui a3, 699051 +# CHECK-ALIAS-NEXT: addiw a3, a3, -1365 +# CHECK-ALIAS-NEXT: slli a3, a3, 1 +li x13, 0xffffffff55555556 + # CHECK-INST: addi a0, zero, 1110 # CHECK-ALIAS: li a0, 1110 li a0, %lo(0x123456) diff --git a/llvm/test/MC/RISCV/rv64zba-aliases-valid.s b/llvm/test/MC/RISCV/rv64zba-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64zba-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64zba-aliases-valid.s @@ -25,14 +25,6 @@ # CHECK-S-OBJ-NEXT: zext.w t1, t1 li x6, 0xfffffffe -# CHECK-S-OBJ-NOALIAS: lui t2, 699051 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t2, t2, -1366 -# CHECK-S-OBJ-NOALIAS-NEXT: add.uw t2, t2, zero -# CHECK-S-OBJ: lui t2, 699051 -# CHECK-S-OBJ-NEXT: addiw t2, t2, -1366 -# CHECK-S-OBJ-NEXT: zext.w t2, t2 -li x7, 0xaaaaaaaa - # CHECK-S-OBJ-NOALIAS: lui t0, 768955 # CHECK-S-OBJ-NOALIAS-NEXT: slli.uw t0, t0, 12 # CHECK-S-OBJ-NOALIAS-NEXT: addi t0, t0, 1979 diff --git a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s @@ -31,22 +31,6 @@ # CHECK-S-OBJ: bexti t0, t1, 8 bext x5, x6, 8 -# CHECK-S-OBJ-NOALIAS: lui t0, 174763 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, -1366 -# CHECK-S-OBJ-NOALIAS-NEXT: bseti t0, t0, 31 -# CHECK-S-OBJ: lui t0, 174763 -# CHECK-S-OBJ-NEXT: addiw t0, t0, -1366 -# CHECK-S-OBJ-NEXT: bseti t0, t0, 31 -li x5, 2863311530 # 0xaaaaaaaa - -# CHECK-S-OBJ-NOALIAS: lui t0, 873813 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, 1366 -# CHECK-S-OBJ-NOALIAS-NEXT: bclri t0, t0, 31 -# CHECK-S-OBJ: lui t0, 873813 -# CHECK-S-OBJ-NEXT: addiw t0, t0, 1366 -# CHECK-S-OBJ-NEXT: bclri t0, t0, 31 -li x5, -2863311530 # 0xffffffff55555556 - # CHECK-S-OBJ-NOALIAS: addi t0, zero, 1365 # CHECK-S-OBJ-NOALIAS-NEXT: bseti t0, t0, 31 # CHECK-S-OBJ: li t0, 1365