最可靠方式是clang --target=riscv64 --target-help结合LLVM版本号、源码RISCV.td声明、-print-enabled-extensions输出及intrinsic编译验证四者交叉确认,因不同版本对RISC-V扩展的解析逻辑、默认启用和intrinsic注册状态差异极大。

直接查 clang --target=riscv64 --target-help 输出最可靠,但必须结合 LLVM 版本号、源码提交点和实际编译验证——不同版本对 RISC-V 扩展的解析逻辑、默认启用行为、intrinsic 注册状态差异极大,光看 help 列表容易误判。
用 --target-help 快速比对基础支持范围
这是最轻量、最面向用户的横向对比方式。不同 LLVM 版本下运行:
clang --target=riscv64 --target-help | grep -E '^(rv|z|s|_z|_s)'
重点关注三类内容:
-
rv64imafdc等基础字符串是否完整列出:LLVM 22 起已将Zcf/Zcd从隐式启用改为显式要求+zcf,旧版(如 15.x)可能不显示但实际能 parse -
rva20u64这类 profile 名是否出现:LLVM 22 新增了rva22u64、rvb23u64等,老版本只到rva20u64 -
zkn1、zba、zicond等扩展是否在列表中:LLVM 21 默认不启用加密扩展,22 起才在RISCVISAInfo.cpp中加入zkn*展开规则
查 llvm-config --version 和源码提交哈希确认真实能力边界
help 输出只是前端展示,真正决定支持与否的是后端实现。必须交叉验证:
- 运行
llvm-config --version得到类似22.1.4的结果,再查对应 release tag 的lib/Target/RISCV/RISCV.td文件 - 搜索
def Zkn1或let ISAExt = "zkn1":若存在且无let Unsupported = 1,说明该扩展已注册进 IR 层 - 若看到
let AssemblerPredicate = ...但无ISAExt,说明仅汇编器识别(如部分Zicbom实现),IR 层无法用 intrinsic 调用 - 注意:GitHub 上 master 分支的
RISCV.td可能比你本地22.1.4多出未合入的实验性扩展(如Zfh),不能直接对标
用 -print-enabled-extensions 验证运行时实际解析结果
这个命令反映的是 clang 前端最终传给后端的扩展集合,比 --target-help 更贴近真实编译行为:
clang --target=riscv64-unknown-elf -march=rv64gc_zkn1 -print-enabled-extensions
输出差异揭示关键变化:
- LLVM 21:即使写了
-march=rv64gc_zkn1,也可能只输出g c f d,因为zkn1未在RISCVISAInfo.cpp中定义展开规则 - LLVM 22:同一命令会明确列出
zkn1 zkr zkne,前提是没漏掉--target或-menable-experimental-extensions(后者对厂商自定义xkrypto必需) - 若输出含
zba但编译 intrinsic 报错use of unknown builtin,说明头文件或BuiltinsRISCV.def未同步更新,不是 help 列表误导,而是工具链组件版本不一致
真正容易被忽略的点是:同一 -march 字符串在不同版本下激活的子模块可能完全不同
比如 rv64gc_zba:
- 在 LLVM 20 中,
llc -mtriple=riscv64 -march=rv64gc_zba --print-isas可能根本不识别zba,报unsupported architecture extension - 在 LLVM 22.1.0 中,它能解析并激活
Zba模块,但__riscv_add_uwintrinsic 可能尚未注册,需查BuiltinsRISCV.def - 在 LLVM 22.1.4 中,该 intrinsic 已存在,但若你用的是系统包管理器安装的 clang(如 Fedora 44 自带的
clang-22.1.0),实际仍可能是旧版头文件
所以别只信文档或 help 输出——版本号、源码哈希、-print-enabled-extensions、llc --print-isas、实际 intrinsic 编译四者缺一不可。

















