[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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

The latest ACLE allows it and further clarifies the following
in regards to the combination of the two attributes:

"If the `default` matches with another explicitly provided
 version in the same translation unit, then the compiler can
 emit only one function instead of the two. The explicitly
 provided version shall be preferred."

("default" refers to the default clone here)

https://github.com/ARM-software/acle/pull/310

>From 65bfc47298131d6fb5dfeed722dc3f2d9d85eadd Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Fri, 22 Mar 2024 17:21:13 +
Subject: [PATCH] [FMV] Allow mixing target_version with target_clones.

The latest ACLE allows it and further clarifies the following
in regards to the combination of the two attributes:

"If the `default` matches with another explicitly provided
 version in the same translation unit, then the compiler can
 emit only one function instead of the two. The explicitly
 provided version shall be preferred."

("default" refers to the default clone here)

https://github.com/ARM-software/acle/pull/310
---
 clang/include/clang/Basic/Attr.td |  14 +
 clang/lib/AST/ASTContext.cpp  |  15 +-
 clang/lib/CodeGen/CodeGenModule.cpp   | 105 ---
 clang/lib/Sema/SemaDecl.cpp   | 192 
 .../CodeGen/aarch64-mixed-target-attributes.c | 278 ++
 .../test/CodeGen/attr-target-clones-aarch64.c |  94 +++---
 .../CodeGenCXX/attr-target-clones-aarch64.cpp |  28 +-
 clang/test/Sema/attr-target-clones-aarch64.c  |   2 +-
 8 files changed, 539 insertions(+), 189 deletions(-)
 create mode 100644 clang/test/CodeGen/aarch64-mixed-target-attributes.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 3e03e55612645b..318d4e5ac5ba44 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3088,6 +3088,20 @@ def TargetClones : InheritableAttr {
 StringRef getFeatureStr(unsigned Index) const {
   return *(featuresStrs_begin() + Index);
 }
+bool isDefaultVersion(unsigned Index) const {
+  return getFeatureStr(Index) == "default";
+}
+void getFeatures(llvm::SmallVectorImpl &Out,
+ unsigned Index) const {
+  if (isDefaultVersion(Index)) return;
+  StringRef Features = getFeatureStr(Index);
+  SmallVector AttrFeatures;
+  Features.split(AttrFeatures, "+");
+  for (auto &Feature : AttrFeatures) {
+Feature = Feature.trim();
+Out.push_back(Feature);
+  }
+}
 // Given an index into the 'featuresStrs' sequence, compute a unique
 // ID to be used with function name mangling for the associated variant.
 // This mapping is necessary due to a requirement that the mangling ID
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index fcf801adeaf5ef..0b5f20a572a742 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13676,22 +13676,19 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap,
 Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
   } else if (const auto *TC = FD->getAttr()) {
 std::vector Features;
-StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
 if (Target->getTriple().isAArch64()) {
   // TargetClones for AArch64
-  if (VersionStr != "default") {
-SmallVector VersionFeatures;
-VersionStr.split(VersionFeatures, "+");
-for (auto &VFeature : VersionFeatures) {
-  VFeature = VFeature.trim();
+  llvm::SmallVector Feats;
+  TC->getFeatures(Feats, GD.getMultiVersionIndex());
+  for (StringRef Feat : Feats)
+if (Target->validateCpuSupports(Feat.str()))
   // Use '?' to mark features that came from AArch64 TargetClones.
-  Features.push_back((StringRef{"?"} + VFeature).str());
-}
-  }
+  Features.push_back("?" + Feat.str());
   Features.insert(Features.begin(),
   Target->getTargetOpts().FeaturesAsWritten.begin(),
   Target->getTargetOpts().FeaturesAsWritten.end());
 } else {
+  StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
   if (VersionStr.starts_with("arch="))
 TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
   else if (VersionStr != "default")
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index ac81df8cf7adfe..bc7d7ac561113b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3712,7 +3712,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
 // Forward declarations are emitted lazily on first use.
 if (!FD->doesThisDeclarationHaveABody()) {
   if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
-  !FD->isTargetVersionMultiVersi

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

2024-03-25 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Alexandros Lamprineas (labrinea)


Changes

The latest ACLE allows it and further clarifies the following
in regards to the combination of the two attributes:

"If the `default` matches with another explicitly provided
 version in the same translation unit, then the compiler can
 emit only one function instead of the two. The explicitly
 provided version shall be preferred."

("default" refers to the default clone here)

https://github.com/ARM-software/acle/pull/310

---

Patch is 47.24 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/86493.diff


8 Files Affected:

- (modified) clang/include/clang/Basic/Attr.td (+14) 
- (modified) clang/lib/AST/ASTContext.cpp (+6-9) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+50-55) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+129-63) 
- (added) clang/test/CodeGen/aarch64-mixed-target-attributes.c (+278) 
- (modified) clang/test/CodeGen/attr-target-clones-aarch64.c (+47-47) 
- (modified) clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp (+14-14) 
- (modified) clang/test/Sema/attr-target-clones-aarch64.c (+1-1) 


``diff
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 3e03e55612645b..318d4e5ac5ba44 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3088,6 +3088,20 @@ def TargetClones : InheritableAttr {
 StringRef getFeatureStr(unsigned Index) const {
   return *(featuresStrs_begin() + Index);
 }
+bool isDefaultVersion(unsigned Index) const {
+  return getFeatureStr(Index) == "default";
+}
+void getFeatures(llvm::SmallVectorImpl &Out,
+ unsigned Index) const {
+  if (isDefaultVersion(Index)) return;
+  StringRef Features = getFeatureStr(Index);
+  SmallVector AttrFeatures;
+  Features.split(AttrFeatures, "+");
+  for (auto &Feature : AttrFeatures) {
+Feature = Feature.trim();
+Out.push_back(Feature);
+  }
+}
 // Given an index into the 'featuresStrs' sequence, compute a unique
 // ID to be used with function name mangling for the associated variant.
 // This mapping is necessary due to a requirement that the mangling ID
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index fcf801adeaf5ef..0b5f20a572a742 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13676,22 +13676,19 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap,
 Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
   } else if (const auto *TC = FD->getAttr()) {
 std::vector Features;
-StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
 if (Target->getTriple().isAArch64()) {
   // TargetClones for AArch64
-  if (VersionStr != "default") {
-SmallVector VersionFeatures;
-VersionStr.split(VersionFeatures, "+");
-for (auto &VFeature : VersionFeatures) {
-  VFeature = VFeature.trim();
+  llvm::SmallVector Feats;
+  TC->getFeatures(Feats, GD.getMultiVersionIndex());
+  for (StringRef Feat : Feats)
+if (Target->validateCpuSupports(Feat.str()))
   // Use '?' to mark features that came from AArch64 TargetClones.
-  Features.push_back((StringRef{"?"} + VFeature).str());
-}
-  }
+  Features.push_back("?" + Feat.str());
   Features.insert(Features.begin(),
   Target->getTargetOpts().FeaturesAsWritten.begin(),
   Target->getTargetOpts().FeaturesAsWritten.end());
 } else {
+  StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
   if (VersionStr.starts_with("arch="))
 TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
   else if (VersionStr != "default")
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index ac81df8cf7adfe..bc7d7ac561113b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3712,7 +3712,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
 // Forward declarations are emitted lazily on first use.
 if (!FD->doesThisDeclarationHaveABody()) {
   if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
-  !FD->isTargetVersionMultiVersion())
+  (!FD->isMultiVersion() ||
+   !FD->getASTContext().getTargetInfo().getTriple().isAArch64()))
 return;
 
   StringRef MangledName = getMangledName(GD);
@@ -3994,10 +3995,11 @@ void 
CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
 auto *Spec = FD->getAttr();
 for (unsigned I = 0; I < Spec->cpus_size(); ++I)
   EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
-  } else if (FD->isTargetClonesMultiVersion()) {
-auto *Clone = FD->getAttr();
-for (unsigned I = 0; I < Clone->fe

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

2024-03-25 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 13078cbc3eeb0ae91c370ce0f604f7165b26e0c8 
65bfc47298131d6fb5dfeed722dc3f2d9d85eadd -- 
clang/test/CodeGen/aarch64-mixed-target-attributes.c 
clang/lib/AST/ASTContext.cpp clang/lib/CodeGen/CodeGenModule.cpp 
clang/lib/Sema/SemaDecl.cpp clang/test/CodeGen/attr-target-clones-aarch64.c 
clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp 
clang/test/Sema/attr-target-clones-aarch64.c
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b1f2749c40..9a286e0b26 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11471,8 +11471,7 @@ static bool 
PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
   return false;
 }
 
-static
-void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
+static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
   if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
 return;
 
@@ -11480,8 +11479,8 @@ void patchDefaultTargetVersion(FunctionDecl *From, 
FunctionDecl *To) {
   MultiVersionKind MVKindTo = To->getMultiVersionKind();
 
   if (MVKindTo == MultiVersionKind::None &&
- (MVKindFrom == MultiVersionKind::TargetVersion ||
-  MVKindFrom == MultiVersionKind::TargetClones)) {
+  (MVKindFrom == MultiVersionKind::TargetVersion ||
+   MVKindFrom == MultiVersionKind::TargetClones)) {
 To->setIsMultiVersion();
 To->addAttr(TargetVersionAttr::CreateImplicit(
 To->getASTContext(), "default", To->getSourceRange()));
@@ -11599,8 +11598,7 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, 
FunctionDecl *OldFD,
   return false;
 }
 
-static bool MultiVersionTypesCompatible(FunctionDecl *Old,
-FunctionDecl *New) {
+static bool MultiVersionTypesCompatible(FunctionDecl *Old, FunctionDecl *New) {
   MultiVersionKind OldKind = Old->getMultiVersionKind();
   MultiVersionKind NewKind = New->getMultiVersionKind();
 

``




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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

2024-03-25 Thread via cfe-commits

github-actions[bot] wrote:



:white_check_mark: With the latest revision this PR passed the Python code 
formatter.

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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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

>From dfef9d04c0a65423a051ac00044b39f8911aa731 Mon Sep 17 00:00:00 2001
From: Alexandros Lamprineas 
Date: Fri, 22 Mar 2024 17:21:13 +
Subject: [PATCH] [FMV] Allow mixing target_version with target_clones.

The latest ACLE allows it and further clarifies the following
in regards to the combination of the two attributes:

"If the `default` matches with another explicitly provided
 version in the same translation unit, then the compiler can
 emit only one function instead of the two. The explicitly
 provided version shall be preferred."

("default" refers to the default clone here)

https://github.com/ARM-software/acle/pull/310
---
 clang/include/clang/Basic/Attr.td |  14 +
 clang/lib/AST/ASTContext.cpp  |  15 +-
 clang/lib/CodeGen/CodeGenModule.cpp   | 105 ---
 clang/lib/Sema/SemaDecl.cpp   | 190 
 .../CodeGen/aarch64-mixed-target-attributes.c | 278 ++
 .../test/CodeGen/attr-target-clones-aarch64.c |  94 +++---
 .../CodeGenCXX/attr-target-clones-aarch64.cpp |  28 +-
 clang/test/Sema/attr-target-clones-aarch64.c  |   2 +-
 8 files changed, 537 insertions(+), 189 deletions(-)
 create mode 100644 clang/test/CodeGen/aarch64-mixed-target-attributes.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 3e03e55612645b..318d4e5ac5ba44 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3088,6 +3088,20 @@ def TargetClones : InheritableAttr {
 StringRef getFeatureStr(unsigned Index) const {
   return *(featuresStrs_begin() + Index);
 }
+bool isDefaultVersion(unsigned Index) const {
+  return getFeatureStr(Index) == "default";
+}
+void getFeatures(llvm::SmallVectorImpl &Out,
+ unsigned Index) const {
+  if (isDefaultVersion(Index)) return;
+  StringRef Features = getFeatureStr(Index);
+  SmallVector AttrFeatures;
+  Features.split(AttrFeatures, "+");
+  for (auto &Feature : AttrFeatures) {
+Feature = Feature.trim();
+Out.push_back(Feature);
+  }
+}
 // Given an index into the 'featuresStrs' sequence, compute a unique
 // ID to be used with function name mangling for the associated variant.
 // This mapping is necessary due to a requirement that the mangling ID
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index fcf801adeaf5ef..0b5f20a572a742 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13676,22 +13676,19 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap &FeatureMap,
 Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
   } else if (const auto *TC = FD->getAttr()) {
 std::vector Features;
-StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
 if (Target->getTriple().isAArch64()) {
   // TargetClones for AArch64
-  if (VersionStr != "default") {
-SmallVector VersionFeatures;
-VersionStr.split(VersionFeatures, "+");
-for (auto &VFeature : VersionFeatures) {
-  VFeature = VFeature.trim();
+  llvm::SmallVector Feats;
+  TC->getFeatures(Feats, GD.getMultiVersionIndex());
+  for (StringRef Feat : Feats)
+if (Target->validateCpuSupports(Feat.str()))
   // Use '?' to mark features that came from AArch64 TargetClones.
-  Features.push_back((StringRef{"?"} + VFeature).str());
-}
-  }
+  Features.push_back("?" + Feat.str());
   Features.insert(Features.begin(),
   Target->getTargetOpts().FeaturesAsWritten.begin(),
   Target->getTargetOpts().FeaturesAsWritten.end());
 } else {
+  StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
   if (VersionStr.starts_with("arch="))
 TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
   else if (VersionStr != "default")
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index ac81df8cf7adfe..bc7d7ac561113b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3712,7 +3712,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
 // Forward declarations are emitted lazily on first use.
 if (!FD->doesThisDeclarationHaveABody()) {
   if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
-  !FD->isTargetVersionMultiVersion())
+  (!FD->isMultiVersion() ||
+   !FD->getASTContext().getTargetInfo().getTriple().isAArch64()))
 return;
 
   StringRef MangledName = getMangledName(GD);
@@ -3994,10 +3995,11 @@ void 
CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
 auto *Spec = FD->getAttr();
 for (unsigned I = 0; I < Spec->cpus_size(); ++I)
   EmitGlobalFunctionDefinition(GD.getWithMultiVersion

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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


@@ -0,0 +1,278 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature --check-attributes --check-globals 
--include-generated-funcs
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S 
-emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
+
+// The following is guarded because in NOFMV we get an error for redefining 
the default.
+#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
+int explicit_default(void) { return 0; }
+__attribute__((target_version("jscvt"))) int explicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int explicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int explicit_default(void) { return 3; 
}
+
+int foo(void) { return explicit_default(); }
+#endif
+
+__attribute__((target_version("jscvt"))) int implicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int implicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int implicit_default(void) { return 3; 
}
+
+int bar(void) { return implicit_default(); }
+
+// These shouldn't generate anything.
+int unused_version_declarations(void);
+__attribute__((target_clones("dotprod", "lse"))) int 
unused_version_declarations(void);
+__attribute__((target_version("jscvt"))) int unused_version_declarations(void);
+
+// These should generate the default (mangled) version and the resolver.
+int default_def_with_version_decls(void) { return 0; }
+__attribute__((target_clones("dotprod", "lse"))) int 
default_def_with_version_decls(void);
+__attribute__((target_version("jscvt"))) int 
default_def_with_version_decls(void);
+
+//.
+// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
+// CHECK: @explicit_default.ifunc = weak_odr alias i32 (), ptr 
@explicit_default
+// CHECK: @implicit_default.ifunc = weak_odr alias i32 (), ptr 
@implicit_default
+// CHECK: @default_def_with_version_decls.ifunc = weak_odr alias i32 (), ptr 
@default_def_with_version_decls
+// CHECK: @explicit_default = weak_odr ifunc i32 (), ptr 
@explicit_default.resolver
+// CHECK: @implicit_default = weak_odr ifunc i32 (), ptr 
@implicit_default.resolver
+// CHECK: @default_def_with_version_decls = weak_odr ifunc i32 (), ptr 
@default_def_with_version_decls.resolver
+//.
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.default
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 0
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mjscvt
+// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mdotprod
+// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mlse
+// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.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]], 1048576
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576
+// 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 @explicit_default._Mjscvt
+// CHECK:   resolver_else:
+// CHECK-NEXT:[[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP5:%.*]] = and i64 [[TMP4]], 64
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label 
[[RESOLVER_ELSE2:%.*]]
+// CHECK:   resolver_return1:
+// CHECK-NEXT:ret ptr @explicit_default._Mrdm
+// CHECK:   resolver_else2:
+// CHECK-NEXT:[[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP9:%.*]] = and i64 [[TMP8]], 16
+// CHECK-NEXT:[[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
+// CHECK-NEXT:[[TMP11:%.*]] = and i1 true, [[TMP10]]
+// CHECK-NEXT:br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label 
[[RESOLVER_ELSE4:%.*]]
+// CHECK:   resolver_return3:
+// CHECK-NEXT:ret ptr @explicit_default._Mdotprod
+// CHECK:   resolver_else4:
+// CHECK-NEXT:[[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 
8
+// CHECK-NEXT:[[

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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


@@ -0,0 +1,278 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature --check-attributes --check-globals 
--include-generated-funcs
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S 
-emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
+
+// The following is guarded because in NOFMV we get an error for redefining 
the default.
+#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
+int explicit_default(void) { return 0; }
+__attribute__((target_version("jscvt"))) int explicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int explicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int explicit_default(void) { return 3; 
}
+
+int foo(void) { return explicit_default(); }
+#endif
+
+__attribute__((target_version("jscvt"))) int implicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int implicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int implicit_default(void) { return 3; 
}
+
+int bar(void) { return implicit_default(); }
+
+// These shouldn't generate anything.
+int unused_version_declarations(void);
+__attribute__((target_clones("dotprod", "lse"))) int 
unused_version_declarations(void);
+__attribute__((target_version("jscvt"))) int unused_version_declarations(void);
+
+// These should generate the default (mangled) version and the resolver.
+int default_def_with_version_decls(void) { return 0; }
+__attribute__((target_clones("dotprod", "lse"))) int 
default_def_with_version_decls(void);
+__attribute__((target_version("jscvt"))) int 
default_def_with_version_decls(void);
+
+//.
+// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
+// CHECK: @explicit_default.ifunc = weak_odr alias i32 (), ptr 
@explicit_default
+// CHECK: @implicit_default.ifunc = weak_odr alias i32 (), ptr 
@implicit_default
+// CHECK: @default_def_with_version_decls.ifunc = weak_odr alias i32 (), ptr 
@default_def_with_version_decls
+// CHECK: @explicit_default = weak_odr ifunc i32 (), ptr 
@explicit_default.resolver
+// CHECK: @implicit_default = weak_odr ifunc i32 (), ptr 
@implicit_default.resolver
+// CHECK: @default_def_with_version_decls = weak_odr ifunc i32 (), ptr 
@default_def_with_version_decls.resolver
+//.
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.default
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 0
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mjscvt
+// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mdotprod
+// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mlse
+// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.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]], 1048576
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576
+// 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 @explicit_default._Mjscvt
+// CHECK:   resolver_else:
+// CHECK-NEXT:[[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP5:%.*]] = and i64 [[TMP4]], 64
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label 
[[RESOLVER_ELSE2:%.*]]
+// CHECK:   resolver_return1:
+// CHECK-NEXT:ret ptr @explicit_default._Mrdm
+// CHECK:   resolver_else2:
+// CHECK-NEXT:[[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP9:%.*]] = and i64 [[TMP8]], 16
+// CHECK-NEXT:[[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
+// CHECK-NEXT:[[TMP11:%.*]] = and i1 true, [[TMP10]]
+// CHECK-NEXT:br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label 
[[RESOLVER_ELSE4:%.*]]
+// CHECK:   resolver_return3:
+// CHECK-NEXT:ret ptr @explicit_default._Mdotprod
+// CHECK:   resolver_else4:
+// CHECK-NEXT:[[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 
8
+// CHECK-NEXT:[[

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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


@@ -0,0 +1,278 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature --check-attributes --check-globals 
--include-generated-funcs
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S 
-emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
+
+// The following is guarded because in NOFMV we get an error for redefining 
the default.
+#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
+int explicit_default(void) { return 0; }
+__attribute__((target_version("jscvt"))) int explicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int explicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int explicit_default(void) { return 3; 
}
+
+int foo(void) { return explicit_default(); }
+#endif
+
+__attribute__((target_version("jscvt"))) int implicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int implicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int implicit_default(void) { return 3; 
}
+
+int bar(void) { return implicit_default(); }
+
+// These shouldn't generate anything.
+int unused_version_declarations(void);
+__attribute__((target_clones("dotprod", "lse"))) int 
unused_version_declarations(void);
+__attribute__((target_version("jscvt"))) int unused_version_declarations(void);
+
+// These should generate the default (mangled) version and the resolver.
+int default_def_with_version_decls(void) { return 0; }
+__attribute__((target_clones("dotprod", "lse"))) int 
default_def_with_version_decls(void);
+__attribute__((target_version("jscvt"))) int 
default_def_with_version_decls(void);
+
+//.
+// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
+// CHECK: @explicit_default.ifunc = weak_odr alias i32 (), ptr 
@explicit_default
+// CHECK: @implicit_default.ifunc = weak_odr alias i32 (), ptr 
@implicit_default
+// CHECK: @default_def_with_version_decls.ifunc = weak_odr alias i32 (), ptr 
@default_def_with_version_decls
+// CHECK: @explicit_default = weak_odr ifunc i32 (), ptr 
@explicit_default.resolver
+// CHECK: @implicit_default = weak_odr ifunc i32 (), ptr 
@implicit_default.resolver
+// CHECK: @default_def_with_version_decls = weak_odr ifunc i32 (), ptr 
@default_def_with_version_decls.resolver
+//.
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.default
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 0
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mjscvt
+// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mdotprod
+// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mlse
+// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.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]], 1048576
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576
+// 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 @explicit_default._Mjscvt
+// CHECK:   resolver_else:
+// CHECK-NEXT:[[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP5:%.*]] = and i64 [[TMP4]], 64
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label 
[[RESOLVER_ELSE2:%.*]]
+// CHECK:   resolver_return1:
+// CHECK-NEXT:ret ptr @explicit_default._Mrdm
+// CHECK:   resolver_else2:
+// CHECK-NEXT:[[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP9:%.*]] = and i64 [[TMP8]], 16
+// CHECK-NEXT:[[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
+// CHECK-NEXT:[[TMP11:%.*]] = and i1 true, [[TMP10]]
+// CHECK-NEXT:br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label 
[[RESOLVER_ELSE4:%.*]]
+// CHECK:   resolver_return3:
+// CHECK-NEXT:ret ptr @explicit_default._Mdotprod
+// CHECK:   resolver_else4:
+// CHECK-NEXT:[[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 
8
+// CHECK-NEXT:[[

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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


@@ -0,0 +1,278 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature --check-attributes --check-globals 
--include-generated-funcs
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S 
-emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
+
+// The following is guarded because in NOFMV we get an error for redefining 
the default.
+#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
+int explicit_default(void) { return 0; }
+__attribute__((target_version("jscvt"))) int explicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int explicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int explicit_default(void) { return 3; 
}
+
+int foo(void) { return explicit_default(); }
+#endif
+
+__attribute__((target_version("jscvt"))) int implicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int implicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int implicit_default(void) { return 3; 
}
+
+int bar(void) { return implicit_default(); }
+
+// These shouldn't generate anything.
+int unused_version_declarations(void);
+__attribute__((target_clones("dotprod", "lse"))) int 
unused_version_declarations(void);
+__attribute__((target_version("jscvt"))) int unused_version_declarations(void);
+
+// These should generate the default (mangled) version and the resolver.
+int default_def_with_version_decls(void) { return 0; }
+__attribute__((target_clones("dotprod", "lse"))) int 
default_def_with_version_decls(void);
+__attribute__((target_version("jscvt"))) int 
default_def_with_version_decls(void);
+
+//.
+// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
+// CHECK: @explicit_default.ifunc = weak_odr alias i32 (), ptr 
@explicit_default
+// CHECK: @implicit_default.ifunc = weak_odr alias i32 (), ptr 
@implicit_default
+// CHECK: @default_def_with_version_decls.ifunc = weak_odr alias i32 (), ptr 
@default_def_with_version_decls
+// CHECK: @explicit_default = weak_odr ifunc i32 (), ptr 
@explicit_default.resolver
+// CHECK: @implicit_default = weak_odr ifunc i32 (), ptr 
@implicit_default.resolver
+// CHECK: @default_def_with_version_decls = weak_odr ifunc i32 (), ptr 
@default_def_with_version_decls.resolver
+//.
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.default
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 0
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mjscvt
+// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mdotprod
+// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mlse
+// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.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]], 1048576
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576
+// 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 @explicit_default._Mjscvt
+// CHECK:   resolver_else:
+// CHECK-NEXT:[[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP5:%.*]] = and i64 [[TMP4]], 64
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label 
[[RESOLVER_ELSE2:%.*]]
+// CHECK:   resolver_return1:
+// CHECK-NEXT:ret ptr @explicit_default._Mrdm
+// CHECK:   resolver_else2:
+// CHECK-NEXT:[[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP9:%.*]] = and i64 [[TMP8]], 16
+// CHECK-NEXT:[[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
+// CHECK-NEXT:[[TMP11:%.*]] = and i1 true, [[TMP10]]
+// CHECK-NEXT:br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label 
[[RESOLVER_ELSE4:%.*]]
+// CHECK:   resolver_return3:
+// CHECK-NEXT:ret ptr @explicit_default._Mdotprod
+// CHECK:   resolver_else4:
+// CHECK-NEXT:[[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 
8
+// CHECK-NEXT:[[

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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


@@ -0,0 +1,278 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature --check-attributes --check-globals 
--include-generated-funcs
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -v9.5a -S 
-emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S 
-emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
+
+// The following is guarded because in NOFMV we get an error for redefining 
the default.
+#ifdef __HAVE_FUNCTION_MULTI_VERSIONING
+int explicit_default(void) { return 0; }
+__attribute__((target_version("jscvt"))) int explicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int explicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int explicit_default(void) { return 3; 
}
+
+int foo(void) { return explicit_default(); }
+#endif
+
+__attribute__((target_version("jscvt"))) int implicit_default(void) { return 
1; }
+__attribute__((target_clones("dotprod", "lse"))) int implicit_default(void) { 
return 2; }
+__attribute__((target_version("rdma"))) int implicit_default(void) { return 3; 
}
+
+int bar(void) { return implicit_default(); }
+
+// These shouldn't generate anything.
+int unused_version_declarations(void);
+__attribute__((target_clones("dotprod", "lse"))) int 
unused_version_declarations(void);
+__attribute__((target_version("jscvt"))) int unused_version_declarations(void);
+
+// These should generate the default (mangled) version and the resolver.
+int default_def_with_version_decls(void) { return 0; }
+__attribute__((target_clones("dotprod", "lse"))) int 
default_def_with_version_decls(void);
+__attribute__((target_version("jscvt"))) int 
default_def_with_version_decls(void);
+
+//.
+// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
+// CHECK: @explicit_default.ifunc = weak_odr alias i32 (), ptr 
@explicit_default
+// CHECK: @implicit_default.ifunc = weak_odr alias i32 (), ptr 
@implicit_default
+// CHECK: @default_def_with_version_decls.ifunc = weak_odr alias i32 (), ptr 
@default_def_with_version_decls
+// CHECK: @explicit_default = weak_odr ifunc i32 (), ptr 
@explicit_default.resolver
+// CHECK: @implicit_default = weak_odr ifunc i32 (), ptr 
@implicit_default.resolver
+// CHECK: @default_def_with_version_decls = weak_odr ifunc i32 (), ptr 
@default_def_with_version_decls.resolver
+//.
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.default
+// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 0
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mjscvt
+// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 1
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mdotprod
+// CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: define {{[^@]+}}@explicit_default._Mlse
+// CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:ret i32 2
+//
+//
+// CHECK-LABEL: define {{[^@]+}}@explicit_default.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]], 1048576
+// CHECK-NEXT:[[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576
+// 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 @explicit_default._Mjscvt
+// CHECK:   resolver_else:
+// CHECK-NEXT:[[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP5:%.*]] = and i64 [[TMP4]], 64
+// CHECK-NEXT:[[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64
+// CHECK-NEXT:[[TMP7:%.*]] = and i1 true, [[TMP6]]
+// CHECK-NEXT:br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label 
[[RESOLVER_ELSE2:%.*]]
+// CHECK:   resolver_return1:
+// CHECK-NEXT:ret ptr @explicit_default._Mrdm
+// CHECK:   resolver_else2:
+// CHECK-NEXT:[[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
+// CHECK-NEXT:[[TMP9:%.*]] = and i64 [[TMP8]], 16
+// CHECK-NEXT:[[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
+// CHECK-NEXT:[[TMP11:%.*]] = and i1 true, [[TMP10]]
+// CHECK-NEXT:br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label 
[[RESOLVER_ELSE4:%.*]]
+// CHECK:   resolver_return3:
+// CHECK-NEXT:ret ptr @explicit_default._Mdotprod
+// CHECK:   resolver_else4:
+// CHECK-NEXT:[[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 
8
+// CHECK-NEXT:[[

[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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

LGTM

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


[clang] [FMV] Allow mixing target_version with target_clones. (PR #86493)

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

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