FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V 64-bit LLVM Backendを試す

f:id:msyksphinz:20181111134229p:plain

LLVMについて理解するために、RISC-Vをネタにしていろいろ勉強してみたい。 Release 7.0では一応RISC-Vの32-bitと64-bit版がサポートされているようなので、ビルドに追加して様子を見てみる。

$ cmake -G Ninja -DCMAKE_BUILD_TYPE="Debug" -DLLVM_TARGETS_TO_BUILD="Cpu0" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" ../llvm-msyksphinz
$ cmake --build .

まずは、32‐bitと64‐bitで単純な関数をビルドして様子を見る。LLVM Backend tutorialに出てくるch3_1.cppをビルドして様子を見る。

  • ch3_1.cpp
int main()
{
  return 0;
}
$ riscv64-unknown-elf-gcc -c ../lbdex/input/ch3.cpp
$ riscv64-unknown-elf-objdump -d ch3.o

ch3.o:     file format elf64-littleriscv


Disassembly of section .text:

0000000000000000 <main>:
   0:   1141                    addi    sp,sp,-16
   2:   e422                    sd      s0,8(sp)
   4:   0800                    addi    s0,sp,16
   6:   4791                    li      a5,4
   8:   853e                    mv      a0,a5
   a:   6422                    ld      s0,8(sp)
   c:   0141                    addi    sp,sp,16
   e:   8082                    ret
  • LLVMの場合(32-bit)
$ ./bin/clang -target riscv32-unknown-linux-gnu -c ../lbdex/input/ch3.cpp -emit-llvm -o ch3.riscv32.bc
$ ./bin/llvm-dis ch3.riscv32.bc -o -
; ModuleID = 'ch3.riscv32.bc'
source_filename = "../lbdex/input/ch3.cpp"
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128"
target triple = "riscv32-unknown-linux-gnu"

; Function Attrs: noinline norecurse nounwind optnone
define dso_local i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  ret i32 0
}
$ ./bin/llc -march=riscv32 -relocation-model=pic -filetype=asm ch3.riscv32.bc -o -
main:                                   # @main
# %bb.0:                                # %entry
        addi    sp, sp, -16
        sw      ra, 12(sp)
        sw      s0, 8(sp)
        addi    s0, sp, 16
        sw      zero, -12(s0)
        mv      a0, zero
        lw      s0, 8(sp)
        lw      ra, 12(sp)
        addi    sp, sp, 16
        ret
  • LLVMの場合(64-bit)
$ ./bin/clang -target riscv64-unknown-linux-gnu -c ../lbdex/input/ch3.cpp -emit-llvm -o ch3.riscv64.bc
$ ./bin/llvm-dis ch3.riscv64.bc -o -
; ModuleID = 'ch3.riscv64.bc'
source_filename = "../lbdex/input/ch3.cpp"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
target triple = "riscv64-unknown-linux-gnu"

; Function Attrs: noinline norecurse nounwind optnone
define dso_local signext i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  ret i32 4
}
$ ./bin/llc -march=riscv64 -relocation-model=pic -filetype=asm ch3.riscv64.bc -o -
        .text
        .file   "ch3.cpp"
LLVM ERROR: Cannot select: t12: ch = store<(store 4 into %ir.retval), trunc to i32> t0, Constant:i64<0>, FrameIndex:i64<0>, undef:i64
  t11: i64 = Constant<0>
  t2: i64 = FrameIndex<0>
  t4: i64 = undef
In function: main

うーん、何故か64-bitでllcを実行すると落ちてしまう。どこかDAGが足りていないのか?解析するのにはどうしたらいいんだ?