================ @@ -2854,10 +2854,121 @@ void CodeGenFunction::EmitMultiVersionResolver( case llvm::Triple::aarch64: EmitAArch64MultiVersionResolver(Resolver, Options); return; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + EmitRISCVMultiVersionResolver(Resolver, Options); + return; default: - assert(false && "Only implemented for x86 and AArch64 targets"); + assert(false && "Only implemented for x86, AArch64 and RISC-V targets"); + } +} + +void CodeGenFunction::EmitRISCVMultiVersionResolver( + llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { + + if (getContext().getTargetInfo().getTriple().getOS() != + llvm::Triple::OSType::Linux) { + CGM.getDiags().Report(diag::err_os_unsupport_riscv_target_clones); + return; + } + + llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver); + Builder.SetInsertPoint(CurBlock); + EmitRISCVCpuInit(); + + bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc(); + bool HasDefault = false; + unsigned DefaultIndex = 0; + // Check the each candidate function. + for (unsigned Index = 0; Index < Options.size(); Index++) { ---------------- BeMg wrote:
In other target, it sort the order base on target-defined priority score for all cpu/extension. Take Aarch64 as example, it define a table like: ``` // `llvm/lib/Target/AArch64/AArch64FMV.td` // The last one is score that using to sorting. def : FMVExtension<"aes", "FEAT_AES", "+fp-armv8,+neon", 150>; def : FMVExtension<"bf16", "FEAT_BF16", "+bf16", 280>; def : FMVExtension<"bti", "FEAT_BTI", "+bti", 510>; def : FMVExtension<"crc", "FEAT_CRC", "+crc", 110>; ... ``` And sort it before going to emit the resolver. ``` ... llvm::stable_sort( Options, [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS, const CodeGenFunction::MultiVersionResolverOption &RHS) { return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS); }); ... static unsigned TargetMVPriority(const TargetInfo &TI, const CodeGenFunction::MultiVersionResolverOption &RO) { unsigned Priority = 0; unsigned NumFeatures = 0; for (StringRef Feat : RO.Conditions.Features) { Priority = std::max(Priority, TI.multiVersionSortPriority(Feat)); NumFeatures++; } if (!RO.Conditions.Architecture.empty()) Priority = std::max( Priority, TI.multiVersionSortPriority(RO.Conditions.Architecture)); Priority += TI.multiVersionFeatureCost() * NumFeatures; return Priority; } ``` https://github.com/llvm/llvm-project/pull/85786 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits