| ... | ... | @@ -547,7 +547,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 547 | 547 | } else if (handle_is_ptr(return_type) && |
| 548 | 548 | calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) |
| 549 | 549 | { |
| 550 | | addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); |
| 550 | // We do not add the sret attribute, because it would require the return type to be void, |
| 551 | // and we want the return value to return the sret pointer, to work around LLVM Coroutine |
| 552 | // transformation passes not understanding the data dependency. |
| 553 | //addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); |
| 551 | 554 | addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull"); |
| 552 | 555 | } |
| 553 | 556 | |
| ... | ... | @@ -1616,7 +1619,9 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns |
| 1616 | 1619 | if (calling_convention_does_first_arg_return(g->cur_fn->type_entry->data.fn.fn_type_id.cc)) { |
| 1617 | 1620 | assert(g->cur_ret_ptr); |
| 1618 | 1621 | gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value); |
| 1619 | | LLVMBuildRetVoid(g->builder); |
| 1622 | // as a workaround for LLVM coroutines not understanding instruction dependencies, |
| 1623 | // we return the sret pointer argument instead of returning void |
| 1624 | LLVMBuildRet(g->builder, g->cur_ret_ptr); |
| 1620 | 1625 | } else { |
| 1621 | 1626 | LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, ""); |
| 1622 | 1627 | LLVMBuildRet(g->builder, by_val_value); |
| ... | ... | @@ -2775,7 +2780,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2775 | 2780 | } else if (!ret_has_bits) { |
| 2776 | 2781 | return nullptr; |
| 2777 | 2782 | } else if (first_arg_ret) { |
| 2778 | | return instruction->tmp_ptr; |
| 2783 | // instead of returning instruction->tmp_ptr here, we trust that the function returned the first arg. |
| 2784 | // this is a workaround for llvm coroutines not understanding the data dependency |
| 2785 | return result; |
| 2779 | 2786 | } else { |
| 2780 | 2787 | return result; |
| 2781 | 2788 | } |