[clang] [clang] Add value_type attr, use it to add noalias when pass-by-value. (PR #95004)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 10 08:57:36 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

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

Still needs proper docs.

---
Full diff: https://github.com/llvm/llvm-project/pull/95004.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+10) 
- (modified) clang/lib/CodeGen/CGCall.cpp (+4-3) 
- (added) clang/test/CodeGenCXX/value-type-attr.cpp (+40) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (+1) 


``````````diff
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index b70b0c8b836a5..811e1620f38d7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1811,6 +1811,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 65d82285b907b..55733734d1de2 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2744,9 +2744,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 99732694f72a5..4474a2c415bb2 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -201,6 +201,7 @@
 // CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
 // CHECK-NEXT: UnsafeBufferUsage (SubjectMatchRule_function)
 // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: ValueType (SubjectMatchRule_record)
 // CHECK-NEXT: VecReturn (SubjectMatchRule_record)
 // CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
 // CHECK-NEXT: WarnUnused (SubjectMatchRule_record)

``````````

</details>


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


More information about the cfe-commits mailing list