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 @@ -182,6 +182,34 @@ } } + // Try to use BCLRI for upper 32-bit if the lower 32-bit is negative, + // or try to use BSETI for upper 32-bit if the lower 32-bit is positive. + if (Res.size() > 2 && ActiveFeatures[RISCV::FeatureStdExtZbs]) { + assert(ActiveFeatures[RISCV::Feature64Bit] && + "Expected RV32 to only need 2 instructions"); + int32_t Lo = Val; + uint32_t Hi = Val >> 32; + unsigned Opc = 0; + RISCVMatInt::InstSeq TmpSeq; + generateInstSeqImpl(Lo, ActiveFeatures, TmpSeq); + // Check if it is profitable to use BCLI/BSETI. + if (Lo > 0 && TmpSeq.size() + countPopulation(Hi) < Res.size()) { + Opc = RISCV::BSETI; + } else if (Lo < 0 && TmpSeq.size() + countPopulation(~Hi) < Res.size()) { + Opc = RISCV::BCLRI; + Hi = ~Hi; + } + // Search for each bit and build cprresponding BCLRI/BSETI. + if (Opc > 0) { + while (Hi != 0) { + unsigned Bit = 31 - countLeadingZeros(Hi); + TmpSeq.push_back(RISCVMatInt::Inst(Opc, Bit + 32)); + Hi &= ~(1 << Bit); + } + return 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 @@ -467,13 +467,12 @@ ; ; RV64IB-LABEL: imm_2reg_1: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a0, zero, -1 -; RV64IB-NEXT: slli a0, a0, 35 -; RV64IB-NEXT: addi a0, a0, 9 -; RV64IB-NEXT: slli a0, a0, 13 -; RV64IB-NEXT: addi a0, a0, 837 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, 1656 +; RV64IB-NEXT: lui a0, 74565 +; RV64IB-NEXT: addiw a0, a0, 1656 +; RV64IB-NEXT: bseti a0, a0, 63 +; RV64IB-NEXT: bseti a0, a0, 62 +; RV64IB-NEXT: bseti a0, a0, 61 +; RV64IB-NEXT: bseti a0, a0, 60 ; RV64IB-NEXT: ret ret i64 -1152921504301427080 ; 0xF000_0000_1234_5678 } @@ -522,10 +521,9 @@ ; ; RV64IB-LABEL: imm_5372288229: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 160 -; RV64IB-NEXT: addiw a0, a0, 437 -; RV64IB-NEXT: slli a0, a0, 13 -; RV64IB-NEXT: addi a0, a0, -795 +; RV64IB-NEXT: lui a0, 263018 +; RV64IB-NEXT: addiw a0, a0, -795 +; RV64IB-NEXT: bseti a0, a0, 32 ; RV64IB-NEXT: ret ret i64 5372288229 } @@ -540,10 +538,9 @@ ; ; RV64IB-LABEL: imm_neg_5372288229: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 1048416 -; RV64IB-NEXT: addiw a0, a0, -437 -; RV64IB-NEXT: slli a0, a0, 13 -; RV64IB-NEXT: addi a0, a0, 795 +; RV64IB-NEXT: lui a0, 785558 +; RV64IB-NEXT: addiw a0, a0, 795 +; RV64IB-NEXT: bclri a0, a0, 32 ; RV64IB-NEXT: ret ret i64 -5372288229 } @@ -558,10 +555,9 @@ ; ; RV64IB-LABEL: imm_8953813715: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 267 -; RV64IB-NEXT: addiw a0, a0, -637 -; RV64IB-NEXT: slli a0, a0, 13 -; RV64IB-NEXT: addi a0, a0, -1325 +; RV64IB-NEXT: lui a0, 88838 +; RV64IB-NEXT: addiw a0, a0, -1325 +; RV64IB-NEXT: bseti a0, a0, 33 ; RV64IB-NEXT: ret ret i64 8953813715 } @@ -576,10 +572,9 @@ ; ; RV64IB-LABEL: imm_neg_8953813715: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 1048309 -; RV64IB-NEXT: addiw a0, a0, 637 -; RV64IB-NEXT: slli a0, a0, 13 -; RV64IB-NEXT: addi a0, a0, 1325 +; RV64IB-NEXT: lui a0, 959738 +; RV64IB-NEXT: addiw a0, a0, 1325 +; RV64IB-NEXT: bclri a0, a0, 33 ; RV64IB-NEXT: ret ret i64 -8953813715 } @@ -647,12 +642,9 @@ ; ; RV64IB-LABEL: imm_70370820078523: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 256 -; RV64IB-NEXT: addiw a0, a0, 31 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, -273 -; RV64IB-NEXT: slli a0, a0, 14 -; RV64IB-NEXT: addi a0, a0, -1093 +; RV64IB-NEXT: lui a0, 506812 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bseti a0, a0, 46 ; RV64IB-NEXT: ret ret i64 70370820078523 ; 0x40007bbbbbbb } @@ -667,13 +659,9 @@ ; ; RV64IB-LABEL: imm_neg_9223372034778874949: ; RV64IB: # %bb.0: -; RV64IB-NEXT: addi a0, zero, -1 -; RV64IB-NEXT: slli a0, a0, 37 -; RV64IB-NEXT: addi a0, a0, 31 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, -273 -; RV64IB-NEXT: slli a0, a0, 14 -; RV64IB-NEXT: addi a0, a0, -1093 +; RV64IB-NEXT: lui a0, 506812 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bseti a0, a0, 63 ; RV64IB-NEXT: ret ret i64 -9223372034778874949 ; 0x800000007bbbbbbb } @@ -688,13 +676,10 @@ ; ; RV64IB-LABEL: imm_neg_9223301666034697285: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 917505 -; RV64IB-NEXT: slli a0, a0, 8 -; RV64IB-NEXT: addi a0, a0, 31 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, -273 -; RV64IB-NEXT: slli a0, a0, 14 -; RV64IB-NEXT: addi a0, a0, -1093 +; RV64IB-NEXT: lui a0, 506812 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bseti a0, a0, 63 +; RV64IB-NEXT: bseti a0, a0, 46 ; RV64IB-NEXT: ret ret i64 -9223301666034697285 ; 0x800040007bbbbbbb } @@ -727,10 +712,9 @@ ; ; RV64IB-LABEL: imm_neg_8798043653189: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 917475 -; RV64IB-NEXT: addiw a0, a0, -273 -; RV64IB-NEXT: slli a0, a0, 14 -; RV64IB-NEXT: addi a0, a0, -1093 +; RV64IB-NEXT: lui a0, 572348 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bclri a0, a0, 43 ; RV64IB-NEXT: ret ret i64 -8798043653189 ; 0xfffff7ff8bbbbbbb } @@ -746,11 +730,9 @@ ; ; RV64IB-LABEL: imm_9223372034904144827: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 1048343 -; RV64IB-NEXT: addiw a0, a0, 1911 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, 1911 -; RV64IB-NEXT: srli a0, a0, 1 +; RV64IB-NEXT: lui a0, 572348 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bclri a0, a0, 63 ; RV64IB-NEXT: ret ret i64 9223372034904144827 ; 0x7fffffff8bbbbbbb } @@ -766,13 +748,10 @@ ; ; RV64IB-LABEL: imm_neg_9223354442718100411: ; RV64IB: # %bb.0: -; RV64IB-NEXT: lui a0, 524287 -; RV64IB-NEXT: slli a0, a0, 6 -; RV64IB-NEXT: addi a0, a0, -29 -; RV64IB-NEXT: slli a0, a0, 12 -; RV64IB-NEXT: addi a0, a0, -273 -; RV64IB-NEXT: slli a0, a0, 14 -; RV64IB-NEXT: addi a0, a0, -1093 +; RV64IB-NEXT: lui a0, 572348 +; RV64IB-NEXT: addiw a0, a0, -1093 +; RV64IB-NEXT: bclri a0, a0, 63 +; RV64IB-NEXT: bclri a0, a0, 44 ; RV64IB-NEXT: ret ret i64 9223354442718100411 ; 0x7fffefff8bbbbbbb }