| ... | @@ -2280,13 +2280,16 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable, | ... | @@ -2280,13 +2280,16 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable, |
| 2280 | return operand_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr; | 2280 | return operand_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr; |
| 2281 | } | 2281 | } |
| 2282 | | 2282 | |
| 2283 | ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; | | |
| 2284 | bool ret_type_has_bits = type_has_bits(ret_type); | | |
| 2285 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; | 2283 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 2286 | | 2284 | if (operand_has_bits && instruction->operand != nullptr) { |
| 2287 | if (ret_type_has_bits && !handle_is_ptr(ret_type)) { | 2285 | ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; |
| 2288 | // It's a scalar, so it didn't get written to the result ptr. Do that before the atomic rmw. | 2286 | bool need_store = instruction->operand->value.special != ConstValSpecialRuntime || !handle_is_ptr(ret_type); |
| 2289 | LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), g->cur_ret_ptr); | 2287 | if (need_store) { |
| | 2288 | // It didn't get written to the result ptr. We do that now so that we do not have to spill |
| | 2289 | // the return operand. |
| | 2290 | ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true); |
| | 2291 | gen_assign_raw(g, g->cur_ret_ptr, ret_ptr_type, ir_llvm_value(g, instruction->operand)); |
| | 2292 | } |
| 2290 | } | 2293 | } |
| 2291 | | 2294 | |
| 2292 | // Prepare to be suspended. We might end up not having to suspend though. | 2295 | // Prepare to be suspended. We might end up not having to suspend though. |
| ... | @@ -2387,6 +2390,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns | ... | @@ -2387,6 +2390,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns |
| 2387 | LLVMSetTailCall(call_inst, true); | 2390 | LLVMSetTailCall(call_inst, true); |
| 2388 | LLVMBuildRetVoid(g->builder); | 2391 | LLVMBuildRetVoid(g->builder); |
| 2389 | | 2392 | |
| | 2393 | g->cur_is_after_return = false; |
| | 2394 | |
| 2390 | return nullptr; | 2395 | return nullptr; |
| 2391 | } | 2396 | } |
| 2392 | if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) { | 2397 | if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) { |
| ... | @@ -7117,7 +7122,6 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -7117,7 +7122,6 @@ static void do_code_gen(CodeGen *g) { |
| 7117 | } | 7122 | } |
| 7118 | | 7123 | |
| 7119 | if (is_async) { | 7124 | if (is_async) { |
| 7120 | g->cur_is_after_return = false; | | |
| 7121 | g->cur_resume_block_count = 0; | 7125 | g->cur_resume_block_count = 0; |
| 7122 | | 7126 | |
| 7123 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; | 7127 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |