前回の続き。MYRISCVXのテストを追加する。
simple_main.cppをclangでコンパイルすると、以下のようなLLVM中間コードが生成される。
./bin/clang --target=riscv64-unknown-elf -c ../myriscvx-tests/tests/simple_main.cpp -emit-llvm -o - | ./bin/llvm-dis -o -
...
; 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 0
}
...
この中間表現をllcで処理してアセンブリ命令を出力するわけだが、上記のコードは以下のように変換されるはずだ。
... main: # @main # %bb.0: # %entry addi x2, x2, -4 addi x10, zero, 0 sw x10, 0(x2) addi x2, x2, 4 ret ...
入力としての中間コードと、出力としての想定するアセンブリ命令を1つにまとめて、テストを作る。
llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll
; 32ビット MYRISCVXでllcを実行。clangで生成したIRは、-O3を指定してある。
; RUN: llc -mtriple=myriscvx32 < %s \
; RUN: | FileCheck %s -check-prefix=MY32I
define dso_local i32 @main32_O3() local_unnamed_addr #0 {
; MY32I-LABEL: main32_O3:
; MY32I: # %bb.0:
; MY32I-NEXT: addi x10, zero, 0
; MY32I-NEXT: ret
entry:
ret i32 0
}
llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll
; 64ビット MYRISCVXでllcを実行。clangで生成したIRは、-O3を指定してある。
; RUN: llc -mtriple=myriscvx64 < %s \
; RUN: | FileCheck %s -check-prefix=MY64I
define dso_local i32 @main64_O3() local_unnamed_addr #0 {
; MY64I-LABEL: main64_O3:
; MY64I: # %bb.0:
; MY64I-NEXT: addi x10, zero, 0
; MY64I-NEXT: ret
entry:
ret i32 0
}
llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll
; 64ビット MYRISCVXでllcを実行。clangで生成したIRは、-O0を指定してある。
; RUN: llc -mtriple=myriscvx32 < %s \
; RUN: | FileCheck %s -check-prefix=MY32I
define dso_local signext i32 @main32() #0 {
; MY32I-LABEL: main32:
; MY32I: addi x2, x2, -4
; MY32I: addi x10, zero, 0
; MY32I: sw x10, 0(x2)
; MY32I: addi x2, x2, 4
; MY32I: ret
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
ret i32 0
}
llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll
; 64ビット MYRISCVXでllcを実行。clangで生成したIRは、-O0を指定してある。
; RUN: llc -mtriple=myriscvx64 < %s \
; RUN: | FileCheck %s -check-prefix=MY64I
define dso_local signext i32 @main64() #0 {
; MY64I-LABEL: main64:
; MY64I: addi x2, x2, -4
; MY64I: addi x10, zero, 0
; MY64I: sw x10, 0(x2)
; MY64I: addi x2, x2, 4
; MY64I: ret
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
ret i32 0
}
-check-prefix=で指定したラベルを元に生成されたコードとの比較を行っていく。上記の4つのテストが実行され、最終結果が表示される仕組みだ。実行してみる。
$ ./bin/llvm-lit -v ../llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll -- Testing: 1 tests, 1 threads -- PASS: LLVM :: CodeGen/MYRISCVX/simple_main.ll (1 of 1) Testing Time: 0.45s Expected Passes : 1
なんだかあまり変わり映えののない結果になったが、Passしているので良しとする。万が一テストに失敗した場合は以下のようにエラーログが表示される。
llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll
; 32ビット MYRISCVXでllcを実行。clangで生成したIRは、-O3を指定してある。
; RUN: llc -mtriple=myriscvx32 < %s \
; RUN: | FileCheck %s -check-prefix=MY32I
define dso_local i32 @main32_O3() local_unnamed_addr #0 {
; MY32I-LABEL: main32_O3:
; MY32I: # %bb.0:
; MY32I-NEXT: addi x10, zero, 0
; MY32I-NEXT: rett # 間違えてretをrettとしてしまった。
entry:
ret i32 0
}
実行すると以下のようにエラーが表示された。故意に間違えたエラーではあるが、正しく指摘されている。
Exit Code: 1
Command Output (stderr):
--
/home/msyksphinz/work/llvm/llvm-myriscvx80/test/CodeGen/MYRISCVX/simple_main.ll:51:10: error: MY64I: expected string not found in input
; MY64I: rett
^
<stdin>:60:2: note: scanning from here
ret
^