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 @@ } } + // 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). + if (Res.size() > 2 && ActiveFeatures[RISCV::FeatureStdExtZbs]) { + assert(ActiveFeatures[RISCV::Feature64Bit] && + "Expected RV32 to only need 2 instructions"); + int64_t NewVal; + unsigned Opc; + if (Val < 0) { + Opc = RISCV::BCLRI; + NewVal = Val | 0x80000000ll; + } else { + Opc = RISCV::BSETI; + NewVal = Val & ~0x80000000ll; + } + if (isInt<32>(NewVal)) { + RISCVMatInt::InstSeq TmpSeq; + generateInstSeqImpl(NewVal, ActiveFeatures, TmpSeq); + TmpSeq.push_back(RISCVMatInt::Inst(Opc, 31)); + 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 @@ -1444,10 +1444,9 @@ ; ; RV64IZBS-LABEL: imm_2863311530: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 171 -; RV64IZBS-NEXT: addiw a0, a0, -1365 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, -1366 +; RV64IZBS-NEXT: lui a0, 174763 +; RV64IZBS-NEXT: addiw a0, a0, -1366 +; RV64IZBS-NEXT: bseti a0, a0, 31 ; RV64IZBS-NEXT: ret ret i64 2863311530 ; #0xaaaaaaaa } @@ -1478,10 +1477,69 @@ ; ; RV64IZBS-LABEL: imm_neg_2863311530: ; RV64IZBS: # %bb.0: -; RV64IZBS-NEXT: lui a0, 1048405 -; RV64IZBS-NEXT: addiw a0, a0, 1365 -; RV64IZBS-NEXT: slli a0, a0, 12 -; RV64IZBS-NEXT: addi a0, a0, 1366 +; RV64IZBS-NEXT: lui a0, 873813 +; RV64IZBS-NEXT: addiw a0, a0, 1366 +; RV64IZBS-NEXT: bclri a0, a0, 31 ; RV64IZBS-NEXT: ret ret i64 -2863311530 ; #0xffffffff55555556 } + +define i64 @imm_2147486378() { +; RV32I-LABEL: imm_2147486378: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, 524288 +; RV32I-NEXT: addi a0, a0, 1365 +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: ret +; +; RV64I-LABEL: imm_2147486378: +; RV64I: # %bb.0: +; RV64I-NEXT: addi a0, zero, 1 +; RV64I-NEXT: slli a0, a0, 31 +; RV64I-NEXT: addi a0, a0, 1365 +; RV64I-NEXT: ret +; +; RV64IZBA-LABEL: imm_2147486378: +; RV64IZBA: # %bb.0: +; RV64IZBA-NEXT: addi a0, zero, 1 +; RV64IZBA-NEXT: slli a0, a0, 31 +; RV64IZBA-NEXT: addi a0, a0, 1365 +; RV64IZBA-NEXT: ret +; +; RV64IZBS-LABEL: imm_2147486378: +; RV64IZBS: # %bb.0: +; RV64IZBS-NEXT: addi a0, zero, 1365 +; RV64IZBS-NEXT: bseti a0, a0, 31 +; RV64IZBS-NEXT: ret + ret i64 2147485013 +} + +define i64 @imm_neg_2147485013() { +; RV32I-LABEL: imm_neg_2147485013: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, 524288 +; RV32I-NEXT: addi a0, a0, -1365 +; RV32I-NEXT: addi a1, zero, -1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: imm_neg_2147485013: +; RV64I: # %bb.0: +; RV64I-NEXT: addi a0, zero, -1 +; RV64I-NEXT: slli a0, a0, 31 +; RV64I-NEXT: addi a0, a0, -1365 +; RV64I-NEXT: ret +; +; RV64IZBA-LABEL: imm_neg_2147485013: +; RV64IZBA: # %bb.0: +; RV64IZBA-NEXT: addi a0, zero, -1 +; RV64IZBA-NEXT: slli a0, a0, 31 +; RV64IZBA-NEXT: addi a0, a0, -1365 +; RV64IZBA-NEXT: ret +; +; RV64IZBS-LABEL: imm_neg_2147485013: +; RV64IZBS: # %bb.0: +; RV64IZBS-NEXT: addi a0, zero, -1365 +; RV64IZBS-NEXT: bclri a0, a0, 31 +; RV64IZBS-NEXT: ret + ret i64 -2147485013 +} diff --git a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64zbs-aliases-valid.s @@ -30,3 +30,31 @@ # CHECK-S-OBJ-NOALIAS: bexti t0, t1, 8 # CHECK-S-OBJ: bexti t0, t1, 8 bext x5, x6, 8 + +# CHECK-S-OBJ-NOALIAS: lui t0, 174763 +# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, -1366 +# CHECK-S-OBJ-NOALIAS-NEXT: bseti t0, t0, 31 +# CHECK-S-OBJ: lui t0, 174763 +# CHECK-S-OBJ-NEXT: addiw t0, t0, -1366 +# CHECK-S-OBJ-NEXT: bseti t0, t0, 31 +li x5, 2863311530 # 0xaaaaaaaa + +# CHECK-S-OBJ-NOALIAS: lui t0, 873813 +# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, 1366 +# CHECK-S-OBJ-NOALIAS-NEXT: bclri t0, t0, 31 +# CHECK-S-OBJ: lui t0, 873813 +# CHECK-S-OBJ-NEXT: addiw t0, t0, 1366 +# CHECK-S-OBJ-NEXT: bclri t0, t0, 31 +li x5, -2863311530 # 0xffffffff55555556 + +# CHECK-S-OBJ-NOALIAS: addi t0, zero, 1365 +# CHECK-S-OBJ-NOALIAS-NEXT: bseti t0, t0, 31 +# CHECK-S-OBJ: addi t0, zero, 1365 +# CHECK-S-OBJ-NEXT: bseti t0, t0, 31 +li x5, 2147485013 + +# CHECK-S-OBJ-NOALIAS: addi t0, zero, -1365 +# CHECK-S-OBJ-NOALIAS-NEXT: bclri t0, t0, 31 +# CHECK-S-OBJ: addi t0, zero, -1365 +# CHECK-S-OBJ-NEXT: bclri t0, t0, 31 +li x5, -2147485013