[clang] [clang] Handle trivial_abi attribute for Microsoft ABI. (PR #88857)

Tobias Hieta via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 16 04:15:43 PDT 2024


https://github.com/tru updated https://github.com/llvm/llvm-project/pull/88857

>From 08214d87d1a7c83ea25eef3bf18de1568a20a152 Mon Sep 17 00:00:00 2001
From: Tobias Hieta <tobias.hieta at ubisoft.com>
Date: Tue, 16 Apr 2024 09:38:53 +0200
Subject: [PATCH] [clang] Handle trivial_abi attribute for Microsoft ABI.

Previously the trivial_abi was ignored for records when targetting
the microsoft abi, the MSVC rules where always enforced to ensure
compatibility with MSVC. This commit changes it to be closer to
the itanium abi when a record is marked with the trivial_abi attribute.

Fixes #87993
---
 clang/docs/ReleaseNotes.rst                |  5 ++++
 clang/lib/CodeGen/MicrosoftCXXABI.cpp      |  5 ++++
 clang/test/CodeGenCXX/trivial_abi_msvc.cpp | 31 ++++++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/trivial_abi_msvc.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76701dc723b6c3..2b653e5af6f5ae 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -63,6 +63,11 @@ ABI Changes in This Version
   MSVC uses a different mangling for these objects, compatibility is not affected.
   (#GH85423).
 
+- Records carrying the trivial_abi attribute are now returned directly in registers
+  in more cases when using the Microsoft ABI. It is not possible to pass trivial_abi
+  records between MSVC and Clang, so there is no ABI compatibility requirement. This
+  is an ABI break with old versions of Clang. (#GH87993)
+
 AST Dumping Potentially Breaking Changes
 ----------------------------------------
 
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d38a26940a3cb6..b930913badcd3f 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1105,6 +1105,11 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
 
 static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
                              CodeGenModule &CGM) {
+  // If the record is marked with the trivial_abi attribute, we don't
+  // have to conform to the standard MSVC ABI.
+  if (RD->hasAttr<TrivialABIAttr>())
+    return true;
+
   // On AArch64, HVAs that can be passed in registers can also be returned
   // in registers. (Note this is using the MSVC definition of an HVA; see
   // isPermittedToBeHomogeneousAggregate().)
diff --git a/clang/test/CodeGenCXX/trivial_abi_msvc.cpp b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
new file mode 100644
index 00000000000000..0af1d63acd1a5e
--- /dev/null
+++ b/clang/test/CodeGenCXX/trivial_abi_msvc.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: %[[STRUCT_TRIVIAL:.*]] = type { ptr }
+struct __attribute__((trivial_abi)) Trivial {
+  int *p;
+  Trivial() : p(0) {}
+  Trivial(const Trivial &) noexcept = default;
+};
+
+// CHECK-LABEL: define{{.*}} i64 @"?retTrivial@@YA?AUTrivial@@XZ"(
+// CHECK: %retval = alloca %[[STRUCT_TRIVIAL]], align 8
+// CHECK: %call = call noundef ptr @"??0Trivial@@QEAA at XZ"(ptr noundef nonnull align 8 dereferenceable(8) %retval)
+// CHECK: %coerce.dive = getelementptr inbounds %[[STRUCT_TRIVIAL]], ptr %retval, i32 0, i32 0
+// CHECK: %0 = load ptr, ptr %coerce.dive, align 8
+// CHECK: %coerce.val.pi = ptrtoint ptr %0 to i64
+// CHECK: ret i64 %coerce.val.pi
+Trivial retTrivial() {
+  Trivial s;
+  return s;
+}
+
+struct TrivialInstance {
+    Trivial instanceMethod();
+    static Trivial staticMethod();
+};
+
+// We need to make sure that instanceMethod has a sret return value since `this` will always go in the register.
+// CHECK-LABEL: define{{.*}} void @"?instanceMethod at TrivialInstance@@QEAA?AUTrivial@@XZ"({{.*}} sret(%struct.Trivial{{.*}}
+Trivial TrivialInstance::instanceMethod() { return {}; }
+// CHECK-LABEL: define{{.*}} i64 @"?staticMethod at TrivialInstance@@SA?AUTrivial@@XZ"(
+Trivial TrivialInstance::staticMethod() { return {}; }



More information about the cfe-commits mailing list