Index: include/clang/CodeGen/CGFunctionInfo.h =================================================================== --- include/clang/CodeGen/CGFunctionInfo.h +++ include/clang/CodeGen/CGFunctionInfo.h @@ -544,6 +544,8 @@ CGFunctionInfo() : Required(RequiredArgs::All) {} + bool NonPODStructReturn = true; + public: static CGFunctionInfo *create(unsigned llvmCC, bool instanceMethod, @@ -710,6 +712,9 @@ i->Profile(ID); } } + + void setNonPODStructReturn(bool Val) { NonPODStructReturn = Val; } + bool getNonPODStructReturn() const { return NonPODStructReturn; } }; } // end namespace CodeGen Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1984,7 +1984,12 @@ // Attach attributes to sret. if (IRFunctionArgs.hasSRetArg()) { llvm::AttrBuilder SRETAttrs; - SRETAttrs.addAttribute(llvm::Attribute::StructRet); + if (!FI.getNonPODStructReturn()) { + const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl(); + if (RD && RD->isPOD()) + SRETAttrs.addAttribute(llvm::Attribute::StructRet); + } else + SRETAttrs.addAttribute(llvm::Attribute::StructRet); hasUsedSRet = true; if (RetAI.getInReg()) SRETAttrs.addAttribute(llvm::Attribute::InReg); Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -4923,6 +4923,8 @@ if (!::classifyReturnType(getCXXABI(), FI, *this)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + FI.setNonPODStructReturn(Kind != Win64); + for (auto &it : FI.arguments()) it.info = classifyArgumentType(it.type); } Index: test/CodeGen/arm64-microsoft-arguments.cpp =================================================================== --- /dev/null +++ test/CodeGen/arm64-microsoft-arguments.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple aarch64-windows -ffreestanding -emit-llvm \ +// RUN: -x c++ -o - %s | FileCheck %s + +struct pod { int a, b, c, d, e; }; + +struct non_pod { + int a; + non_pod() {} +}; + +struct pod s; +struct non_pod t; + +struct pod bar() { return s; } +struct non_pod foo() { return t; } + +// CHECK: define {{.*}} void @{{.*}}bar{{.*}}(%struct.pod* noalias sret %agg.result) +// CHECK: define {{.*}} void @{{.*}}foo{{.*}}(%struct.non_pod* noalias %agg.result)