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@+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@+2 {{function multiversioning doesn't support feature 'ndd'}} +// expected-note@+2 {{function multiversioning caused by this declaration}} +int __attribute__((target("ndd"))) apx_sub(void); +int __attribute__((target("default"))) apx_sub(void); + +// expected-error@+1 {{function multiversioning doesn't support feature 'egpr'}} +int __attribute__((target("egpr"))) apx_two_subs(void) { return 0; } +// expected-error@+1 {{function multiversioning doesn't support feature 'ndd'}} +int __attribute__((target("ndd"))) apx_two_subs(void) { return 1; } +// expected-note@+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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
