[clang] b8a50e9 - [MS] Simplify rules for passing C++ records

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 24 16:29:55 PDT 2020


Author: Reid Kleckner
Date: 2020-09-24T16:29:47-07:00
New Revision: b8a50e920704436ddcbe0cc9d2020935d7e37095

URL: https://github.com/llvm/llvm-project/commit/b8a50e920704436ddcbe0cc9d2020935d7e37095
DIFF: https://github.com/llvm/llvm-project/commit/b8a50e920704436ddcbe0cc9d2020935d7e37095.diff

LOG: [MS] Simplify rules for passing C++ records

Regardless of the target architecture, we should always use the C rules
(RAA_Default) for records that "canBePassedInRegisters". Those are
trivially copyable things, and things marked with [[trivial_abi]].

This should be NFC, although it changes where the final decision about
x86_32 overaligned records is made. The current x86_32 C rules say that
overaligned things are passed indirectly, so there is no functional
difference.

Added: 
    

Modified: 
    clang/lib/CodeGen/MicrosoftCXXABI.cpp
    clang/test/CodeGenCXX/inalloca-overaligned.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 4f725793cb94..5fcb892f7fb8 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -816,16 +816,22 @@ class MicrosoftCXXABI : public CGCXXABI {
 
 CGCXXABI::RecordArgABI
 MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
+  // Use the default C calling convention rules for things that can be passed in
+  // registers, i.e. non-trivially copyable records or records marked with
+  // [[trivial_abi]].
+  if (RD->canPassInRegisters())
+    return RAA_Default;
+
   switch (CGM.getTarget().getTriple().getArch()) {
   default:
     // FIXME: Implement for other architectures.
     return RAA_Default;
 
   case llvm::Triple::thumb:
-    // Use the simple Itanium rules for now.
+    // Pass things indirectly for now because it is simple.
     // FIXME: This is incompatible with MSVC for arguments with a dtor and no
     // copy ctor.
-    return !RD->canPassInRegisters() ? RAA_Indirect : RAA_Default;
+    return RAA_Indirect;
 
   case llvm::Triple::x86: {
     // If the argument has *required* alignment greater than four bytes, pass
@@ -838,17 +844,12 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
 
     // If C++ prohibits us from making a copy, construct the arguments directly
     // into argument memory.
-    if (!RD->canPassInRegisters())
-      return RAA_DirectInMemory;
-
-    // Otherwise, construct the argument into a temporary and copy the bytes
-    // into the outgoing argument memory.
-    return RAA_Default;
+    return RAA_DirectInMemory;
   }
 
   case llvm::Triple::x86_64:
   case llvm::Triple::aarch64:
-    return !RD->canPassInRegisters() ? RAA_Indirect : RAA_Default;
+    return RAA_Indirect;
   }
 
   llvm_unreachable("invalid enum");

diff  --git a/clang/test/CodeGenCXX/inalloca-overaligned.cpp b/clang/test/CodeGenCXX/inalloca-overaligned.cpp
index 83eb4d1c61a4..60b9da4f0861 100644
--- a/clang/test/CodeGenCXX/inalloca-overaligned.cpp
+++ b/clang/test/CodeGenCXX/inalloca-overaligned.cpp
@@ -85,3 +85,27 @@ int pass_inalloca_both() {
 // CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8
 // CHECK: call x86_thiscallcc %struct.Both* @"??0Both@@QAE at XZ"(%struct.Both* [[TMP]])
 // CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca %argmem)
+
+// Here we have a type that is:
+// - overaligned
+// - not trivially copyable
+// - can be "passed in registers" due to [[trivial_abi]]
+// Clang should pass it directly.
+struct [[trivial_abi]] alignas(8) MyPtr {
+  MyPtr();
+  MyPtr(const MyPtr &o);
+  ~MyPtr();
+  int *ptr;
+};
+
+int receiveMyPtr(MyPtr o) { return *o.ptr; }
+
+// CHECK-LABEL: define dso_local i32 @"?receiveMyPtr@@Y{{.*}}"
+// CHECK-SAME: (%struct.MyPtr* %o)
+
+int passMyPtr() { return receiveMyPtr(MyPtr()); }
+
+// CHECK-LABEL: define dso_local i32 @"?passMyPtr@@Y{{.*}}"
+// CHECK: [[TMP:%[^ ]*]] = alloca %struct.MyPtr, align 8
+// CHECK: call x86_thiscallcc %struct.MyPtr* @"??0MyPtr@@QAE at XZ"(%struct.MyPtr* [[TMP]])
+// CHECK: call i32 @"?receiveMyPtr@@Y{{.*}}"(%struct.MyPtr* [[TMP]])


        


More information about the cfe-commits mailing list