多値

超必死こいて多値の実装をしていたわけですが、
よくみたらLLVMの多値( Multiple Return Value => MRV )って
2.3で新しく入った機能なのね!!!


でもって、

require leaf;

fun foo( n: int ): int, char
{
    n, n@char;
}

fun main(): int
{
    var a, b = foo(3);
    0;
}

ってなソースをコンパイルして

; ModuleID = 'test'

declare i32 @puti(i32)

declare i32 @putc(i32)

define { i32, i8 } @foo(i32 %arg_n) {
ENTRY:
    %cast42 = trunc i32 %arg_n to i8
    ret i32 %arg_n, i8 %cast42
}

define i32 @main() {
ENTRY:
    %ret64 = call { i32, i8 } @foo( i32 3 )
    %ret64_0 = getresult { i32, i8 } %ret64, 0
    %ret64_1 = getresult { i32, i8 } %ret64, 1
    ret i32 0
}

っつうアセンブリはかせたら

Call result #1 has unhandled type i8
llc[0xaca454]
/lib64/libc.so.6[0x35796322a0]
/lib64/libc.so.6(gsignal+0x35)[0x3579632215]
/lib64/libc.so.6(abort+0x183)[0x3579633d83]
llc(_ZN4llvm7CCState17AnalyzeCallResultEPNS_6SDNodeEPFbjjj
NS_11CCValAssign7LocInfoENS_3ISD10ArgFlagsTyERS0_E+0x138)[
0x7ecbf8]
llc(_ZN4llvm17X86TargetLowering15LowerCallResultENS_9SDOpe
randES1_PNS_6SDNodeEjRNS_12SelectionDAGE+0xf5)[0x79b5f5]
llc(_ZN4llvm17X86TargetLowering9LowerCALLENS_9SDOperandERN
S_12SelectionDAGE+0x2bf0)[0x7a8b00]
llc(_ZN4llvm17X86TargetLowering14LowerOperationENS_9SDOper
andERNS_12SelectionDAGE+0x37f)[0x7bdf4f]
llc[0x89909f]
llc[0x8917ab]
llc[0x8918f0]
llc(_ZN4llvm12SelectionDAG8LegalizeEv+0x1ae)[0x89245e]
llc(_ZN4llvm16SelectionDAGISel17CodeGenAndEmitDAGERNS_12Se
lectionDAGE+0x74)[0x843e24]
llc(_ZN4llvm16SelectionDAGISel16SelectBasicBlockEPNS_10Bas
icBlockERNS_15MachineFunctionERNS_20FunctionLoweringInfoE+
0xe1)[0x8642b1]
llc(_ZN4llvm16SelectionDAGISel13runOnFunctionERNS_8Functio
nE+0x24e)[0x8661ee]
llc(_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE+
0x1db)[0xa6eedb]
llc(_ZN4llvm23FunctionPassManagerImpl3runERNS_8FunctionE+0
x21d)[0xa6f54d]
llc(_ZN4llvm19FunctionPassManager3runERNS_8FunctionE+0x3e)
[0xa6f6be]
llc(main+0xf39)[0x4d7cf9]
/lib64/libc.so.6(__libc_start_main+0xfa)[0x357961e32a]
llc(_ZNSt8ios_base4InitD1Ev+0x41)[0x4d63a9]
Tool returned error code!

なんかトオリマセン!!

Call result #1 has unhandled type i8

ってなんですか? サポートしてないってこと?
と思って

require leaf;

fun foo( n: int ): int, int
{
    n, n;
}

fun main(): int
{
    var a, b = foo(3);
    0;
}

として

; ModuleID = 'test'

declare i32 @puti(i32)

declare i32 @putc(i32)

define { i32, i32 } @foo(i32 %arg_n) {
ENTRY:
    ret i32 %arg_n, i32 %arg_n
}

define i32 @main() {
ENTRY:
    %ret62 = call { i32, i32 } @foo( i32 3 )
    %ret62_0 = getresult { i32, i32 } %ret62, 0
    %ret62_1 = getresult { i32, i32 } %ret62, 1
    ret i32 0
}

という出力を実行してみたら、


普通にできた……


('A`)エェー