| ... | ... | @@ -503,7 +503,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 503 | 503 | // nothing to do |
| 504 | 504 | } else if (type_is_nonnull_ptr(return_type)) { |
| 505 | 505 | addLLVMAttr(llvm_fn, 0, "nonnull"); |
| 506 | | } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { |
| 506 | } else if (!is_async && want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { |
| 507 | 507 | // Sret pointers must not be address 0 |
| 508 | 508 | addLLVMArgAttr(llvm_fn, 0, "nonnull"); |
| 509 | 509 | addLLVMArgAttr(llvm_fn, 0, "sret"); |
| ... | ... | @@ -3241,8 +3241,13 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn |
| 3241 | 3241 | static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable, |
| 3242 | 3242 | IrInstructionReturnPtr *instruction) |
| 3243 | 3243 | { |
| 3244 | | src_assert(g->cur_ret_ptr != nullptr || !type_has_bits(instruction->base.value.type), |
| 3245 | | instruction->base.source_node); |
| 3244 | if (!type_has_bits(instruction->base.value.type)) |
| 3245 | return nullptr; |
| 3246 | src_assert(g->cur_ret_ptr != nullptr, instruction->base.source_node); |
| 3247 | if (fn_is_async(g->cur_fn)) { |
| 3248 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_arg_start, ""); |
| 3249 | return LLVMBuildLoad(g->builder, ptr_ptr, ""); |
| 3250 | } |
| 3246 | 3251 | return g->cur_ret_ptr; |
| 3247 | 3252 | } |
| 3248 | 3253 | |
| ... | ... | @@ -3506,6 +3511,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3506 | 3511 | if (ret_has_bits) { |
| 3507 | 3512 | ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, coro_arg_start + 1, ""); |
| 3508 | 3513 | } |
| 3514 | |
| 3515 | // Use the result location which is inside the frame if this is an async call. |
| 3516 | if (ret_has_bits) { |
| 3517 | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, coro_arg_start, ""); |
| 3518 | LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); |
| 3519 | } |
| 3509 | 3520 | } else if (callee_is_async) { |
| 3510 | 3521 | frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc); |
| 3511 | 3522 | awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_ret_ptr, |
| ... | ... | @@ -3513,6 +3524,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3513 | 3524 | if (ret_has_bits) { |
| 3514 | 3525 | ret_ptr = result_loc; |
| 3515 | 3526 | } |
| 3527 | |
| 3528 | // Use the call instruction's result location. |
| 3529 | if (ret_has_bits) { |
| 3530 | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, coro_arg_start, ""); |
| 3531 | LLVMBuildStore(g->builder, result_loc, ret_ptr_ptr); |
| 3532 | } |
| 3516 | 3533 | } |
| 3517 | 3534 | if (instruction->is_async || callee_is_async) { |
| 3518 | 3535 | assert(frame_result_loc != nullptr); |
| ... | ... | @@ -3525,10 +3542,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3525 | 3542 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, coro_awaiter_index, ""); |
| 3526 | 3543 | LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr); |
| 3527 | 3544 | |
| 3528 | | if (ret_has_bits) { |
| 3529 | | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, coro_arg_start, ""); |
| 3530 | | LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); |
| 3531 | | } |
| 3532 | 3545 | } |
| 3533 | 3546 | if (!instruction->is_async && !callee_is_async) { |
| 3534 | 3547 | if (first_arg_ret) { |