RV64の64ビットモードでLLVMがアセンブラを生成できるように格闘している。とりあえずサンプルプログラムとして以下を用意した。
xlen64_func.cpp
#include <stdint.h> int64_t func() { return 0x100; }
要点としては、0x100
の戻り値をint64_t
のデータ型で返せるか、というところだ。引数渡しのCalling Conventionまで一気にサポートすると大変なのでまずは一歩ずつ進める。
これをClangで処理してIRを出力すると以下のようなIRが作られる。
; Function Attrs: noinline nounwind optnone uwtable define dso_local i64 @_Z4funcv() #0 { entry: ret i64 16 }
さらに、llcのSelectionDAGによって以下のようなノードが生成された。
Enabling fast-isel Creating constant: t1: i64 = Constant<16> Creating constant: t2: i32 = Constant<1> Creating constant: t3: i32 = Constant<0> Creating constant: t4: i32 = Constant<16> Creating new node: t6: ch,glue = CopyToReg t0, Register:i32 $v0, Constant:i32<0> Creating new node: t8: ch,glue = CopyToReg t6, Register:i32 $v1, Constant:i32<16>, t6:1 Creating new node: t9: ch = MipsISD::Ret t8, Register:i32 $v0, Register:i32 $v1, t8:1
うーん?このConstant<1>
とかConstant<0>
はどこで使うんだ?実際、私のMYRISCVXの実装では、Constant<1>
は不要なはずだが...
Enabling fast-isel Creating constant: t1: i64 = Constant<16> Creating constant: t2: i32 = Constant<1> Creating constant: t3: i32 = Constant<0> Creating constant: t4: i32 = Constant<16> Return operand #1 has unhandled type i32 UNREACHABLE executed at /home/masayuki/others/llvm/llvm-myriscvx90/lib/CodeGen/CallingConvLower.cpp:130!
これはよく見てみるとMIPSでも同じような不要なノードが作成されている。何故だろう?