Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -182,6 +182,23 @@ } } + // Optimize for values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000. + // First call generateInstSeqImpl with Val+0x80000000 (which is an int32), + // then emit (BCLRI r, 31). + if (Res.size() > 3 && ActiveFeatures[RISCV::FeatureStdExtZbs]) { + assert(ActiveFeatures[RISCV::Feature64Bit] && + "Expected RV32 to only need 2 instructions"); + uint64_t UVal = Val; + if (0xffffffff00000000 <= UVal && UVal <= 0xffffffff7fffffff) { + RISCVMatInt::InstSeq TmpSeq; + generateInstSeqImpl(UVal + 0x80000000, ActiveFeatures, TmpSeq); + assert(TmpSeq.size <= 2 && + "value outside range [0xffffffff7fffffff, 0xffffffff00000000]"); + TmpSeq.push_back(RISCVMatInt::Inst(RISCV::BCLRI, 31)); + return TmpSeq; + } + } + return Res; } Index: llvm/test/CodeGen/RISCV/imm.ll =================================================================== --- llvm/test/CodeGen/RISCV/imm.ll +++ llvm/test/CodeGen/RISCV/imm.ll @@ -804,10 +804,9 @@ ; ; RV64IB-LABEL: imm_neg_2863311530: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 1048405 -; RV64IB-NEXT: addiw a0, a0, 1365 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, 1366 +; RV64IB-NEXT: lui a0, 873813 +; RV64IB-NEXT: addiw a0, a0, 1366 +; RV64IB-NEXT: bclri a0, a0, 31 ; RV64IB-NEXT: ret ret i64 -2863311530 ; #0xffffffff55555556 }