diff --git a/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp --- a/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp @@ -73,6 +73,58 @@ Res.push_back(Inst(RISCV::SLLI, ShiftAmount)); if (Lo12) Res.push_back(Inst(RISCV::ADDI, Lo12)); + + // Now that we handled the general case, let's check if we can improve on it + // in various ways. + + // Try InstSeq(Val) -> InstSeq(Val - Lo12)+ADDI(Lo12). + if (Lo12 != 0 && Res.size() > 2) { + int64_t AltVal = Val - Lo12; + InstSeq AltRes; + generateInstSeq(AltVal, IsRV64, AltRes); + if (AltRes.size() + 1 < Res.size()) { + Res = AltRes; + Res.push_back(Inst(RISCV::ADDI, Lo12)); + } + } + + // Try InstSeq(XXX0*) -> InstSeq(XXX)+SLLI. + if ((Val & 1) == 0 && Res.size() > 2) { + ShiftAmount = findFirstSet((uint64_t)Val); + int64_t AltVal = SignExtend64(Val >> ShiftAmount, 64 - ShiftAmount); + if (isInt<20>(AltVal) && !isInt<12>(AltVal)) { + assert(ShiftAmount > 12); + AltVal = AltVal << 12; + ShiftAmount -= 12; + } + InstSeq AltRes; + generateInstSeq(AltVal, IsRV64, AltRes); + if (AltRes.size() + 1 < Res.size()) { + Res = AltRes; + Res.push_back(Inst(RISCV::SLLI, ShiftAmount)); + } + } + + if (Val > 0 && Res.size() > 2) { + // Try InstSeq(0*XXX) -> InstSeq(XXX1*)+SRLI. + int ShiftAmount = countLeadingZeros((uint64_t)Val); + int64_t AltVal = (Val << ShiftAmount) | ((1L << ShiftAmount) - 1); + InstSeq AltRes; + generateInstSeq(AltVal, IsRV64, AltRes); + if (AltRes.size() + 1 < Res.size()) { + Res = AltRes; + Res.push_back(Inst(RISCV::SRLI, ShiftAmount)); + } + + // Try InstSeq(0*XXX) -> InstSeq(XXX0*)+SRLI. + AltVal = (Val << ShiftAmount); + AltRes.clear(); + generateInstSeq(AltVal, IsRV64, AltRes); + if (AltRes.size() + 1 < Res.size()) { + Res = AltRes; + Res.push_back(Inst(RISCV::SRLI, ShiftAmount)); + } + } } int getIntMatCost(const APInt &Val, unsigned Size, bool IsRV64) { diff --git a/llvm/test/CodeGen/RISCV/add-before-shl.ll b/llvm/test/CodeGen/RISCV/add-before-shl.ll --- a/llvm/test/CodeGen/RISCV/add-before-shl.ll +++ b/llvm/test/CodeGen/RISCV/add-before-shl.ll @@ -38,10 +38,10 @@ ; ; RV64I-LABEL: add_large_const: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a1, 1 -; RV64I-NEXT: addiw a1, a1, -1 -; RV64I-NEXT: add a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 48 +; RV64I-NEXT: lui a1, 4095 +; RV64I-NEXT: slli a1, a1, 36 +; RV64I-NEXT: add a0, a0, a1 ; RV64I-NEXT: srai a0, a0, 48 ; RV64I-NEXT: ret %1 = add i32 %a, 4095 @@ -61,10 +61,10 @@ ; ; RV64I-LABEL: add_huge_const: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a1, 8 -; RV64I-NEXT: addiw a1, a1, -1 -; RV64I-NEXT: add a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 48 +; RV64I-NEXT: lui a1, 32767 +; RV64I-NEXT: slli a1, a1, 36 +; RV64I-NEXT: add a0, a0, a1 ; RV64I-NEXT: srai a0, a0, 48 ; RV64I-NEXT: ret %1 = add i32 %a, 32767 diff --git a/llvm/test/CodeGen/RISCV/copysign-casts.ll b/llvm/test/CodeGen/RISCV/copysign-casts.ll --- a/llvm/test/CodeGen/RISCV/copysign-casts.ll +++ b/llvm/test/CodeGen/RISCV/copysign-casts.ll @@ -29,8 +29,7 @@ ; RV64I-LABEL: fold_promote: ; RV64I: # %bb.0: ; RV64I-NEXT: addi a2, zero, -1 -; RV64I-NEXT: slli a2, a2, 63 -; RV64I-NEXT: addi a2, a2, -1 +; RV64I-NEXT: srli a2, a2, 1 ; RV64I-NEXT: and a0, a0, a2 ; RV64I-NEXT: addi a2, zero, 1 ; RV64I-NEXT: slli a2, a2, 31 diff --git a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll --- a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll +++ b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll @@ -67,16 +67,14 @@ ; RV64I-LABEL: fabs: ; RV64I: # %bb.0: ; RV64I-NEXT: addi a1, zero, -1 -; RV64I-NEXT: slli a1, a1, 63 -; RV64I-NEXT: addi a1, a1, -1 +; RV64I-NEXT: srli a1, a1, 1 ; RV64I-NEXT: and a0, a0, a1 ; RV64I-NEXT: ret ; ; RV64IFD-LABEL: fabs: ; RV64IFD: # %bb.0: ; RV64IFD-NEXT: addi a1, zero, -1 -; RV64IFD-NEXT: slli a1, a1, 63 -; RV64IFD-NEXT: addi a1, a1, -1 +; RV64IFD-NEXT: srli a1, a1, 1 ; RV64IFD-NEXT: and a0, a0, a1 ; RV64IFD-NEXT: ret %1 = call double @llvm.fabs.f64(double %a) @@ -120,9 +118,9 @@ ; RV64I: # %bb.0: ; RV64I-NEXT: not a1, a1 ; RV64I-NEXT: addi a2, zero, -1 -; RV64I-NEXT: slli a2, a2, 63 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: addi a2, a2, -1 +; RV64I-NEXT: slli a3, a2, 63 +; RV64I-NEXT: and a1, a1, a3 +; RV64I-NEXT: srli a2, a2, 1 ; RV64I-NEXT: and a0, a0, a2 ; RV64I-NEXT: or a0, a0, a1 ; RV64I-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/double-intrinsics.ll --- a/llvm/test/CodeGen/RISCV/double-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/double-intrinsics.ll @@ -388,8 +388,7 @@ ; RV64IFD-LABEL: fabs_f64: ; RV64IFD: # %bb.0: ; RV64IFD-NEXT: addi a1, zero, -1 -; RV64IFD-NEXT: slli a1, a1, 63 -; RV64IFD-NEXT: addi a1, a1, -1 +; RV64IFD-NEXT: srli a1, a1, 1 ; RV64IFD-NEXT: and a0, a0, a1 ; RV64IFD-NEXT: ret %1 = call double @llvm.fabs.f64(double %a) diff --git a/llvm/test/CodeGen/RISCV/double-mem.ll b/llvm/test/CodeGen/RISCV/double-mem.ll --- a/llvm/test/CodeGen/RISCV/double-mem.ll +++ b/llvm/test/CodeGen/RISCV/double-mem.ll @@ -136,9 +136,8 @@ ; ; RV64IFD-LABEL: fld_fsd_constant: ; RV64IFD: # %bb.0: -; RV64IFD-NEXT: lui a1, 56 -; RV64IFD-NEXT: addiw a1, a1, -1353 -; RV64IFD-NEXT: slli a1, a1, 14 +; RV64IFD-NEXT: lui a1, 228023 +; RV64IFD-NEXT: slli a1, a1, 2 ; RV64IFD-NEXT: fld ft0, -273(a1) ; RV64IFD-NEXT: fmv.d.x ft1, a0 ; RV64IFD-NEXT: fadd.d ft0, ft1, ft0 diff --git a/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll b/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll --- a/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll +++ b/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll @@ -111,8 +111,7 @@ ; RV64F-NEXT: mv s0, a0 ; RV64F-NEXT: call __adddf3 ; RV64F-NEXT: addi a1, zero, -1 -; RV64F-NEXT: slli a1, a1, 63 -; RV64F-NEXT: addi a1, a1, -1 +; RV64F-NEXT: srli a1, a1, 1 ; RV64F-NEXT: and a1, a0, a1 ; RV64F-NEXT: mv a0, s0 ; RV64F-NEXT: call __adddf3 diff --git a/llvm/test/CodeGen/RISCV/float-mem.ll b/llvm/test/CodeGen/RISCV/float-mem.ll --- a/llvm/test/CodeGen/RISCV/float-mem.ll +++ b/llvm/test/CodeGen/RISCV/float-mem.ll @@ -112,9 +112,8 @@ ; ; RV64IF-LABEL: flw_fsw_constant: ; RV64IF: # %bb.0: -; RV64IF-NEXT: lui a1, 56 -; RV64IF-NEXT: addiw a1, a1, -1353 -; RV64IF-NEXT: slli a1, a1, 14 +; RV64IF-NEXT: lui a1, 228023 +; RV64IF-NEXT: slli a1, a1, 2 ; RV64IF-NEXT: flw ft0, -273(a1) ; RV64IF-NEXT: fmv.w.x ft1, a0 ; RV64IF-NEXT: fadd.s ft0, ft1, ft0 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 @@ -120,9 +120,6 @@ ret i64 2147483648 ; 0x8000_0000 } -; TODO: This and similar constants with all 0s in the upper bits and all 1s in -; the lower bits could be lowered to addi a0, zero, -1 followed by a logical -; right shift. define i64 @imm64_2() nounwind { ; RV32I-LABEL: imm64_2: ; RV32I: # %bb.0: @@ -132,9 +129,8 @@ ; ; RV64I-LABEL: imm64_2: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a0, zero, 1 -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: addi a0, a0, -1 +; RV64I-NEXT: addi a0, zero, -1 +; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret ret i64 4294967295 ; 0xFFFF_FFFF } @@ -271,9 +267,8 @@ ; ; RV64I-LABEL: imm_left_shifted_lui_1: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 64 -; RV64I-NEXT: addiw a0, a0, 1 -; RV64I-NEXT: slli a0, a0, 13 +; RV64I-NEXT: lui a0, 262145 +; RV64I-NEXT: slli a0, a0, 1 ; RV64I-NEXT: ret ret i64 2147491840 ; 0x8000_2000 } @@ -287,9 +282,8 @@ ; ; RV64I-LABEL: imm_left_shifted_lui_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 64 -; RV64I-NEXT: addiw a0, a0, 1 -; RV64I-NEXT: slli a0, a0, 14 +; RV64I-NEXT: lui a0, 262145 +; RV64I-NEXT: slli a0, a0, 2 ; RV64I-NEXT: ret ret i64 4294983680 ; 0x1_0000_4000 } @@ -304,9 +298,8 @@ ; ; RV64I-LABEL: imm_left_shifted_lui_3: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, 1 -; RV64I-NEXT: slli a0, a0, 32 +; RV64I-NEXT: lui a0, 4097 +; RV64I-NEXT: slli a0, a0, 20 ; RV64I-NEXT: ret ret i64 17596481011712 ; 0x1001_0000_0000 } @@ -325,11 +318,8 @@ ; ; RV64I-LABEL: imm_right_shifted_lui_1: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a0, zero, 1 -; RV64I-NEXT: slli a0, a0, 36 -; RV64I-NEXT: addi a0, a0, -1 -; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, 1 +; RV64I-NEXT: lui a0, 983056 +; RV64I-NEXT: srli a0, a0, 16 ; RV64I-NEXT: ret ret i64 281474976706561 ; 0xFFFF_FFFF_F001 } @@ -344,10 +334,9 @@ ; ; RV64I-LABEL: imm_right_shifted_lui_2: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 65536 -; RV64I-NEXT: addiw a0, a0, -1 +; RV64I-NEXT: lui a0, 1044481 ; RV64I-NEXT: slli a0, a0, 12 -; RV64I-NEXT: addi a0, a0, 1 +; RV64I-NEXT: srli a0, a0, 24 ; RV64I-NEXT: ret ret i64 1099511623681 ; 0xFF_FFFF_F001 } @@ -364,9 +353,8 @@ ; ; RV64I-LABEL: imm_decoupled_lui_addi: ; RV64I: # %bb.0: -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, 1 -; RV64I-NEXT: slli a0, a0, 32 +; RV64I-NEXT: lui a0, 4097 +; RV64I-NEXT: slli a0, a0, 20 ; RV64I-NEXT: addi a0, a0, -3 ; RV64I-NEXT: ret ret i64 17596481011709 ; 0x1000_FFFF_FFFD diff --git a/llvm/test/CodeGen/RISCV/rv64-large-stack.ll b/llvm/test/CodeGen/RISCV/rv64-large-stack.ll --- a/llvm/test/CodeGen/RISCV/rv64-large-stack.ll +++ b/llvm/test/CodeGen/RISCV/rv64-large-stack.ll @@ -9,16 +9,14 @@ ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: addi sp, sp, -2032 ; CHECK-NEXT: sd ra, 2024(sp) -; CHECK-NEXT: lui a0, 95 -; CHECK-NEXT: addiw a0, a0, 1505 -; CHECK-NEXT: slli a0, a0, 13 +; CHECK-NEXT: lui a0, 390625 +; CHECK-NEXT: slli a0, a0, 1 ; CHECK-NEXT: addi a0, a0, -2000 ; CHECK-NEXT: sub sp, sp, a0 ; CHECK-NEXT: addi a0, sp, 16 ; CHECK-NEXT: call baz -; CHECK-NEXT: lui a0, 95 -; CHECK-NEXT: addiw a0, a0, 1505 -; CHECK-NEXT: slli a0, a0, 13 +; CHECK-NEXT: lui a0, 390625 +; CHECK-NEXT: slli a0, a0, 1 ; CHECK-NEXT: addi a0, a0, -2000 ; CHECK-NEXT: add sp, sp, a0 ; CHECK-NEXT: ld ra, 2024(sp) diff --git a/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll b/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll --- a/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll +++ b/llvm/test/CodeGen/RISCV/srem-vector-lkk.ll @@ -169,11 +169,10 @@ ; RV64IM-NEXT: addi a5, zero, 95 ; RV64IM-NEXT: mul a2, a2, a5 ; RV64IM-NEXT: sub a1, a1, a2 -; RV64IM-NEXT: lui a2, 248 +; RV64IM-NEXT: lui a2, 777976 ; RV64IM-NEXT: addiw a2, a2, -1057 -; RV64IM-NEXT: slli a2, a2, 15 -; RV64IM-NEXT: addi a2, a2, -1057 -; RV64IM-NEXT: slli a2, a2, 15 +; RV64IM-NEXT: slli a2, a2, 29 +; RV64IM-NEXT: srli a2, a2, 14 ; RV64IM-NEXT: addi a2, a2, -1057 ; RV64IM-NEXT: slli a2, a2, 13 ; RV64IM-NEXT: addi a2, a2, -265 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 @@ -1560,10 +1560,9 @@ ; LP64-LP64F-LP64D-FPELIM-NEXT: addi a0, a0, 655 ; LP64-LP64F-LP64D-FPELIM-NEXT: slli a0, a0, 12 ; LP64-LP64F-LP64D-FPELIM-NEXT: addi t0, a0, 1475 -; 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: lui a0, 1048248 ; LP64-LP64F-LP64D-FPELIM-NEXT: addiw a0, a0, 1311 ; LP64-LP64F-LP64D-FPELIM-NEXT: slli a0, a0, 12 @@ -1611,10 +1610,9 @@ ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, a0, 655 ; LP64-LP64F-LP64D-WITHFP-NEXT: slli a0, a0, 12 ; LP64-LP64F-LP64D-WITHFP-NEXT: addi t0, a0, 1475 -; 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: lui a0, 1048248 ; LP64-LP64F-LP64D-WITHFP-NEXT: addiw a0, a0, 1311 ; LP64-LP64F-LP64D-WITHFP-NEXT: slli a0, a0, 12 diff --git a/llvm/test/MC/RISCV/rv64c-aliases-valid.s b/llvm/test/MC/RISCV/rv64c-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64c-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64c-aliases-valid.s @@ -59,9 +59,8 @@ # CHECK-EXPAND: c.li a2, 1 # CHECK-EXPAND: c.slli a2, 31 li x12, 0x80000000 -# CHECK-EXPAND: c.li a2, 1 -# CHECK-EXPAND: c.slli a2, 32 -# CHECK-EXPAND: c.addi a2, -1 +# CHECK-EXPAND: c.li a2, -1 +# CHECK-EXPAND: c.srli a2, 32 li x12, 0xFFFFFFFF # CHECK-EXPAND: c.li t0, 1 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 @@ -72,9 +72,8 @@ # CHECK-EXPAND: addi a2, zero, 1 # CHECK-EXPAND: slli a2, a2, 31 li x12, 0x80000000 -# CHECK-EXPAND: addi a2, zero, 1 -# CHECK-EXPAND: slli a2, a2, 32 -# CHECK-EXPAND: addi a2, a2, -1 +# CHECK-EXPAND: addi a2, zero, -1 +# CHECK-EXPAND: srli a2, a2, 32 li x12, 0xFFFFFFFF # CHECK-EXPAND: addi t0, zero, 1 @@ -107,32 +106,24 @@ li t4, 0x123456789abcdef0 # CHECK-EXPAND: addi t5, zero, -1 li t5, 0xFFFFFFFFFFFFFFFF -# CHECK-EXPAND: lui t6, 64 -# CHECK-EXPAND: addiw t6, t6, 1 -# CHECK-EXPAND: slli t6, t6, 13 +# CHECK-EXPAND: lui t6, 262145 +# CHECK-EXPAND: slli t6, t6, 1 li t6, 0x80002000 -# CHECK-EXPAND: lui t0, 64 -# CHECK-EXPAND: addiw t0, t0, 1 -# CHECK-EXPAND: slli t0, t0, 14 +# CHECK-EXPAND: lui t0, 262145 +# CHECK-EXPAND: slli t0, t0, 2 li x5, 0x100004000 -# CHECK-EXPAND: lui t1, 1 -# CHECK-EXPAND: addiw t1, t1, 1 -# CHECK-EXPAND: slli t1, t1, 32 +# CHECK-EXPAND: lui t1, 4097 +# CHECK-EXPAND: slli t1, t1, 20 li x6, 0x100100000000 -# CHECK-EXPAND: addi t2, zero, 1 -# CHECK-EXPAND: slli t2, t2, 36 -# CHECK-EXPAND: addi t2, t2, -1 -# CHECK-EXPAND: slli t2, t2, 12 -# CHECK-EXPAND: addi t2, t2, 1 +# CHECK-EXPAND: lui t2, 983056 +# CHECK-EXPAND: srli t2, t2, 16 li x7, 0xFFFFFFFFF001 -# CHECK-EXPAND: lui s0, 65536 -# CHECK-EXPAND: addiw s0, s0, -1 +# CHECK-EXPAND: lui s0, 1044481 # CHECK-EXPAND: slli s0, s0, 12 -# CHECK-EXPAND: addi s0, s0, 1 +# CHECK-EXPAND: srli s0, s0, 24 li x8, 0xFFFFFFF001 -# CHECK-EXPAND: lui s1, 1 -# CHECK-EXPAND: addiw s1, s1, 1 -# CHECK-EXPAND: slli s1, s1, 32 +# CHECK-EXPAND: lui s1, 4097 +# CHECK-EXPAND: slli s1, s1, 20 # CHECK-EXPAND: addi s1, s1, -3 li x9, 0x1000FFFFFFFD # CHECK-EXPAND: addi a0, zero, -1