[clang] 1d55a81 - [X86] Support apxf in attribute target (#184078)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 19 04:38:55 PDT 2026
Author: Mikołaj Piróg
Date: 2026-07-19T13:38:48+02:00
New Revision: 1d55a816c6dddfaacfd39f3235519a2389b56423
URL: https://github.com/llvm/llvm-project/commit/1d55a816c6dddfaacfd39f3235519a2389b56423
DIFF: https://github.com/llvm/llvm-project/commit/1d55a816c6dddfaacfd39f3235519a2389b56423.diff
LOG: [X86] Support apxf in attribute target (#184078)
As in title. This adds support for using apxf in attribute target.
Individual features are not supported for FMV but are supported for
enabling a feature for the function
Patch done with usage of Claude Code.
Added:
Modified:
clang/lib/Basic/Targets/X86.cpp
clang/test/CodeGen/attr-target-mv.c
clang/test/CodeGen/attr-target-x86.c
clang/test/Sema/attr-target-mv.c
clang/test/Sema/attr-target.c
llvm/include/llvm/TargetParser/X86TargetParser.def
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index f77b2d4e0815d..7d8a74d62be74 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -174,6 +174,14 @@ bool X86TargetInfo::initFeatureMap(
continue;
}
+ if (Feature == "+apxf" || Feature == "-apxf") {
+ char Sign = Feature[0];
+ for (const char *Sub :
+ {"egpr", "push2pop2", "ppx", "ndd", "ccmp", "nf", "zu", "jmpabs"})
+ UpdatedFeaturesVec.push_back(Sign + std::string(Sub));
+ continue;
+ }
+
UpdatedFeaturesVec.push_back(Feature);
}
@@ -1184,6 +1192,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("xsavec", true)
.Case("xsaves", true)
.Case("xsaveopt", true)
+ .Case("apxf", true)
.Case("egpr", true)
.Case("push2pop2", true)
.Case("ppx", true)
diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c
index 68af3c7476b32..f4a9667aa403e 100644
--- a/clang/test/CodeGen/attr-target-mv.c
+++ b/clang/test/CodeGen/attr-target-mv.c
@@ -32,6 +32,7 @@ int __attribute__((target("arch=clearwaterforest"))) foo(void) {return 26;}
int __attribute__((target("arch=diamondrapids"))) foo(void) {return 27;}
int __attribute__((target("arch=wildcatlake"))) foo(void) {return 28;}
int __attribute__((target("arch=novalake"))) foo(void) {return 29;}
+int __attribute__((target("apxf"))) foo(void) {return 30;}
int __attribute__((target("default"))) foo(void) { return 2; }
int bar(void) {
@@ -209,6 +210,8 @@ void calls_pr50025c(void) { pr50025c(); }
// ITANIUM: ret i32 28
// ITANIUM: define{{.*}} i32 @foo.arch_novalake()
// ITANIUM: ret i32 29
+// ITANIUM: define{{.*}} i32 @foo.apxf()
+// ITANIUM: ret i32 30
// ITANIUM: define{{.*}} i32 @foo()
// ITANIUM: ret i32 2
// ITANIUM: define{{.*}} i32 @bar()
@@ -272,6 +275,8 @@ void calls_pr50025c(void) { pr50025c(); }
// WINDOWS: ret i32 28
// WINDOWS: define dso_local i32 @foo.arch_novalake()
// WINDOWS: ret i32 29
+// WINDOWS: define dso_local i32 @foo.apxf()
+// WINDOWS: ret i32 30
// WINDOWS: define dso_local i32 @foo()
// WINDOWS: ret i32 2
// WINDOWS: define dso_local i32 @bar()
@@ -280,6 +285,7 @@ void calls_pr50025c(void) { pr50025c(); }
// ITANIUM: define weak_odr ptr @foo.resolver() #[[ATTR_RESOLVER:[0-9]+]]
// LINUX-SAME: comdat
// ITANIUM: call void @__cpu_indicator_init()
+// ITANIUM: ret ptr @foo.apxf
// ITANIUM: ret ptr @foo.arch_sandybridge
// ITANIUM: ret ptr @foo.arch_ivybridge
// ITANIUM: ret ptr @foo.sse4.2
@@ -287,6 +293,7 @@ void calls_pr50025c(void) { pr50025c(); }
// WINDOWS: define weak_odr dso_local i32 @foo.resolver() #[[ATTR_RESOLVER:[0-9]+]] comdat
// WINDOWS: call void @__cpu_indicator_init()
+// WINDOWS: call i32 @foo.apxf
// WINDOWS: call i32 @foo.arch_sandybridge
// WINDOWS: call i32 @foo.arch_ivybridge
// WINDOWS: call i32 @foo.sse4.2
diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c
index 6a110ce38605b..954a508fc6773 100644
--- a/clang/test/CodeGen/attr-target-x86.c
+++ b/clang/test/CodeGen/attr-target-x86.c
@@ -19,6 +19,17 @@
// 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: define {{.*}}@f_egpr({{.*}} [[f_egpr:#[0-9]+]]
+// CHECK: define {{.*}}@f_ndd({{.*}} [[f_ndd:#[0-9]+]]
+// CHECK: define {{.*}}@f_ccmp({{.*}} [[f_ccmp:#[0-9]+]]
+// CHECK: define {{.*}}@f_nf({{.*}} [[f_nf:#[0-9]+]]
+// CHECK: define {{.*}}@f_cf({{.*}} [[f_cf:#[0-9]+]]
+// CHECK: define {{.*}}@f_zu({{.*}} [[f_zu:#[0-9]+]]
+// CHECK: define {{.*}}@f_push2pop2({{.*}} [[f_push2pop2:#[0-9]+]]
+// CHECK: define {{.*}}@f_ppx({{.*}} [[f_ppx:#[0-9]+]]
+// CHECK: define {{.*}}@f_jmpabs({{.*}} [[f_jmpabs:#[0-9]+]]
// CHECK: [[f_default]] = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87" "tune-cpu"="i686"
void f_default(void) {}
@@ -108,3 +119,47 @@ 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{{.*}}+jmpabs{{.*}}+ndd{{.*}}+nf{{.*}}+ppx{{.*}}+push2pop2{{.*}}+zu
+__attribute__((target("apxf")))
+void f_apxf(void) {}
+
+// CHECK: [[f_no_apxf]] = {{.*}}"target-features"="{{.*}}-ccmp{{.*}}-egpr{{.*}}-jmpabs{{.*}}-ndd{{.*}}-nf{{.*}}-ppx{{.*}}-push2pop2{{.*}}-zu
+__attribute__((target("no-apxf")))
+void f_no_apxf(void) {}
+
+// CHECK: [[f_egpr]] = {{.*}}"target-features"="{{.*}}+egpr
+__attribute__((target("egpr")))
+void f_egpr(void) {}
+
+// CHECK: [[f_ndd]] = {{.*}}"target-features"="{{.*}}+ndd
+__attribute__((target("ndd")))
+void f_ndd(void) {}
+
+// CHECK: [[f_ccmp]] = {{.*}}"target-features"="{{.*}}+ccmp
+__attribute__((target("ccmp")))
+void f_ccmp(void) {}
+
+// CHECK: [[f_nf]] = {{.*}}"target-features"="{{.*}}+nf
+__attribute__((target("nf")))
+void f_nf(void) {}
+
+// CHECK: [[f_cf]] = {{.*}}"target-features"="{{.*}}+cf
+__attribute__((target("cf")))
+void f_cf(void) {}
+
+// CHECK: [[f_zu]] = {{.*}}"target-features"="{{.*}}+zu
+__attribute__((target("zu")))
+void f_zu(void) {}
+
+// CHECK: [[f_push2pop2]] = {{.*}}"target-features"="{{.*}}+push2pop2
+__attribute__((target("push2pop2")))
+void f_push2pop2(void) {}
+
+// CHECK: [[f_ppx]] = {{.*}}"target-features"="{{.*}}+ppx
+__attribute__((target("ppx")))
+void f_ppx(void) {}
+
+// CHECK: [[f_jmpabs]] = {{.*}}"target-features"="{{.*}}+jmpabs
+__attribute__((target("jmpabs")))
+void f_jmpabs(void) {}
diff --git a/clang/test/Sema/attr-target-mv.c b/clang/test/Sema/attr-target-mv.c
index dfc3d614dc1e0..e77a1888595f2 100644
--- a/clang/test/Sema/attr-target-mv.c
+++ b/clang/test/Sema/attr-target-mv.c
@@ -185,3 +185,18 @@ int __attribute__((target("default"))) no_priority3(void);
int __attribute__((target("avx2"))) no_priority3(void);
// expected-error at +1 {{function multiversioning doesn't support feature 'sha'}}
int __attribute__((target("sha"))) no_priority3(void);
+
+int __attribute__((target("default"))) apxf_mv(void) { return 0; }
+int __attribute__((target("apxf"))) apxf_mv(void) { return 1; }
+
+// expected-error at +2 {{function multiversioning doesn't support feature 'ndd'}}
+// expected-note at +2 {{function multiversioning caused by this declaration}}
+int __attribute__((target("ndd"))) apx_sub(void);
+int __attribute__((target("default"))) apx_sub(void);
+
+// expected-error at +1 {{function multiversioning doesn't support feature 'egpr'}}
+int __attribute__((target("egpr"))) apx_two_subs(void) { return 0; }
+// expected-error at +1 {{function multiversioning doesn't support feature 'ndd'}}
+int __attribute__((target("ndd"))) apx_two_subs(void) { return 1; }
+// expected-note at +1 {{function multiversioning caused by this declaration}}
+int __attribute__((target("default"))) apx_two_subs(void) { return 2; }
diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c
index 6e9d85b5e1d67..b11147396aee4 100644
--- a/clang/test/Sema/attr-target.c
+++ b/clang/test/Sema/attr-target.c
@@ -35,6 +35,22 @@ void __attribute__((target("x86-64-v2"))) v2(void) {}
int __attribute__((target("sha"))) good_target_but_not_for_fmv() { return 5; }
+// 'apxf' and the individual APX sub-features are all valid in a 'target'
+// attribute when used to enable the feature on a single (non-multiversioned)
+// function, so none of these produce a diagnostic.
+int __attribute__((target("apxf"))) apx_supported(void) { return 6; }
+int __attribute__((target("no-apxf"))) no_apx_supported(void) { return 7; }
+int __attribute__((target("egpr"))) egpr_enabled(void) { return 8; }
+int __attribute__((target("ndd"))) ndd_enabled(void) { return 9; }
+int __attribute__((target("ccmp"))) ccmp_enabled(void) { return 10; }
+int __attribute__((target("nf"))) nf_enabled(void) { return 11; }
+int __attribute__((target("cf"))) cf_enabled(void) { return 12; }
+int __attribute__((target("zu"))) zu_enabled(void) { return 13; }
+int __attribute__((target("push2pop2"))) push2pop2_enabled(void) { return 14; }
+int __attribute__((target("ppx"))) ppx_enabled(void) { return 15; }
+int __attribute__((target("jmpabs"))) jmpabs_enabled(void) { return 16; }
+int __attribute__((target("egpr,ndd,ccmp"))) multiple_enabled(void) { return 17; }
+
#elifdef __aarch64__
int __attribute__((target("sve,arch=armv8-a"))) foo(void) { return 4; }
diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def
index 0185bfa76db66..30d3bc563a2be 100644
--- a/llvm/include/llvm/TargetParser/X86TargetParser.def
+++ b/llvm/include/llvm/TargetParser/X86TargetParser.def
@@ -235,7 +235,7 @@ X86_FEATURE_COMPAT(AVXVNNIINT16, "avxvnniint16", 0, 107)
X86_FEATURE_COMPAT(SM3, "sm3", 0, 108)
X86_FEATURE_COMPAT(SHA512, "sha512", 0, 109)
X86_FEATURE_COMPAT(SM4, "sm4", 0, 110)
-X86_FEATURE_COMPAT(APXF, "apxf", 0, 111)
+X86_FEATURE_COMPAT(APXF, "apxf", 36, 111)
X86_FEATURE_COMPAT(USERMSR, "usermsr", 0, 112)
X86_FEATURE_COMPAT(AVX10_1, "avx10.1", 34, 114)
X86_FEATURE_COMPAT(AVX10_2, "avx10.2", 35, 116)
@@ -274,7 +274,7 @@ X86_FEATURE (LVI_CFI, "lvi-cfi")
X86_FEATURE (LVI_LOAD_HARDENING, "lvi-load-hardening")
// Max number of priorities. Priorities form a consecutive range.
-#define MAX_PRIORITY 35
+#define MAX_PRIORITY 36
#undef X86_FEATURE_COMPAT
#undef X86_FEATURE
More information about the cfe-commits
mailing list