diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1e77386aede2e..cdef43f2011bc 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -570,6 +570,7 @@ X86 Support - Support ISA of ``USER_MSR``. * Support intrinsic of ``_urdmsr``. * Support intrinsic of ``_uwrmsr``. +- Support ISA of ``AVX10.1``. Arm and AArch64 Support ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 640044622fc09..95849fef787ed 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -197,6 +197,9 @@ def m_wasm_Features_Driver_Group : OptionGroup<"">, def m_x86_Features_Group : OptionGroup<"">, Group, Visibility<[ClangOption, CLOption]>, DocName<"X86">; +def m_x86_AVX10_Features_Group : OptionGroup<"">, + Group, Visibility<[ClangOption, CLOption]>, + DocName<"X86 AVX10">; def m_riscv_Features_Group : OptionGroup<"">, Group, DocName<"RISC-V">; def m_ve_Features_Group : OptionGroup<"">, @@ -5754,6 +5757,12 @@ def msse4a : Flag<["-"], "msse4a">, Group; def mno_sse4a : Flag<["-"], "mno-sse4a">, Group; def mavx : Flag<["-"], "mavx">, Group; def mno_avx : Flag<["-"], "mno-avx">, Group; +def mavx10_1_256 : Flag<["-"], "mavx10.1-256">, Group; +def mno_avx10_1_256 : Flag<["-"], "mno-avx10.1-256">, Group; +def mavx10_1_512 : Flag<["-"], "mavx10.1-512">, Group; +def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, Group; +def mavx10_1 : Flag<["-"], "mavx10.1">, Alias; +def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Alias; def mavx2 : Flag<["-"], "mavx2">, Group; def mno_avx2 : Flag<["-"], "mno-avx2">, Group; def mavx512f : Flag<["-"], "mavx512f">, Group; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index bea5c52a7b8d7..ec9a518e56449 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -121,6 +121,7 @@ bool X86TargetInfo::initFeatureMap( std::vector UpdatedFeaturesVec; bool HasEVEX512 = true; bool HasAVX512F = false; + bool HasAVX10 = false; for (const auto &Feature : FeaturesVec) { // Expand general-regs-only to -x86, -mmx and -sse if (Feature == "+general-regs-only") { @@ -130,17 +131,35 @@ bool X86TargetInfo::initFeatureMap( continue; } - if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") + if (Feature.substr(0, 7) == "+avx10.") { + HasAVX10 = true; HasAVX512F = true; - if (HasAVX512F && Feature == "-avx512f") + if (Feature.substr(Feature.size() - 3, 3) == "512") { + HasEVEX512 = true; + } else if (Feature.substr(7, 2) == "1-") { + HasEVEX512 = false; + } + } else if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") { + HasAVX512F = true; + } else if (HasAVX512F && Feature == "-avx512f") { + HasAVX512F = false; + } else if (HasAVX10 && Feature == "-avx10.1-256") { + HasAVX10 = false; HasAVX512F = false; - if (HasEVEX512 && Feature == "-evex512") + } else if (!HasEVEX512 && Feature == "+evex512") { + HasEVEX512 = true; + } else if (HasEVEX512 && Feature == "-avx10.1-512") { HasEVEX512 = false; + } else if (HasEVEX512 && Feature == "-evex512") { + HasEVEX512 = false; + } UpdatedFeaturesVec.push_back(Feature); } if (HasAVX512F && HasEVEX512) UpdatedFeaturesVec.push_back("+evex512"); + else if (HasAVX10) + UpdatedFeaturesVec.push_back("-evex512"); if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec)) return false; @@ -241,6 +260,10 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasGFNI = true; } else if (Feature == "+evex512") { HasEVEX512 = true; + } else if (Feature == "+avx10.1-256") { + HasAVX10_1 = true; + } else if (Feature == "+avx10.1-512") { + HasAVX10_1_512 = true; } else if (Feature == "+avx512cd") { HasAVX512CD = true; } else if (Feature == "+avx512vpopcntdq") { @@ -748,6 +771,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasEVEX512) Builder.defineMacro("__EVEX512__"); + if (HasAVX10_1) + Builder.defineMacro("__AVX10_1__"); + if (HasAVX10_1_512) + Builder.defineMacro("__AVX10_1_512__"); if (HasAVX512CD) Builder.defineMacro("__AVX512CD__"); if (HasAVX512VPOPCNTDQ) @@ -973,6 +1000,8 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("amx-int8", true) .Case("amx-tile", true) .Case("avx", true) + .Case("avx10.1-256", true) + .Case("avx10.1-512", true) .Case("avx2", true) .Case("avx512f", true) .Case("avx512cd", true) @@ -1081,6 +1110,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("amx-int8", HasAMXINT8) .Case("amx-tile", HasAMXTILE) .Case("avx", SSELevel >= AVX) + .Case("avx10.1-256", HasAVX10_1) + .Case("avx10.1-512", HasAVX10_1_512) .Case("avx2", SSELevel >= AVX2) .Case("avx512f", SSELevel >= AVX512F) .Case("avx512cd", HasAVX512CD) diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 298db55c67442..99a64501d263c 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -95,6 +95,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasLWP = false; bool HasFMA = false; bool HasF16C = false; + bool HasAVX10_1 = false; + bool HasAVX10_1_512 = false; bool HasEVEX512 = false; bool HasAVX512CD = false; bool HasAVX512VPOPCNTDQ = false; diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index cf2bc63d74ada..848c26ddb43e4 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -229,6 +229,31 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, << D.getOpts().getOptionName(LVIOpt); } + bool HasAVX10 = false; + for (const Arg *A : Args.filtered(options::OPT_m_x86_AVX10_Features_Group)) { + StringRef Name = A->getOption().getName(); + A->claim(); + + // Skip over "-m". + assert(Name.startswith("m") && "Invalid feature name."); + Name = Name.substr(1); + + bool IsNegative = Name.startswith("no-"); + if (IsNegative) + Name = Name.substr(3); + +#ifndef NDEBUG + assert(Name.startswith("avx10.") && "Invalid AVX10 feature name."); + StringRef Version, Width; + std::tie(Version, Width) = Name.substr(6).split('-'); + assert(Version == "1" && "Invalid AVX10 feature name."); + assert((Width == "256" || Width == "512") && "Invalid AVX10 feature name."); +#endif + + Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); + HasAVX10 = true; + } + // Now add any that the user explicitly requested on the command line, // which may override the defaults. for (const Arg *A : Args.filtered(options::OPT_m_x86_Features_Group, @@ -246,9 +271,14 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, continue; } + StringRef AVX512Name = Name; bool IsNegative = Name.startswith("no-"); if (IsNegative) Name = Name.substr(3); + if (HasAVX10 && (Name.startswith("avx512") || Name == "evex512")) { + D.Diag(diag::warn_drv_unused_argument) << AVX512Name; + continue; + } Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); } diff --git a/clang/test/CodeGen/X86/avx512-error.c b/clang/test/CodeGen/X86/avx512-error.c index 8e42105ec1127..133e7d01ea33c 100644 --- a/clang/test/CodeGen/X86/avx512-error.c +++ b/clang/test/CodeGen/X86/avx512-error.c @@ -1,9 +1,17 @@ -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify -DFEATURE_TEST=1 -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify -DFEATURE_TEST=2 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=1 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -target-feature -evex512 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=2 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512bw -emit-llvm -o /dev/null -verify -DFEATURE_TEST=3 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-256 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=1 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-256 -emit-llvm -o /dev/null -verify=noevex -DFEATURE_TEST=2 +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx10.1-512 -emit-llvm -o /dev/null -verify -DFEATURE_TEST=3 #include -#if FEATURE_TEST == 1 +#if FEATURE_TEST & 3 +// expected-no-diagnostics +#endif + +#if FEATURE_TEST & 1 __attribute__((target("avx512bw,evex512"))) __m512d zmm_verify_ok(__m512d a) { // No error emitted if we have "evex512" feature. @@ -12,11 +20,11 @@ __m512d zmm_verify_ok(__m512d a) { __m512d zmm_error(__m512d a) { // CHECK-LABEL: @test_mm512_sqrt_pd - return __builtin_ia32_sqrtpd512(a, _MM_FROUND_CUR_DIRECTION); // expected-error {{'__builtin_ia32_sqrtpd512' needs target feature avx512f,evex512}} + return __builtin_ia32_sqrtpd512(a, _MM_FROUND_CUR_DIRECTION); // noevex-error {{'__builtin_ia32_sqrtpd512' needs target feature avx512f,evex512}} } #endif -#if FEATURE_TEST == 2 +#if FEATURE_TEST & 2 __attribute__((target("avx512bw,evex512"))) __mmask64 k64_verify_ok(__mmask64 a) { // No error emitted if we have "evex512" feature. @@ -24,6 +32,6 @@ __mmask64 k64_verify_ok(__mmask64 a) { } __mmask64 test_knot_mask64(__mmask64 a) { - return _knot_mask64(a); // expected-error {{always_inline function '_knot_mask64' requires target feature 'evex512', but would be inlined into function 'test_knot_mask64' that is compiled without support for 'evex512'}} + return _knot_mask64(a); // noevex-error {{always_inline function '_knot_mask64' requires target feature 'evex512', but would be inlined into function 'test_knot_mask64' that is compiled without support for 'evex512'}} } #endif diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c index d261c007a0a2a..304398678216f 100644 --- a/clang/test/CodeGen/attr-target-x86.c +++ b/clang/test/CodeGen/attr-target-x86.c @@ -36,6 +36,9 @@ void __attribute__((target("arch=x86-64-v2"))) x86_64_v2(void) {} void __attribute__((target("arch=x86-64-v3"))) x86_64_v3(void) {} void __attribute__((target("arch=x86-64-v4"))) x86_64_v4(void) {} +void __attribute__((target("avx10.1-256"))) avx10_1_256(void) {} +void __attribute__((target("avx10.1-512"))) avx10_1_512(void) {} + // Check that we emit the additional subtarget and cpu features for foo and not for baz or bar. // CHECK: baz{{.*}} #0 // CHECK: foo{{.*}} #1 @@ -51,13 +54,15 @@ void __attribute__((target("arch=x86-64-v4"))) x86_64_v4(void) {} // CHECK: lake{{.*}} #7 // CHECK: use_before_def{{.*}} #7 // CHECK: walrus{{.*}} #8 +// CHECK: avx10_1_256{{.*}} #12 +// CHECK: avx10_1_512{{.*}} #13 // CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87" "tune-cpu"="i686" // CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" // CHECK-NOT: tune-cpu -// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-aes,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-gfni,-kl,-pclmul,-sha,-sha512,-sm3,-sm4,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-widekl,-xop" "tune-cpu"="i686" +// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-aes,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-gfni,-kl,-pclmul,-sha,-sha512,-sm3,-sm4,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-widekl,-xop" "tune-cpu"="i686" // CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+crc32,+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" "tune-cpu"="i686" -// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-sha512,-sm3,-sm4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" "tune-cpu"="i686" -// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes" +// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-avx,-avx10.1-256,-avx10.1-512,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512fp16,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-avxifma,-avxneconvert,-avxvnni,-avxvnniint16,-avxvnniint8,-f16c,-fma,-fma4,-sha512,-sm3,-sm4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" "tune-cpu"="i686" +// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-avx10.1-256,-avx10.1-512,-vaes" // CHECK-NOT: tune-cpu // CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cmov,+cx8,+x87,-3dnow,-3dnowa,-mmx" // CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+cx8,+mmx" @@ -70,3 +75,6 @@ void __attribute__((target("arch=x86-64-v4"))) x86_64_v4(void) {} // CHECK-SAME: "target-features"="+avx,+avx2,+bmi,+bmi2,+cmov,+crc32,+cx16,+cx8,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" // CHECK: "target-cpu"="x86-64-v4" // CHECK-SAME: "target-features"="+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+cmov,+crc32,+cx16,+cx8,+evex512,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" + +// CHECK: #12 = {{.*}}"target-cpu"="i686" "target-features"="+aes,+avx,+avx10.1-256,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+f16c,+fma,+mmx,+pclmul,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,-avx10.1-512,-evex512" +// CHECK: #13 = {{.*}}"target-cpu"="i686" "target-features"="+aes,+avx,+avx10.1-256,+avx10.1-512,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+cmov,+crc32,+cx8,+evex512,+f16c,+fma,+mmx,+pclmul,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave" diff --git a/clang/test/CodeGen/target-avx-abi-diag.c b/clang/test/CodeGen/target-avx-abi-diag.c index 34995dc471545..72de0fa2a39bd 100644 --- a/clang/test/CodeGen/target-avx-abi-diag.c +++ b/clang/test/CodeGen/target-avx-abi-diag.c @@ -5,6 +5,10 @@ // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=1 -o - -S // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=2 -o - -S // RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -target-feature -evex512 -verify=avx512-256 -DAVX512_ERR=3 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-512 -verify=both -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=1 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=2 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx10.1-256 -verify=avx512-256 -DAVX512_ERR=3 -o - -S // REQUIRES: x86-registered-target // both-no-diagnostics diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 464dcda504bbd..3ef11ffcb695d 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -374,6 +374,26 @@ // EVEX512: "-target-feature" "+evex512" // NO-EVEX512: "-target-feature" "-evex512" +// RUN: %clang --target=i386 -mavx10.1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: %clang --target=i386 -mavx10.1-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: %clang --target=i386 -mavx10.1-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_512 %s +// RUN: %clang --target=i386 -mavx10.1-256 -mavx10.1-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_512 %s +// RUN: %clang --target=i386 -mavx10.1-512 -mavx10.1-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: not %clang --target=i386 -march=i386 -mavx10.1-128 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s +// RUN: not %clang --target=i386 -march=i386 -mavx10.a-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s +// RUN: not %clang --target=i386 -march=i386 -mavx10.1024-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mavx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mno-avx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mevex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mno-evex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s +// AVX10_1_256: "-target-feature" "+avx10.1-256" +// AVX10_1_512: "-target-feature" "+avx10.1-512" +// BAD-AVX10: error: unknown argument{{:?}} '-mavx10.{{.*}}' +// AVX10-AVX512: warning: argument unused during compilation: '{{.*}}avx512f' +// AVX10-AVX512-NOT: "avx512f" +// AVX10-EVEX512: warning: argument unused during compilation: '{{.*}}evex512' +// AVX10-EVEX512-NOT: "evex512" + // RUN: %clang --target=i386 -musermsr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=USERMSR %s // RUN: %clang --target=i386 -mno-usermsr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-USERMSR %s // USERMSR: "-target-feature" "+usermsr" diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index 873416d79b125..7c03ff87eefe3 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -750,6 +750,20 @@ // AVXVNNIINT16NOAVX2-NOT: #define __AVX2__ 1 // AVXVNNIINT16NOAVX2-NOT: #define __AVXVNNIINT16__ 1 +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-256 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-256 -mno-avx512f -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s +// AVX10_1_256: #define __AVX10_1__ 1 +// AVX10_1_256: #define __AVX512F__ 1 +// AVX10_1_256-NOT: __EVEX512__ + +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -mno-avx512f -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -mno-evex512 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s +// AVX10_1_512: #define __AVX10_1__ 1 +// AVX10_1_512: #define __AVX512F__ 1 +// AVX10_1_512: #define __EVEX512__ 1 + // RUN: %clang -target i686-unknown-linux-gnu -march=atom -musermsr -x c -E -dM -o - %s | FileCheck -check-prefix=USERMSR %s // USERMSR: #define __USERMSR__ 1 diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 94b43800c17bd..ade7318f2359b 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -134,6 +134,7 @@ Changes to the X86 Backend with C, but also fixes code generation where LLVM already assumed that the type matched and called into libgcc helper functions. * Support ISA of ``USER_MSR``. +* Support ISA of ``AVX10.1-256`` and ``AVX10.1-512``. Changes to the OCaml bindings ----------------------------- diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def index 709ff8603b042..cc0f8bd31ae7d 100644 --- a/llvm/include/llvm/TargetParser/X86TargetParser.def +++ b/llvm/include/llvm/TargetParser/X86TargetParser.def @@ -241,6 +241,8 @@ X86_FEATURE (SM3, "sm3") X86_FEATURE (SM4, "sm4") X86_FEATURE (AVXVNNIINT16, "avxvnniint16") X86_FEATURE (EVEX512, "evex512") +X86_FEATURE (AVX10_1, "avx10.1-256") +X86_FEATURE (AVX10_1_512, "avx10.1-512") X86_FEATURE (USERMSR, "usermsr") // These features aren't really CPU features, but the frontend can set them. X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk") diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index f3f8d5718dfc2..556cef1f4f97e 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -333,6 +333,14 @@ def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true", "Support movdiri instruction (direct store integer)">; def FeatureMOVDIR64B : SubtargetFeature<"movdir64b", "HasMOVDIR64B", "true", "Support movdir64b instruction (direct store 64 bytes)">; +def FeatureAVX10_1 : SubtargetFeature<"avx10.1-256", "HasAVX10_1", "true", + "Support AVX10.1 up to 256-bit instruction", + [FeatureCDI, FeatureVBMI, FeatureIFMA, FeatureVNNI, + FeatureBF16, FeatureVPOPCNTDQ, FeatureVBMI2, FeatureBITALG, + FeatureVAES, FeatureVPCLMULQDQ, FeatureFP16]>; +def FeatureAVX10_1_512 : SubtargetFeature<"avx10.1-512", "HasAVX10_1_512", "true", + "Support AVX10.1 up to 512-bit instruction", + [FeatureAVX10_1, FeatureEVEX512]>; // Ivy Bridge and newer processors have enhanced REP MOVSB and STOSB (aka // "string operations"). See "REP String Enhancement" in the Intel Software diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index cb740bc99f788..9046b6af463ac 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -904,6 +904,8 @@ def HasAVX : Predicate<"Subtarget->hasAVX()">; def HasAVX2 : Predicate<"Subtarget->hasAVX2()">; def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">; def HasEVEX512 : Predicate<"Subtarget->hasEVEX512()">; +def HasAVX10_1 : Predicate<"Subtarget->hasAVX10_1()">; +def HasAVX10_1_512 : Predicate<"Subtarget->hasAVX10_1_512()">; def HasAVX512 : Predicate<"Subtarget->hasAVX512()">; def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">; def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">; diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index b320911d3ce27..337f918c93175 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1797,6 +1797,7 @@ bool sys::getHostCPUFeatures(StringMap &Features) { Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave; Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1); Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1); + Features["avx10.1-256"] = HasLeaf7Subleaf1 && ((EDX >> 19) & 1); bool HasLeafD = MaxLevel >= 0xd && !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); @@ -1815,6 +1816,11 @@ bool sys::getHostCPUFeatures(StringMap &Features) { MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX); Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1); + bool HasLeaf24 = + MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX); + Features["avx10.1-512"] = + Features["avx10.1-256"] && HasLeaf24 && ((EBX >> 18) & 1); + return true; } #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp index 94849f915daa1..f9aece5aaa24e 100644 --- a/llvm/lib/TargetParser/X86TargetParser.cpp +++ b/llvm/lib/TargetParser/X86TargetParser.cpp @@ -611,6 +611,15 @@ constexpr FeatureBitset ImpliedFeaturesWIDEKL = FeatureKL; // AVXVNNI Features constexpr FeatureBitset ImpliedFeaturesAVXVNNI = FeatureAVX2; +// AVX10 Features +constexpr FeatureBitset ImpliedFeaturesAVX10_1 = + FeatureAVX512CD | FeatureAVX512VBMI | FeatureAVX512IFMA | + FeatureAVX512VNNI | FeatureAVX512BF16 | FeatureAVX512VPOPCNTDQ | + FeatureAVX512VBMI2 | FeatureAVX512BITALG | FeatureVAES | FeatureVPCLMULQDQ | + FeatureAVX512FP16; +constexpr FeatureBitset ImpliedFeaturesAVX10_1_512 = + FeatureAVX10_1 | FeatureEVEX512; + constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = { #define X86_FEATURE(ENUM, STR) {{"+" STR}, ImpliedFeatures##ENUM}, #include "llvm/TargetParser/X86TargetParser.def"