[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-06 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea closed 
https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Pavel Iliin via cfe-commits

https://github.com/ilinpv approved this pull request.

Thanks for tests!

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea updated 
https://github.com/llvm/llvm-project/pull/83887

>From f11c97d7f7f67edaf6de4390bcceb13dfea376a1 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Mon, 4 Mar 2024 18:12:22 +
Subject: [PATCH] [FMV] Allow target version definitions in any order.

This patch fixes #71698. It allows defining the default target
version prior to other version definitions without raising
semantic errors.
---
 clang/lib/Sema/SemaDecl.cpp  | 15 +--
 clang/test/CodeGen/attr-target-version.c | 56 
 clang/test/Sema/attr-target-version.c| 25 ---
 3 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3ae78748a4e499..bd3235ea7efb92 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11429,6 +11429,16 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
  bool ,
  NamedDecl *,
  LookupResult ) {
+  assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+
+  // The definitions should be allowed in any order. If we have discovered
+  // a new target version and the preceeding was the default, then add the
+  // corresponding attribute to it.
+  if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
+  NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
+OldFD->addAttr(TargetVersionAttr::CreateImplicit(S.Context, "default",
+ OldFD->getSourceRange()));
+
   const auto *NewTA = NewFD->getAttr();
   const auto *NewTVA = NewFD->getAttr();
   const auto *OldTA = OldFD->getAttr();
@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
+  (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
 Redeclaration = true;
 OldDecl = OldFD;
 OldFD->setIsMultiVersion();
diff --git a/clang/test/CodeGen/attr-target-version.c 
b/clang/test/CodeGen/attr-target-version.c
index 56a42499d0a7ca..ae1a8772f6cc07 100644
--- a/clang/test/CodeGen/attr-target-version.c
+++ b/clang/test/CodeGen/attr-target-version.c
@@ -94,16 +94,16 @@ int hoo(void) {
 // CHECK: @fmv_one.ifunc = weak_odr alias i32 (), ptr @fmv_one
 // CHECK: @fmv_two.ifunc = weak_odr alias i32 (), ptr @fmv_two
 // CHECK: @fmv_e.ifunc = weak_odr alias i32 (), ptr @fmv_e
+// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline
 // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d
-// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver
 // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver
 // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver
 // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver
+// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver
 // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver
-// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 //.
 // CHECK: Function Attrs: noinline nounwind optnone
 // CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng
@@ -238,11 +238,18 @@ int hoo(void) {
 // CHECK-NEXT:ret i32 111
 //
 //
-// CHECK: Function Attrs: noinline nounwind optnone
-// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs
-// CHECK-SAME: () #[[ATTR2]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:ret void
+// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
+// CHECK-NEXT:  resolver_entry:
+// CHECK-NEXT:call void @__init_cpu_features_resolver()
+// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
+// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
+// CHECK-NEXT:br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label 
[[RESOLVER_ELSE:%.*]]
+// CHECK:   resolver_return:
+// CHECK-NEXT:ret ptr @fmv_c._Mssbs
+// CHECK:   resolver_else:
+// CHECK-NEXT:ret ptr @fmv_c.default
 //
 //
 // CHECK: Function Attrs: noinline nounwind optnone
@@ -405,20 +412,6 @@ int hoo(void) {
 // CHECK-NEXT:ret ptr @fmv_d.default
 //
 //
-// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
-// CHECK-NEXT:  resolver_entry:
-// CHECK-NEXT:call void @__init_cpu_features_resolver()
-// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8

[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea edited 
https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Alexandros Lamprineas via cfe-commits


@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||

labrinea wrote:

As far as I can tell yes, this is astatic function with exactly one call site.

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Pavel Iliin via cfe-commits


@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||

ilinpv wrote:

Seems we are changing "target" attribute semantic here as well that we would 
like to avoid, why are we sure that !OldFD->isMultiVersion() is always true ?

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Pavel Iliin via cfe-commits


@@ -11429,6 +11429,16 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
  bool ,
  NamedDecl *,
  LookupResult ) {
+  assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+
+  // The definitions should be allowed in any order. If we have discovered
+  // a new target version and the preceeding was the default, then add the
+  // corresponding attribute to it.
+  if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&

ilinpv wrote:

Should it work for case target_version("default") declared first? It would good 
to add tests for various orders of function definition and target_version 
attributes. 

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Pavel Iliin via cfe-commits

https://github.com/ilinpv requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-05 Thread Pavel Iliin via cfe-commits

https://github.com/ilinpv edited https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread via cfe-commits

https://github.com/DanielKristofKiss approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread Jon Roelofs via cfe-commits

https://github.com/jroelofs approved this pull request.

Thank you, this is great!

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea updated 
https://github.com/llvm/llvm-project/pull/83887

>From 65a192641b5856714b9247372d9c471e03520762 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Mon, 4 Mar 2024 18:12:22 +
Subject: [PATCH] [FMV] Allow target version definitions in any order.

This patch fixes #71698. It allows defining the default target
version prior to other version definitions without raising
semantic errors.
---
 clang/lib/Sema/SemaDecl.cpp  | 15 +--
 clang/test/CodeGen/attr-target-version.c | 56 
 clang/test/Sema/attr-target-version.c|  5 +--
 3 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3ae78748a4e499..bd3235ea7efb92 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11429,6 +11429,16 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
  bool ,
  NamedDecl *,
  LookupResult ) {
+  assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+
+  // The definitions should be allowed in any order. If we have discovered
+  // a new target version and the preceeding was the default, then add the
+  // corresponding attribute to it.
+  if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
+  NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
+OldFD->addAttr(TargetVersionAttr::CreateImplicit(S.Context, "default",
+ OldFD->getSourceRange()));
+
   const auto *NewTA = NewFD->getAttr();
   const auto *NewTVA = NewFD->getAttr();
   const auto *OldTA = OldFD->getAttr();
@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
+  (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
 Redeclaration = true;
 OldDecl = OldFD;
 OldFD->setIsMultiVersion();
diff --git a/clang/test/CodeGen/attr-target-version.c 
b/clang/test/CodeGen/attr-target-version.c
index 56a42499d0a7ca..ae1a8772f6cc07 100644
--- a/clang/test/CodeGen/attr-target-version.c
+++ b/clang/test/CodeGen/attr-target-version.c
@@ -94,16 +94,16 @@ int hoo(void) {
 // CHECK: @fmv_one.ifunc = weak_odr alias i32 (), ptr @fmv_one
 // CHECK: @fmv_two.ifunc = weak_odr alias i32 (), ptr @fmv_two
 // CHECK: @fmv_e.ifunc = weak_odr alias i32 (), ptr @fmv_e
+// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline
 // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d
-// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver
 // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver
 // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver
 // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver
+// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver
 // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver
-// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 //.
 // CHECK: Function Attrs: noinline nounwind optnone
 // CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng
@@ -238,11 +238,18 @@ int hoo(void) {
 // CHECK-NEXT:ret i32 111
 //
 //
-// CHECK: Function Attrs: noinline nounwind optnone
-// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs
-// CHECK-SAME: () #[[ATTR2]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:ret void
+// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
+// CHECK-NEXT:  resolver_entry:
+// CHECK-NEXT:call void @__init_cpu_features_resolver()
+// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
+// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
+// CHECK-NEXT:br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label 
[[RESOLVER_ELSE:%.*]]
+// CHECK:   resolver_return:
+// CHECK-NEXT:ret ptr @fmv_c._Mssbs
+// CHECK:   resolver_else:
+// CHECK-NEXT:ret ptr @fmv_c.default
 //
 //
 // CHECK: Function Attrs: noinline nounwind optnone
@@ -405,20 +412,6 @@ int hoo(void) {
 // CHECK-NEXT:ret ptr @fmv_d.default
 //
 //
-// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
-// CHECK-NEXT:  resolver_entry:
-// CHECK-NEXT:call void @__init_cpu_features_resolver()
-// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
-// 

[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff bd7bce2c8465e9cb36a823846a52c9f553502575 
5a717769aa20dfbbaa8edd4bcd3048ebedee20a2 -- clang/lib/Sema/SemaDecl.cpp 
clang/test/CodeGen/attr-target-version.c clang/test/Sema/attr-target-version.c
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 81c5a11c58..bd3235ea7e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11436,8 +11436,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   // corresponding attribute to it.
   if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
   NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
-OldFD->addAttr(TargetVersionAttr::CreateImplicit(
-S.Context, "default", OldFD->getSourceRange()));
+OldFD->addAttr(TargetVersionAttr::CreateImplicit(S.Context, "default",
+ OldFD->getSourceRange()));
 
   const auto *NewTA = NewFD->getAttr();
   const auto *NewTVA = NewFD->getAttr();

``




https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread Alexandros Lamprineas via cfe-commits

labrinea wrote:

I appreciate there's some code repetition between 
`CheckTargetCausesMultiVersioning` and `CheckMultiVersionAdditionalDecl`. 
Perhaps they deserve some refactoring in a separate patch. Please advise if you 
have any suggestions for moving the fix elsewhere.

https://github.com/llvm/llvm-project/pull/83887
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Alexandros Lamprineas (labrinea)


Changes

This patch fixes #71698. It allows defining the default target version 
prior to other version definitions without raising semantic errors.

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


3 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+12-3) 
- (modified) clang/test/CodeGen/attr-target-version.c (+28-28) 
- (modified) clang/test/Sema/attr-target-version.c (+1-4) 


``diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3ae78748a4e499..81c5a11c58094e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11429,6 +11429,16 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
  bool ,
  NamedDecl *,
  LookupResult ) {
+  assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+
+  // The definitions should be allowed in any order. If we have discovered
+  // a new target version and the preceeding was the default, then add the
+  // corresponding attribute to it.
+  if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
+  NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
+OldFD->addAttr(TargetVersionAttr::CreateImplicit(
+S.Context, "default", OldFD->getSourceRange()));
+
   const auto *NewTA = NewFD->getAttr();
   const auto *NewTVA = NewFD->getAttr();
   const auto *OldTA = OldFD->getAttr();
@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
+  (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
 Redeclaration = true;
 OldDecl = OldFD;
 OldFD->setIsMultiVersion();
diff --git a/clang/test/CodeGen/attr-target-version.c 
b/clang/test/CodeGen/attr-target-version.c
index 56a42499d0a7ca..ae1a8772f6cc07 100644
--- a/clang/test/CodeGen/attr-target-version.c
+++ b/clang/test/CodeGen/attr-target-version.c
@@ -94,16 +94,16 @@ int hoo(void) {
 // CHECK: @fmv_one.ifunc = weak_odr alias i32 (), ptr @fmv_one
 // CHECK: @fmv_two.ifunc = weak_odr alias i32 (), ptr @fmv_two
 // CHECK: @fmv_e.ifunc = weak_odr alias i32 (), ptr @fmv_e
+// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline
 // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d
-// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver
 // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver
 // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver
 // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver
+// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver
 // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver
-// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 //.
 // CHECK: Function Attrs: noinline nounwind optnone
 // CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng
@@ -238,11 +238,18 @@ int hoo(void) {
 // CHECK-NEXT:ret i32 111
 //
 //
-// CHECK: Function Attrs: noinline nounwind optnone
-// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs
-// CHECK-SAME: () #[[ATTR2]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:ret void
+// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
+// CHECK-NEXT:  resolver_entry:
+// CHECK-NEXT:call void @__init_cpu_features_resolver()
+// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
+// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
+// CHECK-NEXT:br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label 
[[RESOLVER_ELSE:%.*]]
+// CHECK:   resolver_return:
+// CHECK-NEXT:ret ptr @fmv_c._Mssbs
+// CHECK:   resolver_else:
+// CHECK-NEXT:ret ptr @fmv_c.default
 //
 //
 // CHECK: Function Attrs: noinline nounwind optnone
@@ -405,20 +412,6 @@ int hoo(void) {
 // CHECK-NEXT:ret ptr @fmv_d.default
 //
 //
-// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
-// CHECK-NEXT:  resolver_entry:
-// CHECK-NEXT:call void @__init_cpu_features_resolver()
-// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
-// CHECK-NEXT:[[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
-// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
-// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
-// 

[clang] [FMV] Allow target version definitions in any order. (PR #83887)

2024-03-04 Thread Alexandros Lamprineas via cfe-commits

https://github.com/labrinea created 
https://github.com/llvm/llvm-project/pull/83887

This patch fixes #71698. It allows defining the default target version prior to 
other version definitions without raising semantic errors.

>From 5a717769aa20dfbbaa8edd4bcd3048ebedee20a2 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Mon, 4 Mar 2024 18:12:22 +
Subject: [PATCH] [FMV] Allow target version definitions in any order.

This patch fixes #71698. It allows defining the default target
version prior to other version definitions without raising
semantic errors.
---
 clang/lib/Sema/SemaDecl.cpp  | 15 +--
 clang/test/CodeGen/attr-target-version.c | 56 
 clang/test/Sema/attr-target-version.c|  5 +--
 3 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3ae78748a4e499..81c5a11c58094e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11429,6 +11429,16 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
  bool ,
  NamedDecl *,
  LookupResult ) {
+  assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
+
+  // The definitions should be allowed in any order. If we have discovered
+  // a new target version and the preceeding was the default, then add the
+  // corresponding attribute to it.
+  if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
+  NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
+OldFD->addAttr(TargetVersionAttr::CreateImplicit(
+S.Context, "default", OldFD->getSourceRange()));
+
   const auto *NewTA = NewFD->getAttr();
   const auto *NewTVA = NewFD->getAttr();
   const auto *OldTA = OldFD->getAttr();
@@ -11455,9 +11465,8 @@ static bool CheckTargetCausesMultiVersioning(Sema , 
FunctionDecl *OldFD,
   }
 
   // If this is 'default', permit the forward declaration.
-  if (!OldFD->isMultiVersion() &&
-  ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
-   (NewTVA && NewTVA->isDefaultVersion() && !OldTVA))) {
+  if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
+  (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
 Redeclaration = true;
 OldDecl = OldFD;
 OldFD->setIsMultiVersion();
diff --git a/clang/test/CodeGen/attr-target-version.c 
b/clang/test/CodeGen/attr-target-version.c
index 56a42499d0a7ca..ae1a8772f6cc07 100644
--- a/clang/test/CodeGen/attr-target-version.c
+++ b/clang/test/CodeGen/attr-target-version.c
@@ -94,16 +94,16 @@ int hoo(void) {
 // CHECK: @fmv_one.ifunc = weak_odr alias i32 (), ptr @fmv_one
 // CHECK: @fmv_two.ifunc = weak_odr alias i32 (), ptr @fmv_two
 // CHECK: @fmv_e.ifunc = weak_odr alias i32 (), ptr @fmv_e
+// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv_inline.ifunc = weak_odr alias i32 (), ptr @fmv_inline
 // CHECK: @fmv_d.ifunc = internal alias i32 (), ptr @fmv_d
-// CHECK: @fmv_c.ifunc = weak_odr alias void (), ptr @fmv_c
 // CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver
 // CHECK: @fmv_one = weak_odr ifunc i32 (), ptr @fmv_one.resolver
 // CHECK: @fmv_two = weak_odr ifunc i32 (), ptr @fmv_two.resolver
 // CHECK: @fmv_e = weak_odr ifunc i32 (), ptr @fmv_e.resolver
+// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 // CHECK: @fmv_inline = weak_odr ifunc i32 (), ptr @fmv_inline.resolver
 // CHECK: @fmv_d = internal ifunc i32 (), ptr @fmv_d.resolver
-// CHECK: @fmv_c = weak_odr ifunc void (), ptr @fmv_c.resolver
 //.
 // CHECK: Function Attrs: noinline nounwind optnone
 // CHECK-LABEL: define {{[^@]+}}@fmv._MflagmMfp16fmlMrng
@@ -238,11 +238,18 @@ int hoo(void) {
 // CHECK-NEXT:ret i32 111
 //
 //
-// CHECK: Function Attrs: noinline nounwind optnone
-// CHECK-LABEL: define {{[^@]+}}@fmv_c._Mssbs
-// CHECK-SAME: () #[[ATTR2]] {
-// CHECK-NEXT:  entry:
-// CHECK-NEXT:ret void
+// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
+// CHECK-NEXT:  resolver_entry:
+// CHECK-NEXT:call void @__init_cpu_features_resolver()
+// CHECK-NEXT:[[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
+// CHECK-NEXT:[[TMP3:%.*]] = and i1 true, [[TMP2]]
+// CHECK-NEXT:br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label 
[[RESOLVER_ELSE:%.*]]
+// CHECK:   resolver_return:
+// CHECK-NEXT:ret ptr @fmv_c._Mssbs
+// CHECK:   resolver_else:
+// CHECK-NEXT:ret ptr @fmv_c.default
 //
 //
 // CHECK: Function Attrs: noinline nounwind optnone
@@ -405,20 +412,6 @@ int hoo(void) {
 // CHECK-NEXT:ret ptr @fmv_d.default
 //
 //
-// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat {
-// CHECK-NEXT:  resolver_entry:
-// CHECK-NEXT:call void