[PATCH] D49464: [COFF, ARM64] Mark only POD-type returns as SRET

Mandeep Singh Grang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 17 18:12:59 PDT 2018


mgrang created this revision.
mgrang added reviewers: mstorsjo, compnerd, rnk.
Herald added a reviewer: javed.absar.
Herald added subscribers: chrib, kristof.beyls.

Refer the MS ARM64 ABI Convention:
https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions#return-values

"For return-by-value that cannot be passed via registers, the caller shall reserve a
block of memory of sufficient size and alignment to hold the result.
The address of the memory block shall be passed as an additional argument to
the function in x8 for POD type, or in x0 (or x1 if $this is passed in x0) for non-POD type."

We mark a return as SRET only for POD types so that it uses X8. For non-POD types we do not mark SRET so that it uses X0.


https://reviews.llvm.org/D49464

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGen/arm64-microsoft-arguments.cpp


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)
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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49464.155998.patch
Type: text/x-patch
Size: 1476 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180718/6a353621/attachment.bin>


More information about the llvm-commits mailing list