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,34 @@ } } + // Try to use BCLRI for upper 32-bit if the lower 32-bit is negative int32, + // or use BSETI for upper 32-bit if the lower 32-bit is positive int32. + 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 BCLRI/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 corresponding BCLRI/BSETI. + if (Opc > 0) { + while (Hi != 0) { + unsigned Bit = countTrailingZeros(Hi); + TmpSeq.push_back(RISCVMatInt::Inst(Opc, Bit + 32)); + Hi &= ~(1 << Bit); + } + Res = TmpSeq; + } + } + return Res; } Index: llvm/test/CodeGen/RISCV/imm.ll =================================================================== --- llvm/test/CodeGen/RISCV/imm.ll +++ llvm/test/CodeGen/RISCV/imm.ll @@ -841,13 +841,12 @@ ; ; RV64IZBS-LABEL: imm_2reg_1: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: addi a0, zero, -1 -; RV64IZBS-NEXT: slli a0, a0, 35 -; RV64IZBS-NEXT: addi a0, a0, 9 -; RV64IZBS-NEXT: slli a0, a0, 13 -; RV64IZBS-NEXT: addi a0, a0, 837 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 1656 +; RV64IZBS-NEXT: lui a0, 74565 +; RV64IZBS-NEXT: addiw a0, a0, 1656 +; RV64IZBS-NEXT: bseti a0, a0, 60 +; RV64IZBS-NEXT: bseti a0, a0, 61 +; RV64IZBS-NEXT: bseti a0, a0, 62 +; RV64IZBS-NEXT: bseti a0, a0, 63 ; RV64IZBS-NEXT: ret ret i64 -1152921504301427080 ; 0xF000_0000_1234_5678 } @@ -936,10 +935,9 @@ ; ; RV64IZBS-LABEL: imm_5372288229: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 160 -; RV64IZBS-NEXT: addiw a0, a0, 437 -; RV64IZBS-NEXT: slli a0, a0, 13 -; RV64IZBS-NEXT: addi a0, a0, -795 +; RV64IZBS-NEXT: lui a0, 263018 +; RV64IZBS-NEXT: addiw a0, a0, -795 +; RV64IZBS-NEXT: bseti a0, a0, 32 ; RV64IZBS-NEXT: ret ret i64 5372288229 } @@ -970,10 +968,9 @@ ; ; RV64IZBS-LABEL: imm_neg_5372288229: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 1048416 -; RV64IZBS-NEXT: addiw a0, a0, -437 -; RV64IZBS-NEXT: slli a0, a0, 13 -; RV64IZBS-NEXT: addi a0, a0, 795 +; RV64IZBS-NEXT: lui a0, 785558 +; RV64IZBS-NEXT: addiw a0, a0, 795 +; RV64IZBS-NEXT: bclri a0, a0, 32 ; RV64IZBS-NEXT: ret ret i64 -5372288229 } @@ -1004,10 +1001,9 @@ ; ; RV64IZBS-LABEL: imm_8953813715: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 267 -; RV64IZBS-NEXT: addiw a0, a0, -637 -; RV64IZBS-NEXT: slli a0, a0, 13 -; RV64IZBS-NEXT: addi a0, a0, -1325 +; RV64IZBS-NEXT: lui a0, 88838 +; RV64IZBS-NEXT: addiw a0, a0, -1325 +; RV64IZBS-NEXT: bseti a0, a0, 33 ; RV64IZBS-NEXT: ret ret i64 8953813715 } @@ -1038,10 +1034,9 @@ ; ; RV64IZBS-LABEL: imm_neg_8953813715: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 1048309 -; RV64IZBS-NEXT: addiw a0, a0, 637 -; RV64IZBS-NEXT: slli a0, a0, 13 -; RV64IZBS-NEXT: addi a0, a0, 1325 +; RV64IZBS-NEXT: lui a0, 959738 +; RV64IZBS-NEXT: addiw a0, a0, 1325 +; RV64IZBS-NEXT: bclri a0, a0, 33 ; RV64IZBS-NEXT: ret ret i64 -8953813715 } @@ -1175,12 +1170,9 @@ ; ; RV64IZBS-LABEL: imm_70370820078523: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 256 -; RV64IZBS-NEXT: addiw a0, a0, 31 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -273 -; RV64IZBS-NEXT: slli a0, a0, 14 -; RV64IZBS-NEXT: addi a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 506812 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bseti a0, a0, 46 ; RV64IZBS-NEXT: ret ret i64 70370820078523 ; 0x40007bbbbbbb } @@ -1217,13 +1209,9 @@ ; ; RV64IZBS-LABEL: imm_neg_9223372034778874949: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: addi a0, zero, -1 -; RV64IZBS-NEXT: slli a0, a0, 37 -; RV64IZBS-NEXT: addi a0, a0, 31 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -273 -; RV64IZBS-NEXT: slli a0, a0, 14 -; RV64IZBS-NEXT: addi a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 506812 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bseti a0, a0, 63 ; RV64IZBS-NEXT: ret ret i64 -9223372034778874949 ; 0x800000007bbbbbbb } @@ -1260,13 +1248,10 @@ ; ; RV64IZBS-LABEL: imm_neg_9223301666034697285: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 917505 -; RV64IZBS-NEXT: slli a0, a0, 8 -; RV64IZBS-NEXT: addi a0, a0, 31 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -273 -; RV64IZBS-NEXT: slli a0, a0, 14 -; RV64IZBS-NEXT: addi a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 506812 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bseti a0, a0, 46 +; RV64IZBS-NEXT: bseti a0, a0, 63 ; RV64IZBS-NEXT: ret ret i64 -9223301666034697285 ; 0x800040007bbbbbbb } @@ -1329,10 +1314,9 @@ ; ; RV64IZBS-LABEL: imm_neg_8798043653189: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 917475 -; RV64IZBS-NEXT: addiw a0, a0, -273 -; RV64IZBS-NEXT: slli a0, a0, 14 -; RV64IZBS-NEXT: addi a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 572348 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bclri a0, a0, 43 ; RV64IZBS-NEXT: ret ret i64 -8798043653189 ; 0xfffff7ff8bbbbbbb } @@ -1366,11 +1350,9 @@ ; ; RV64IZBS-LABEL: imm_9223372034904144827: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 1048343 -; RV64IZBS-NEXT: addiw a0, a0, 1911 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 1911 -; RV64IZBS-NEXT: srli a0, a0, 1 +; RV64IZBS-NEXT: lui a0, 572348 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bclri a0, a0, 63 ; RV64IZBS-NEXT: ret ret i64 9223372034904144827 ; 0x7fffffff8bbbbbbb } @@ -1408,13 +1390,10 @@ ; ; RV64IZBS-LABEL: imm_neg_9223354442718100411: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 524287 -; RV64IZBS-NEXT: slli a0, a0, 6 -; RV64IZBS-NEXT: addi a0, a0, -29 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -273 -; RV64IZBS-NEXT: slli a0, a0, 14 -; RV64IZBS-NEXT: addi a0, a0, -1093 +; RV64IZBS-NEXT: lui a0, 572348 +; RV64IZBS-NEXT: addiw a0, a0, -1093 +; RV64IZBS-NEXT: bclri a0, a0, 44 +; RV64IZBS-NEXT: bclri a0, a0, 63 ; RV64IZBS-NEXT: ret ret i64 9223354442718100411 ; 0x7fffefff8bbbbbbb } Index: llvm/test/MC/RISCV/rv64zbs-aliases-valid.s =================================================================== --- llvm/test/MC/RISCV/rv64zbs-aliases-valid.s +++ llvm/test/MC/RISCV/rv64zbs-aliases-valid.s @@ -30,3 +30,23 @@ # CHECK-S-OBJ-NOALIAS: bexti t0, t1, 8 # CHECK-S-OBJ: bexti t0, t1, 8 bext x5, x6, 8 + +# CHECK-S-OBJ-NOALIAS: lui t1, 572348 +# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1093 +# CHECK-S-OBJ-NOALIAS-NEXT: bclri t1, t1, 44 +# CHECK-S-OBJ-NOALIAS-NEXT: bclri t1, t1, 63 +# CHECK-S-OBJ: lui t1, 572348 +# CHECK-S-OBJ-NEXT: addiw t1, t1, -1093 +# CHECK-S-OBJ-NEXT: bclri t1, t1, 44 +# CHECK-S-OBJ-NEXT: bclri t1, t1, 63 +li x6, 9223354442718100411 + +# CHECK-S-OBJ-NOALIAS: lui t1, 506812 +# CHECK-S-OBJ-NOALIAS-NEXT: addiw t1, t1, -1093 +# CHECK-S-OBJ-NOALIAS-NEXT: bseti t1, t1, 46 +# CHECK-S-OBJ-NOALIAS-NEXT: bseti t1, t1, 63 +# CHECK-S-OBJ: lui t1, 506812 +# CHECK-S-OBJ-NEXT: addiw t1, t1, -1093 +# CHECK-S-OBJ-NEXT: bseti t1, t1, 46 +# CHECK-S-OBJ-NEXT: bseti t1, t1, 63 +li x6, -9223301666034697285