diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index fcb3282d06..389ede91b7 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -549,7 +549,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { // Sret pointers must not be address 0 addLLVMArgAttr(llvm_fn, 0, "nonnull"); - addLLVMArgAttr(llvm_fn, 0, "sret"); + ZigLLVMAddSretAttr(llvm_fn, 0, get_llvm_type(g, return_type)); if (cc_want_sret_attr(cc)) { addLLVMArgAttr(llvm_fn, 0, "noalias"); } @@ -1972,7 +1972,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ switch (fn_walk->id) { case FnWalkIdAttrs: if (abi_class != X64CABIClass_MEMORY_nobyval) { - ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); + ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i, get_llvm_type(g, ty)); addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); } else if (g->zig_target->arch == ZigLLVM_aarch64 || g->zig_target->arch == ZigLLVM_aarch64_be) diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b4bdf7c033..55e507c6d0 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -798,7 +798,17 @@ void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_v AttrBuilder attr_builder; Type *llvm_type = unwrap(type_val); attr_builder.addByValAttr(llvm_type); - const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo, attr_builder); + const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo + 1, attr_builder); + func->setAttributes(new_attr_set); +} + +void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val) { + Function *func = unwrap(fn_ref); + const AttributeList attr_set = func->getAttributes(); + AttrBuilder attr_builder; + Type *llvm_type = unwrap(type_val); + attr_builder.addStructRetAttr(llvm_type); + const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo + 1, attr_builder); func->setAttributes(new_attr_set); } diff --git a/src/zig_llvm.h b/src/zig_llvm.h index fc9f39d9e9..c8ffa32e81 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -269,6 +269,7 @@ ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigL ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); +ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv);