https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/95004

>From c3b6943c236990c9f0ba363b4335b3c0e048ef2c Mon Sep 17 00:00:00 2001
From: Florian Hahn <f...@fhahn.com>
Date: Mon, 10 Jun 2024 16:54:02 +0100
Subject: [PATCH 1/3] [clang] Add value_type attr, use it to add noalias when
 pass-by-value.

This adds an attribute version of -fpass-by-value-is-noalias (added in
a874d63344)

Still needs proper docs.
---
 clang/include/clang/Basic/Attr.td             | 10 +++++
 clang/lib/CodeGen/CGCall.cpp                  |  7 ++--
 clang/test/CodeGenCXX/value-type-attr.cpp     | 40 +++++++++++++++++++
 ...a-attribute-supported-attributes-list.test |  1 +
 4 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/value-type-attr.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 4d34346460561..4270f3ec5d6ab 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1972,6 +1972,16 @@ def TrivialABI : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def ValueType : InheritableAttr {
+  // This attribute does not have a C [[]] spelling because it requires the
+  // CPlusPlus language option.
+  let Spellings = [Clang<"value_type", 0>];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let Documentation = [TrivialABIDocs];
+  let LangOpts = [CPlusPlus];
+  let SimpleHandler = 1;
+}
+
 def MaxFieldAlignment : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7aa77e55dbfcc..fb4154eef303d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2797,9 +2797,10 @@ void CodeGenModule::ConstructAttributeList(StringRef 
Name,
         Attrs.addByValAttr(getTypes().ConvertTypeForMem(ParamType));
 
       auto *Decl = ParamType->getAsRecordDecl();
-      if (CodeGenOpts.PassByValueIsNoAlias && Decl &&
-          Decl->getArgPassingRestrictions() ==
-              RecordArgPassingKind::CanPassInRegs)
+      if (Decl && ((CodeGenOpts.PassByValueIsNoAlias &&
+                    Decl->getArgPassingRestrictions() ==
+                        RecordArgPassingKind::CanPassInRegs) ||
+                   Decl->hasAttr<ValueTypeAttr>()))
         // When calling the function, the pointer passed in will be the only
         // reference to the underlying object. Mark it accordingly.
         Attrs.addAttribute(llvm::Attribute::NoAlias);
diff --git a/clang/test/CodeGenCXX/value-type-attr.cpp 
b/clang/test/CodeGenCXX/value-type-attr.cpp
new file mode 100644
index 0000000000000..46938dd7d271a
--- /dev/null
+++ b/clang/test/CodeGenCXX/value-type-attr.cpp
@@ -0,0 +1,40 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 5
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions 
-fexceptions -emit-llvm -o - %s | FileCheck %s
+
+struct Small {
+  int *p;
+  Small();
+  ~Small();
+  Small(const Small &) noexcept;
+  Small &operator=(const Small &);
+};
+
+
+struct __attribute__((value_type)) SmallVT {
+  int *p;
+  SmallVT();
+  ~SmallVT();
+  SmallVT(const SmallVT &) noexcept;
+  SmallVT &operator=(const SmallVT &);
+};
+
+struct Large {
+  int *p;
+  int a[128];
+  Large();
+  ~Large();
+  Large(const Large &) noexcept;
+  Large &operator=(const Large &);
+};
+
+struct __attribute__((value_type)) LargeVT {
+  int *p;
+  int a[128];
+  LargeVT();
+  ~LargeVT();
+  LargeVT(const LargeVT &) noexcept;
+  LargeVT &operator=(const LargeVT &);
+};
+
+void foo(Small a, SmallVT b, Large c, LargeVT d) {}
+// CHECK: define void @_Z3foo5Small7SmallVT5Large7LargeVT(ptr noundef %a, ptr 
noalias noundef %b, ptr noundef %c, ptr noalias noundef %d)
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 55f196625770a..2bc34802c5f5b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -209,6 +209,7 @@
 // CHECK-NEXT: UnsafeBufferUsage (SubjectMatchRule_function, 
SubjectMatchRule_field)
 // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: VTablePointerAuthentication (SubjectMatchRule_record)
+// CHECK-NEXT: ValueType (SubjectMatchRule_record)
 // CHECK-NEXT: VecReturn (SubjectMatchRule_record)
 // CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
 // CHECK-NEXT: WarnUnused (SubjectMatchRule_record)

>From 82e6bdb714db9ceeab06a4b61a3748ba5926bc88 Mon Sep 17 00:00:00 2001
From: Florian Hahn <f...@fhahn.com>
Date: Fri, 14 Mar 2025 16:23:24 +0000
Subject: [PATCH 2/3] !fixup add attr docs.

---
 clang/include/clang/Basic/AttrDocs.td | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 34e7ff9612859..0fa733a1a2f94 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -9242,3 +9242,14 @@ Declares that a function potentially allocates heap 
memory, and prevents any pot
 of ``nonallocating`` by the compiler.
   }];
 }
+
+def ValueTypeDocs : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``value_type`` attribute can be used to mark user-defined types as 'value
+types'. When objects of value types are passed by-value to functions, the
+argument must be the only value referencing the passed object. This allows the
+optimizer to assume that no other pointers may alias the object when it is
+passed indirectly to a function..
+  }];
+}

>From e0ff9c786da3b27ad6fa9112beb58684ad6457af Mon Sep 17 00:00:00 2001
From: Florian Hahn <f...@fhahn.com>
Date: Fri, 14 Mar 2025 16:45:50 +0000
Subject: [PATCH 3/3] !fixup update wording

---
 clang/include/clang/Basic/AttrDocs.td | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 0fa733a1a2f94..4228bc1f7d888 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -9247,9 +9247,10 @@ def ValueTypeDocs : Documentation {
   let Category = DocCatDecl;
   let Content = [{
 The ``value_type`` attribute can be used to mark user-defined types as 'value
-types'. When objects of value types are passed by-value to functions, the
-argument must be the only value referencing the passed object. This allows the
-optimizer to assume that no other pointers may alias the object when it is
-passed indirectly to a function..
+types'. When objects of value types are passed value to functions, the objects
+are always considered to be formally copied into a new object. This means the
+argument itself must be the only value referencing the passed object. This
+allows the optimizer to assume that no other pointers may alias the object when
+it is passed indirectly to a function..
   }];
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to