前回の続き。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 ^