[clang] [llvm] [X86] Support apxf in attribute target (PR #184078)
Mikołaj Piróg via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 3 04:10:21 PST 2026
https://github.com/mikolaj-pirog updated https://github.com/llvm/llvm-project/pull/184078
>From 36839a382fe5b5444ef85666d46ebb18ba7ac649 Mon Sep 17 00:00:00 2001
From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pirog at intel.com>
Date: Mon, 2 Mar 2026 08:15:36 +0100
Subject: [PATCH 1/2] Support apxf in function multiversioning, don't support
indivudal features
---
clang/lib/Basic/Targets/X86.cpp | 34 +++++++++++++++++++++-------
clang/test/CodeGen/attr-target-x86.c | 10 ++++++++
clang/test/Sema/attr-target.c | 21 +++++++++++++++++
3 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 6f88a428b1230..f0c31dddbc205 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -179,6 +179,31 @@ bool X86TargetInfo::initFeatureMap(
continue;
}
+ // Expand apxf to the individual APX features
+ if (Feature == "+apxf") {
+ UpdatedFeaturesVec.push_back("+egpr");
+ UpdatedFeaturesVec.push_back("+ndd");
+ UpdatedFeaturesVec.push_back("+ccmp");
+ UpdatedFeaturesVec.push_back("+nf");
+ UpdatedFeaturesVec.push_back("+zu");
+ if (!getTriple().isOSWindows()) {
+ UpdatedFeaturesVec.push_back("+push2pop2");
+ UpdatedFeaturesVec.push_back("+ppx");
+ }
+ continue;
+ }
+
+ if (Feature == "-apxf") {
+ UpdatedFeaturesVec.push_back("-egpr");
+ UpdatedFeaturesVec.push_back("-ndd");
+ UpdatedFeaturesVec.push_back("-ccmp");
+ UpdatedFeaturesVec.push_back("-nf");
+ UpdatedFeaturesVec.push_back("-zu");
+ UpdatedFeaturesVec.push_back("-push2pop2");
+ UpdatedFeaturesVec.push_back("-ppx");
+ continue;
+ }
+
UpdatedFeaturesVec.push_back(Feature);
}
@@ -1169,14 +1194,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("xsavec", true)
.Case("xsaves", true)
.Case("xsaveopt", true)
- .Case("egpr", true)
- .Case("push2pop2", true)
- .Case("ppx", true)
- .Case("ndd", true)
- .Case("ccmp", true)
- .Case("nf", true)
- .Case("cf", true)
- .Case("zu", true)
+ .Case("apxf", true)
.Default(false);
}
diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c
index 474fa93629d89..35f07a2e0c2bb 100644
--- a/clang/test/CodeGen/attr-target-x86.c
+++ b/clang/test/CodeGen/attr-target-x86.c
@@ -19,6 +19,8 @@
// CHECK: define {{.*}}@f_avx10_1{{.*}} [[f_avx10_1:#[0-9]+]]
// CHECK: define {{.*}}@f_prefer_256_bit({{.*}} [[f_prefer_256_bit:#[0-9]+]]
// CHECK: define {{.*}}@f_no_prefer_256_bit({{.*}} [[f_no_prefer_256_bit:#[0-9]+]]
+// CHECK: define {{.*}}@f_apxf({{.*}} [[f_apxf:#[0-9]+]]
+// CHECK: define {{.*}}@f_no_apxf({{.*}} [[f_no_apxf:#[0-9]+]]
// CHECK: [[f_default]] = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87" "tune-cpu"="i686"
void f_default(void) {}
@@ -108,3 +110,11 @@ void f_prefer_256_bit(void) {}
// CHECK: [[f_no_prefer_256_bit]] = {{.*}}"target-features"="{{.*}}-prefer-256-bit
__attribute__((target("no-prefer-256-bit")))
void f_no_prefer_256_bit(void) {}
+
+// CHECK: [[f_apxf]] = {{.*}}"target-features"="{{.*}}+ccmp{{.*}}+egpr{{.*}}+ndd{{.*}}+nf{{.*}}+ppx{{.*}}+push2pop2{{.*}}+zu
+__attribute__((target("apxf")))
+void f_apxf(void) {}
+
+// CHECK: [[f_no_apxf]] = {{.*}}"target-features"="{{.*}}-ccmp{{.*}}-egpr{{.*}}-ndd{{.*}}-nf{{.*}}-ppx{{.*}}-push2pop2{{.*}}-zu
+__attribute__((target("no-apxf")))
+void f_no_apxf(void) {}
diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c
index 65ece3c27d299..a68fb06ec8684 100644
--- a/clang/test/Sema/attr-target.c
+++ b/clang/test/Sema/attr-target.c
@@ -35,6 +35,27 @@ void __attribute__((target("x86-64-v2"))) v2(void) {}
int __attribute__((target("sha"))) good_target_but_not_for_fmv() { return 5; }
+int __attribute__((target("apxf"))) apx_supported(void) { return 6; }
+int __attribute__((target("no-apxf"))) no_apx_supported(void) { return 7; }
+
+// APXF sub-features should NOT be supported directly in target attribute
+//expected-warning at +1 {{unsupported 'egpr' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("egpr"))) egpr_not_supported(void) { return 8; }
+//expected-warning at +1 {{unsupported 'ndd' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("ndd"))) ndd_not_supported(void) { return 9; }
+//expected-warning at +1 {{unsupported 'ccmp' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("ccmp"))) ccmp_not_supported(void) { return 10; }
+//expected-warning at +1 {{unsupported 'nf' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("nf"))) nf_not_supported(void) { return 11; }
+//expected-warning at +1 {{unsupported 'cf' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("cf"))) cf_not_supported(void) { return 12; }
+//expected-warning at +1 {{unsupported 'zu' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("zu"))) zu_not_supported(void) { return 13; }
+//expected-warning at +1 {{unsupported 'push2pop2' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("push2pop2"))) push2pop2_not_supported(void) { return 14; }
+//expected-warning at +1 {{unsupported 'ppx' in the 'target' attribute string; 'target' attribute ignored}}
+int __attribute__((target("ppx"))) ppx_not_supported(void) { return 15; }
+
#elifdef __aarch64__
int __attribute__((target("sve,arch=armv8-a"))) foo(void) { return 4; }
>From 74c3586f2c06e6c7c536b8df1c06f9c22ccff482 Mon Sep 17 00:00:00 2001
From: "Pirog, Mikolaj Maciej" <mikolaj.maciej.pirog at intel.com>
Date: Tue, 3 Mar 2026 13:09:22 +0100
Subject: [PATCH 2/2] Deduplicate
---
clang/lib/Basic/Targets/X86.cpp | 30 ++++---------------
clang/lib/Driver/ToolChains/Arch/X86.cpp | 21 ++++---------
clang/test/Driver/cl-x86-flags.c | 2 +-
.../llvm/TargetParser/X86TargetParser.h | 4 +++
llvm/lib/TargetParser/X86TargetParser.cpp | 16 ++++++++++
5 files changed, 32 insertions(+), 41 deletions(-)
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index f0c31dddbc205..8a910205eedba 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -169,7 +169,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabled(Features, "ppx", false);
}
- std::vector<std::string> UpdatedFeaturesVec;
+ std::vector<StringRef> UpdatedFeaturesVec;
for (const auto &Feature : FeaturesVec) {
// Expand general-regs-only to -x86, -mmx and -sse
if (Feature == "+general-regs-only") {
@@ -179,35 +179,15 @@ bool X86TargetInfo::initFeatureMap(
continue;
}
- // Expand apxf to the individual APX features
- if (Feature == "+apxf") {
- UpdatedFeaturesVec.push_back("+egpr");
- UpdatedFeaturesVec.push_back("+ndd");
- UpdatedFeaturesVec.push_back("+ccmp");
- UpdatedFeaturesVec.push_back("+nf");
- UpdatedFeaturesVec.push_back("+zu");
- if (!getTriple().isOSWindows()) {
- UpdatedFeaturesVec.push_back("+push2pop2");
- UpdatedFeaturesVec.push_back("+ppx");
- }
+ if (llvm::X86::expandAPXFeatures(Feature, getTriple(), UpdatedFeaturesVec))
continue;
- }
-
- if (Feature == "-apxf") {
- UpdatedFeaturesVec.push_back("-egpr");
- UpdatedFeaturesVec.push_back("-ndd");
- UpdatedFeaturesVec.push_back("-ccmp");
- UpdatedFeaturesVec.push_back("-nf");
- UpdatedFeaturesVec.push_back("-zu");
- UpdatedFeaturesVec.push_back("-push2pop2");
- UpdatedFeaturesVec.push_back("-ppx");
- continue;
- }
UpdatedFeaturesVec.push_back(Feature);
}
- if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
+ if (!TargetInfo::initFeatureMap(
+ Features, Diags, CPU,
+ {UpdatedFeaturesVec.begin(), UpdatedFeaturesVec.end()}))
return false;
// Can't do this earlier because we need to be able to explicitly enable
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp
index 61d512f9e093f..62b9c59d651d4 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/Option/ArgList.h"
#include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/X86TargetParser.h"
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -257,21 +258,11 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (A->getOption().matches(options::OPT_mapxf) ||
A->getOption().matches(options::OPT_mno_apxf)) {
- if (IsNegative) {
- Features.insert(Features.end(),
- {"-egpr", "-ndd", "-ccmp", "-nf", "-zu"});
- if (!Triple.isOSWindows())
- Features.insert(Features.end(), {"-push2pop2", "-ppx"});
- } else {
- Features.insert(Features.end(),
- {"+egpr", "+ndd", "+ccmp", "+nf", "+zu"});
- if (!Triple.isOSWindows())
- Features.insert(Features.end(), {"+push2pop2", "+ppx"});
-
- if (Not64Bit)
- D.Diag(diag::err_drv_unsupported_opt_for_target)
- << StringRef("-mapxf") << Triple.getTriple();
- }
+ llvm::X86::expandAPXFeatures(IsNegative ? "-apxf" : "+apxf", Triple,
+ Features);
+ if (!IsNegative && Not64Bit)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << StringRef("-mapxf") << Triple.getTriple();
continue;
}
diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c
index 5b32f17774e27..6bad93b633549 100644
--- a/clang/test/Driver/cl-x86-flags.c
+++ b/clang/test/Driver/cl-x86-flags.c
@@ -224,5 +224,5 @@ void f(void) {
// RUN: %clang_cl --target=x86_64-pc-windows -mapxf -mno-apxf -### -- 2>&1 %s | FileCheck -check-prefix=NO-APXF %s
// RUN: %clang_cl --target=x86_64-pc-windows -mapx-features=egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu -### -- 2>&1 %s | FileCheck -check-prefix=APXALL %s
// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu"
-// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu"
+// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" "-target-feature" "-push2pop2" "-target-feature" "-ppx"
// APXALL: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+cf" "-target-feature" "+zu"
diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.h b/llvm/include/llvm/TargetParser/X86TargetParser.h
index 31d13ce29f7fc..ead5791fc911f 100644
--- a/llvm/include/llvm/TargetParser/X86TargetParser.h
+++ b/llvm/include/llvm/TargetParser/X86TargetParser.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
#include <array>
namespace llvm {
@@ -187,6 +188,9 @@ LLVM_ABI std::array<uint32_t, 4>
getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
LLVM_ABI unsigned getFeaturePriority(ProcessorFeatures Feat);
+LLVM_ABI bool expandAPXFeatures(StringRef Name, const llvm::Triple &Triple,
+ std::vector<StringRef> &Features);
+
} // namespace X86
} // namespace llvm
diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp
index f848b1ac08607..b2b561041399e 100644
--- a/llvm/lib/TargetParser/X86TargetParser.cpp
+++ b/llvm/lib/TargetParser/X86TargetParser.cpp
@@ -778,6 +778,22 @@ llvm::X86::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
return FeatureMask;
}
+bool llvm::X86::expandAPXFeatures(StringRef Name, const llvm::Triple &Triple,
+ std::vector<StringRef> &Features) {
+ if (Name == "+apxf") {
+ Features.insert(Features.end(), {"+egpr", "+ndd", "+ccmp", "+nf", "+zu"});
+ if (!Triple.isOSWindows()) {
+ Features.insert(Features.end(), {"+push2pop2", "+ppx"});
+ }
+ } else if (Name == "-apxf") {
+ Features.insert(Features.end(), {"-egpr", "-ndd", "-ccmp", "-nf", "-zu",
+ "-push2pop2", "-ppx"});
+ } else {
+ return false;
+ }
+ return true;
+}
+
unsigned llvm::X86::getFeaturePriority(ProcessorFeatures Feat) {
#ifndef NDEBUG
// Check that priorities are set properly in the .def file. We expect that
More information about the cfe-commits
mailing list