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 @@ -284,6 +284,32 @@ if (TmpSeq.size() < Res.size()) Res = TmpSeq; } + // Try to use LUI+SH*ADD+ADDI. + int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull; + int64_t Lo12 = SignExtend64<12>(Val); + Div = 0; + if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) { + Div = 3; + Opc = RISCV::SH1ADD; + } else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) { + Div = 5; + Opc = RISCV::SH2ADD; + } else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) { + Div = 9; + Opc = RISCV::SH3ADD; + } + // Build the new instruction sequence. + if (Div > 0) { + // For Val that has zero Lo12 (implies Val equals to Hi52) should has + // already been processed to LUI+SH*ADD by previous optimization. + assert(Lo12 != 0 && + "unexpected instruction sequence for immediate materialisation"); + generateInstSeqImpl(Hi52 / Div, ActiveFeatures, TmpSeq); + TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0)); + TmpSeq.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12)); + if (TmpSeq.size() < Res.size()) + Res = TmpSeq; + } } return Res; 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 @@ -1712,9 +1712,8 @@ ; ; RV64IZBA-LABEL: imm_7158272001: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 427 -; RV64IZBA-NEXT: addiw a0, a0, -1367 -; RV64IZBA-NEXT: slli a0, a0, 12 +; RV64IZBA-NEXT: lui a0, 349525 +; RV64IZBA-NEXT: sh2add a0, a0, a0 ; RV64IZBA-NEXT: addi a0, a0, 1 ; RV64IZBA-NEXT: ret ; @@ -1746,9 +1745,8 @@ ; ; RV64IZBA-LABEL: imm_12884889601: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 768 -; RV64IZBA-NEXT: addiw a0, a0, -3 -; RV64IZBA-NEXT: slli a0, a0, 12 +; RV64IZBA-NEXT: lui a0, 349525 +; RV64IZBA-NEXT: sh3add a0, a0, a0 ; RV64IZBA-NEXT: addi a0, a0, 1 ; RV64IZBA-NEXT: ret ; @@ -1780,9 +1778,8 @@ ; ; RV64IZBA-LABEL: imm_neg_3435982847: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1048371 -; RV64IZBA-NEXT: addiw a0, a0, 817 -; RV64IZBA-NEXT: slli a0, a0, 12 +; RV64IZBA-NEXT: lui a0, 768955 +; RV64IZBA-NEXT: sh1add a0, a0, a0 ; RV64IZBA-NEXT: addi a0, a0, 1 ; RV64IZBA-NEXT: ret ; @@ -1813,9 +1810,8 @@ ; ; RV64IZBA-LABEL: imm_neg_5726842879: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1048235 -; RV64IZBA-NEXT: addiw a0, a0, -1419 -; RV64IZBA-NEXT: slli a0, a0, 12 +; RV64IZBA-NEXT: lui a0, 768945 +; RV64IZBA-NEXT: sh2add a0, a0, a0 ; RV64IZBA-NEXT: addi a0, a0, 1 ; RV64IZBA-NEXT: ret ; @@ -1846,9 +1842,8 @@ ; ; RV64IZBA-LABEL: imm_neg_10307948543: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 1047962 -; RV64IZBA-NEXT: addiw a0, a0, -1645 -; RV64IZBA-NEXT: slli a0, a0, 12 +; RV64IZBA-NEXT: lui a0, 768955 +; RV64IZBA-NEXT: sh3add a0, a0, a0 ; RV64IZBA-NEXT: addi a0, a0, 1 ; RV64IZBA-NEXT: ret ; 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 @@ -117,52 +117,42 @@ # CHECK-S-OBJ-NEXT: addi t1, t1, -1366 li x6, 12900918536874 -# CHECK-S-OBJ-NOALIAS: lui t1, 427 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1367 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ-NOALIAS: lui t1, 349525 +# CHECK-S-OBJ-NOALIAS-NEXT: sh2add t1, t1, t1 # CHECK-S-OBJ-NOALIAS-NEXT: addi t1, t1, 1 -# CHECK-S-OBJ: lui t1, 427 -# CHECK-S-OBJ-NEXT: addiw t1, t1, -1367 -# CHECK-S-OBJ-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ: lui t1, 349525 +# CHECK-S-OBJ-NEXT: sh2add t1, t1, t1 # CHECK-S-OBJ-NEXT: addi t1, t1, 1 li x6, 7158272001 # 0x0000_0001_aaaa_9001 -# CHECK-S-OBJ-NOALIAS: lui t1, 768 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -3 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ-NOALIAS: lui t1, 349525 +# CHECK-S-OBJ-NOALIAS-NEXT: sh3add t1, t1, t1 # CHECK-S-OBJ-NOALIAS-NEXT: addi t1, t1, 1 -# CHECK-S-OBJ: lui t1, 768 -# CHECK-S-OBJ-NEXT: addiw t1, t1, -3 -# CHECK-S-OBJ-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ: lui t1, 349525 +# CHECK-S-OBJ-NEXT: sh3add t1, t1, t1 # CHECK-S-OBJ-NEXT: addi t1, t1, 1 li x6, 12884889601 # 0x0000_0002_ffff_d001 -# CHECK-S-OBJ-NOALIAS: lui t1, 1048371 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, 817 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ-NOALIAS: lui t1, 768955 +# CHECK-S-OBJ-NOALIAS-NEXT: sh1add t1, t1, t1 # CHECK-S-OBJ-NOALIAS-NEXT: addi t1, t1, 1 -# CHECK-S-OBJ: lui t1, 1048371 -# CHECK-S-OBJ-NEXT: addiw t1, t1, 817 -# CHECK-S-OBJ-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ: lui t1, 768955 +# CHECK-S-OBJ-NEXT: sh1add t1, t1, t1 # CHECK-S-OBJ-NEXT: addi t1, t1, 1 li x6, -3435982847 # 0xffff_ffff_3333_1001 -# CHECK-S-OBJ-NOALIAS: lui t1, 1048235 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1419 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ-NOALIAS: lui t1, 768945 +# CHECK-S-OBJ-NOALIAS-NEXT: sh2add t1, t1, t1 # CHECK-S-OBJ-NOALIAS-NEXT: addi t1, t1, 1 -# CHECK-S-OBJ: lui t1, 1048235 -# CHECK-S-OBJ-NEXT: addiw t1, t1, -1419 -# CHECK-S-OBJ-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ: lui t1, 768945 +# CHECK-S-OBJ-NEXT: sh2add t1, t1, t1 # CHECK-S-OBJ-NEXT: addi t1, t1, 1 li x6, -5726842879 # 0xffff_fffe_aaa7_5001 -# CHECK-S-OBJ-NOALIAS: lui t1, 1047962 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1645 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ-NOALIAS: lui t1, 768955 +# CHECK-S-OBJ-NOALIAS-NEXT: sh3add t1, t1, t1 # CHECK-S-OBJ-NOALIAS-NEXT: addi t1, t1, 1 -# CHECK-S-OBJ: lui t1, 1047962 -# CHECK-S-OBJ-NEXT: addiw t1, t1, -1645 -# CHECK-S-OBJ-NEXT: slli t1, t1, 12 +# CHECK-S-OBJ: lui t1, 768955 +# CHECK-S-OBJ-NEXT: sh3add t1, t1, t1 # CHECK-S-OBJ-NEXT: addi t1, t1, 1 li x6, -10307948543 # 0xffff_fffd_9999_3001