0

我一直试图通过 LLVM 让 .NET CIL 在多个平台上运行(我对 GPU 特别感兴趣)。我使用Mono.Compiler将 CIL 转换为 LLVM。

我无法让 AMDGCN 正常工作。对于一个简单的添加功能,我得到以下翻译后的 IR:

; ModuleID = 'bitout.bc'
source_filename = "llvmmodule_1"

define i32 @llvmmodule_1_AddMethod(i32, i32) {
entry:
  %A0 = alloca i32
  store i32 %0, i32* %A0
  %A1 = alloca i32
  store i32 %1, i32* %A1
  %T0 = load i32, i32* %A0
  %T1 = load i32, i32* %A1
  %T2 = add i32 %T0, %T1
  ret i32 %T2
}

我试过直接通过 libLLVM 的 TargetMachineEmitTo{File, MemoryBuffer} 以及间接通过 llc 发出它。

直接发射会产生一个 SIGSEGV:

Thread 1 "mono" received signal SIGSEGV, Segmentation fault.
0x00007fffeddadb1a in llvm::AMDGPUInstPrinter::getRegisterName(unsigned int) () from /usr/lib/libLLVM.so

这似乎是由于上述函数中的(负)缓冲区溢出(据我从 gdb 得知)。

llc 在 amdgcn 和 r600 上都失败了:

Allocation instruction pointer not in the stack address space!
  %A0 = alloca i32
Allocation instruction pointer not in the stack address space!
  %A1 = alloca i32

否则,llc 对于所有其他平台(wasm64 除外)都可以正常编译。

经过一番挖掘,我一直想知道这是否可能是因为没有在 alloca 中指定地址空间(尽管在AMDGPU 的 LLVM 指南中并没有真正解释这一点);所以我得到了翻译后的 IR 的副本并更改了地址空间。事实证明,如果分配在私有地址空间中,llc 会编译它——我猜它是作为堆栈空间工作的。但是我觉得很奇怪,尽管全局地址空间和区域地址空间都不起作用 - 我不应该能够在全局内存中分配空间吗?我在这里想念什么?

同样,我找不到创建采用地址空间的 alloca 指令的方法(BuildAlloca 不采用地址空间作为参数,我找不到任何提及替代方案的文档或示例)。

如果重要的话,我在 ArchLinux 上使用默认的 libLLVM(此时,llvm 8.0.1)。

4

1 回答 1

0

对于 AMDGPU Clang 使用以下代码来获取分配:

  LangAS getASTAllocaAddressSpace() const override {
    return getLangASFromTargetAS(
        getABIInfo().getDataLayout().getAllocaAddrSpace());
  }

在这里忽略 getLangASFromTargetAS 只是一种能够使其与 LangAS 枚举一起工作的方法。

要点是您需要从 DataLayout 中获取地址空间,而不是将其设置为零——但仅适用于 AMDGPU。

于 2019-11-11T10:21:58.097 回答