From 1f5bb99548d4164b3225cb145a44850909d6e0d7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 19 Mar 2023 00:51:57 +0000 Subject: [PATCH] Improve SysV ABI for multiple return values that fit into a single register; Fixes #2384 --- src/llvm_abi.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 1204050ef..9b8a39514 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -563,7 +563,7 @@ namespace lbAbiAmd64SysV { gb_internal void fixup(LLVMTypeRef t, Array *cls); gb_internal lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention); gb_internal Array classify(LLVMTypeRef t); - gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array const ®_classes); + gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array const ®_classes, LLVMTypeRef type); gb_internal LB_ABI_INFO(abi_info) { lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType); @@ -662,7 +662,7 @@ namespace lbAbiAmd64SysV { // the ABI rules for SysV reg_type = type; } else { - reg_type = llreg(c, cls); + reg_type = llreg(c, cls, type); } return lb_arg_type_direct(type, reg_type, nullptr, nullptr); } @@ -785,13 +785,17 @@ namespace lbAbiAmd64SysV { } - gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array const ®_classes) { + gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array const ®_classes, LLVMTypeRef type) { auto types = array_make(heap_allocator(), 0, reg_classes.count); for (isize i = 0; i < reg_classes.count; /**/) { RegClass reg_class = reg_classes[i]; switch (reg_class) { case RegClass_Int: - array_add(&types, LLVMIntTypeInContext(c, 64)); + if (reg_classes.count == 1) { + array_add(&types, LLVMIntTypeInContext(c, cast(unsigned)(lb_sizeof(type)*8))); + } else { + array_add(&types, LLVMIntTypeInContext(c, 64)); + } break; case RegClass_SSEFv: case RegClass_SSEDv: