Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1984,7 +1984,13 @@ // Attach attributes to sret. if (IRFunctionArgs.hasSRetArg()) { llvm::AttrBuilder SRETAttrs; - SRETAttrs.addAttribute(llvm::Attribute::StructRet); + if (getTarget().getTriple().isOSWindows() && + getTarget().getTriple().getArch() == llvm::Triple::aarch64) { + 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: 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)