From 0ef3d96724104e32a6f0b5c4ab4fe8dc1e10635f Mon Sep 17 00:00:00 2001 From: kalsprite Date: Mon, 17 Aug 2026 21:53:37 -0700 Subject: [PATCH] fix reinterpretation on riscv --- src/llvm_backend_stmt.cpp | 6 +++++- tests/abi/gen.odin | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 9fbb2d15d..5cdfb21ce 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1,6 +1,8 @@ #define LB_ENABLE_BASIC_RVO true #define LB_ENABLE_ADVANCED_RVO build_context.enable_rvo +gb_internal LLVMValueRef lb_coerce_fields_load(lbProcedure *p, lbValue x, lbArgType const *arg); + // NOTE(bill): @RVO Check if a call expression returns by sret with a return type matching dst_type. // Returns the callee's function type if eligible for copy elision, nullptr otherwise. gb_internal lbFunctionType *lb_call_sret_eligible(lbProcedure *p, Ast *call_expr, Type *dst_type) { @@ -2587,7 +2589,9 @@ gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res, Toke ret_type = cast_type; } - if (LLVMGetTypeKind(ret_type) == LLVMStructTypeKind) { + if (ft->ret.coerce_offsets.count > 0) { + ret_val = lb_coerce_fields_load(p, res, &ft->ret); + } else if (LLVMGetTypeKind(ret_type) == LLVMStructTypeKind) { LLVMTypeRef src_type = LLVMTypeOf(ret_val); if (p->temp_callee_return_struct_memory == nullptr) { diff --git a/tests/abi/gen.odin b/tests/abi/gen.odin index a793faf30..6303ac09c 100644 --- a/tests/abi/gen.odin +++ b/tests/abi/gen.odin @@ -1441,6 +1441,11 @@ emit_main :: proc() -> string { w(&sb, "%s\tif %s_arg(s, 7) != 7 { return 1 }\n", ind, t.name) w(&sb, "%s\tif %s_chk(s) != 0 { return 1 }\n", ind, t.name) w(&sb, "%s\tif %s_ex(1,2,3,4,5,6,7, 1,2,3,4,5,6,7,8, s, 7) != 7 { return 1 }\n", ind, t.name) + w(&sb, "%s\tif %s_ex2(1,2,3,4,5,6,7,8,9, 1,2,3,4,5,6,7,8,9, s, 7) != 7 { return 1 }\n", ind, t.name) + w(&sb, "%s\tif %s_two(s, s, 7) != 7 { return 1 }\n", ind, t.name) + w(&sb, "%s\tif %s_can(1,2,3,4,5,6,7, 1,2,3,4,5,6,7,8, 0x1111111111111111, s, 0x2222222222222222, 7) != 7 { return 1 }\n", ind, t.name) + w(&sb, "%s\tif %s_can2(1,2,3,4,5,6,7,8,9,10,11, 0x1111111111111111, s, 0x2222222222222222, 7) != 7 { return 1 }\n", ind, t.name) + w(&sb, "%s\tif %s_back() != 0 { return 1 }\n", ind, t.name) w(&sb, "%s\tr := %s_ret()\n", ind, t.name) getters := odin_getters(t, "r") if len(getters) == 0 {