diff options
| author | FourteenBrush <naessensarthur2@protonmail.com> | 2024-01-25 10:15:25 +0100 |
|---|---|---|
| committer | FourteenBrush <naessensarthur2@protonmail.com> | 2024-01-25 10:15:25 +0100 |
| commit | 967ccfc7ccc0f76c653ff4bb625bac60e89a7904 (patch) | |
| tree | f989a0f99337c7a0c93ee84249d73ec0c33e306d /src/llvm_backend_stmt.cpp | |
| parent | 712ae1c5ac73493498aa8e5076d91a6558337117 (diff) | |
| parent | 9cfd4a953e2a7d19237891993b643b2d1477f8b3 (diff) | |
Merge branch 'master' of https://github.com/FourteenBrush/Odin
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 9d688be6a..002fef881 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1846,9 +1846,25 @@ gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) { LLVMBuildRetVoid(p->builder); } else { LLVMValueRef ret_val = res.value; - ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type); - if (p->abi_function_type->ret.cast_type != nullptr) { - ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type); + LLVMTypeRef ret_type = p->abi_function_type->ret.type; + if (LLVMTypeRef cast_type = p->abi_function_type->ret.cast_type) { + ret_type = cast_type; + } + + if (LLVMGetTypeKind(ret_type) == LLVMStructTypeKind) { + LLVMTypeRef src_type = LLVMTypeOf(ret_val); + + if (p->temp_callee_return_struct_memory == nullptr) { + i64 max_align = gb_max(lb_alignof(ret_type), lb_alignof(src_type)); + p->temp_callee_return_struct_memory = llvm_alloca(p, ret_type, max_align); + } + // reuse the temp return value memory where possible + LLVMValueRef ptr = p->temp_callee_return_struct_memory; + LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), ""); + LLVMBuildStore(p->builder, ret_val, nptr); + ret_val = LLVMBuildLoad2(p->builder, ret_type, ptr, ""); + } else { + ret_val = OdinLLVMBuildTransmute(p, ret_val, ret_type); } lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); |