llvm 的 llc -mcpu=help 命令可实时列出当前构建版本支持的 risc-v cpu 名称(如 generic、sifive-u54、thead-c910 等),其输出源自 riscv 后端 getavailablecpus() 实现,比文档更准确且反映实际支持状态;需确保 llvm 编译时启用 riscv 目标(llvm_targets_to_build="riscv")且 llvm-config --targets-built 包含 riscv,否则列表为空。

llc -mcpu=help 列出所有支持的 RISC-V CPU 名称
LLVM 的 llc 工具直接内置了目标后端的 CPU 型号枚举能力,执行 llc -mtriple=riscv64 -mcpu=help(或 riscv32)就能打印完整列表。这个输出来自 RISC-V 后端的 getAvailableCPUs() 实现,比查文档更准、且反映你当前构建的 LLVM 版本真实支持范围。
常见返回包括:generic(默认通用目标)、cv32a60x、cv32a65x、sifive-e21、sifive-u54、rocket、thead-c906、thead-c910 等。注意:不同 LLVM 版本支持的型号差异较大——例如 thead-c910 在 LLVM 16+ 才稳定支持,14.x 中可能只显示 generic 或报错。
为什么不能只看官方文档里的 CPU 列表
LLVM 文档中列出的 CPU 名称常滞后于代码实际支持情况。比如某款国产芯片的 -mcpu=xxx 支持可能已合入主干数月,但官网文档还没更新;反过来,某些旧型号(如 rocket)在新版本中可能已被标记为 deprecated,但文档仍保留。
更关键的是:CPU 名称是否生效,还取决于你编译 LLVM 时是否启用了对应后端的扩展支持。例如启用 RISCVTargetMachine 时未开启 LLVM_TARGETS_TO_BUILD="RISCV",llc -mcpu=help 就会为空。
验证方式很简单:
- 运行
llc --version确认输出含RISCV - 检查
llvm-config --targets-built是否含RISCV - 若无,说明该 LLVM 构建不带 RISC-V 后端,
-mcpu再多也无效
用 clang -### 查看实际传给 llc 的 -mcpu 参数
有时你写了 -mcpu=thead-c910,但最终生成的代码仍是 generic 指令——问题往往不在 CPU 名称本身,而在 clang 调用 llc 时参数被覆盖或忽略。
加 -### 可看到完整命令链:
clang -target riscv64 -mcpu=thead-c910 -c test.c -###
输出里找类似这行:
"/path/to/llc" "-mtriple=riscv64-unknown-elf" "-mcpu=thead-c910" ...
如果 -mcpu 值被替换成 generic 或消失,说明:
- 你用的
-target三元组不匹配(比如riscv32下硬塞thead-c910,会被降级) - Clang 前端做了隐式修正(例如检测到
-march不兼容,主动丢弃-mcpu) - 工具链配置文件(如
clang/resource-dir下的cpu.def)未同步更新
自定义 CPU 名称需要改源码,不是加个字符串就行
如果你要支持一款文档里没有、llc -mcpu=help 也不显示的新 CPU(比如某款 FPGA 上的定制核),不能只靠 -mcpu=xxx 强行传参——LLVM 会报 error: invalid CPU name。
必须修改 RISC-V 后端源码:
- 在
lib/Target/RISCV/RISCV.td中添加def XXX : Proc - 在
lib/Target/RISCV/RISCVSubtarget.cpp的parseCPU或getAvailableCPUs中注册名称 - 重新编译 LLVM,否则
llc -mcpu=help永远看不到它
最容易被忽略的一点是:即使名称注册成功,若未在 RISCV.td 中正确定义该 CPU 的指令集特性(如是否支持 Zicsr、Zifencei、+v),生成的代码仍可能因非法指令而崩溃。所以 -mcpu 不只是名字,它绑定着一整套微架构语义。











