如何在 LLVM IR 中使用 RISC-V 向量 (RVV) 指令?

How do I use the RISC-V Vector (RVV) instructions in LLVM IR?

this presentation Kruppe and Espasa give an overview of the RISC-V Vector extension (RVV) and on slide 16中,他们展示了通过内部函数使用向量指令的 LLVM IR 示例,例如:

%vl = call i32 @llvm.riscv.vsetvl(i32 8)

在谈话时(2019 年 4 月),LLVM 对 V 扩展的支持是在 https://github.com/hanna-kruppe/rvv-llvm. However, that repository is archived now and the README file indicates that it is outdated since support for the RISC-V V extension is now developed upstream. I assume that this means that the features are now available from LLVM master at https://github.com/llvm/llvm-project 的树外开发的。

但是,当我拉出当前主控并构建它并尝试使用 llc 编译示例代码(使用 --mtriple=riscv32-unkown-none-rv32imv 指定目标)时,我得到以下错误:

error: ../llvm-project/build/bin/llc: test.ll:4:18: error: use of undefined value '@llvm.riscv.vsetvl'

V 扩展名似乎可用,因为 llc -march=riscv32 -mattr=help 列出了它:

Available features for this target:
...
  experimental-v           - 'V' (Vector Instructions).

我是否必须明确启用标记为实验性的目标功能?幻灯片中显示的这些矢量内在函数甚至出现在上游版本中吗?如果是,我该如何使用它们?如果不是,我该如何在 LLVM IR 中使用向量指令?


后续行动:在 this post Eli Friedman explains that target-specific intrinsics should be defined in include/llvm/IR/IntrinsicsRISCV.td, and indeed in the archived out-of-tree repository that file contains some vector-specific intrinsics which are not present in the upstream version 中。如果这些内在函数没有被移植到上游,那么使用 RISC-V 向量指令的正确方法是什么?

llvm/include/llvm/ADT/Triple.h中只定义了两个riscv三元组:riscv32和riscv64。

默认HasStdExtVexperimental-v对应的标志,在llvm/lib/Target/RISCV/RISCVSubtarget.h中初始化为false,如果你想使用这个扩展你需要启用这个功能。

Clangs 似乎也支持此功能。在 clang/lib/Driver/ToolChains/Arch/RISCV.cpp 中,您可以看到 march 支持 v 功能并为 llc.experimental-v 生成 experimental-v

include/llvm/IR/IntrinsicsRISCV.td 中没有关于 Vector 扩展的任何内容,但是您可以从标准 'V' Vector 中找到指令的描述 llvm/lib/Target/RISCV/RISCVInstrInfoV.td 中的扩展名。 它仍处于试验阶段。在 clang 中你也可以发现即使支持 v 扩展,在默认情况下你可以在 clang/lib/Driver/ToolChains/Arch/RISCV.cpp

中看到 // Currently LLVM supports only "mafdc".

我在 LLVM developper's mailing list 上提问:目前(2020 年 11 月)只有 MC 层(即汇编级)支持 LLVM 中的 RISC-V V 扩展(因此目前没有内在函数)。

但是,有一个 RFC and patch 添加了对向量加载、存储和整数加法内在函数的初始支持,以及生成 vsetvl[i] 指令所需的基础结构。