diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp @@ -124,13 +124,22 @@ // zext.w if (Imm == UINT64_C(0xffffffff) && ST->hasStdExtZba()) return TTI::TCC_Free; + // bclri + if (ST->hasStdExtZbs() && (~Imm).isPowerOf2()) + return TTI::TCC_Free; if (Inst && Idx == 1 && Imm.getBitWidth() <= ST->getXLen() && canUseShiftPair(Inst, Imm)) return TTI::TCC_Free; - [[fallthrough]]; + Takes12BitImm = true; + break; case Instruction::Add: + Takes12BitImm = true; + break; case Instruction::Or: case Instruction::Xor: + // bseti/binvi + if (ST->hasStdExtZbs() && Imm.isPowerOf2()) + return TTI::TCC_Free; Takes12BitImm = true; break; case Instruction::Mul: diff --git a/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll b/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll --- a/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll +++ b/llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll @@ -95,3 +95,30 @@ %5 = mul i32 %2, %4 ret i32 %5 } + +; bseti +define i64 @test11(i64 %a) nounwind "target-features"="+zbs" { +; CHECK-LABEL: test11 +; CHECK: or i64 %a, 8589934592 + %1 = or i64 %a, 8589934592 ; 1 << 33 + %2 = or i64 %1, 8589934592 ; 1 << 33 + ret i64 %2 +} + +; binvi +define i64 @test12(i64 %a) nounwind "target-features"="+zbs" { +; CHECK-LABEL: test12 +; CHECK: xor i64 %a, -9223372036854775808 + %1 = xor i64 %a, -9223372036854775808 ; 1 << 63 + %2 = xor i64 %1, -9223372036854775808 ; 1 << 63 + ret i64 %2 +} + +; bclri +define i64 @test13(i64 %a) nounwind "target-features"="+zbs" { +; CHECK-LABEL: test13 +; CHECK: and i64 %a, -281474976710657 + %1 = and i64 %a, -281474976710657 ; ~(1 << 48) + %2 = and i64 %1, -281474976710657 ; ~(1 << 48) + ret i64 %2 +}