Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -182,16 +182,17 @@ } } - // Perform the following optimization with the Zbs extension. - // 1. For values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000, - // call generateInstSeqImpl with Val|0x80000000 (which is expected be - // an int32), then emit (BCLRI r, 31). - // 2. For values in range 0x80000000 ~ 0xffffffff, call generateInstSeqImpl - // with Val&~0x80000000 (which is expected to be an int32), then - // emit (BSETI r, 31). + // Perform optimization with BSETI/BCLRI in the Zbs extension. if (Res.size() > 2 && ActiveFeatures[RISCV::FeatureStdExtZbs]) { assert(ActiveFeatures[RISCV::Feature64Bit] && "Expected RV32 to only need 2 instructions"); + + // 1. For values in range 0xffffffff 7fffffff ~ 0xffffffff 00000000, + // call generateInstSeqImpl with Val|0x80000000 (which is expected be + // an int32), then emit (BCLRI r, 31). + // 2. For values in range 0x80000000 ~ 0xffffffff, call generateInstSeqImpl + // with Val&~0x80000000 (which is expected to be an int32), then + // emit (BSETI r, 31). int64_t NewVal; unsigned Opc; if (Val < 0) { @@ -208,6 +209,32 @@ if (TmpSeq.size() < Res.size()) Res = TmpSeq; } + + // Try to use BCLRI for upper 32-bit if the original lower 32-bit is + // negative int32, or use BSETI for upper 32-bit if the original lower + // 32-bit is positive int32. + int32_t Lo = Val; + uint32_t Hi = Val >> 32; + 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); + } + if (TmpSeq.size() < Res.size()) + 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 @@ -58,3 +58,23 @@ # CHECK-S-OBJ: addi t0, zero, -1365 # CHECK-S-OBJ-NEXT: bclri t0, t0, 31 li x5, -2147485013 + +# 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