Skip to content

[X86][AVX10] Permit AVX512 options/features used together with AVX10 #71318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticCommonKinds.td
Original file line number Diff line number Diff line change
@@ -346,6 +346,8 @@ def err_opt_not_valid_on_target : Error<
"option '%0' cannot be specified on this target">;
def err_invalid_feature_combination : Error<
"invalid feature combination: %0">;
def warn_invalid_feature_combination : Warning<
"invalid feature combination: %0">, InGroup<DiagGroup<"invalid-feature-combination">>;
def warn_target_unrecognized_env : Warning<
"mismatch between architecture and environment in target triple '%0'; did you mean '%1'?">,
InGroup<InvalidCommandLineArgument>;
63 changes: 42 additions & 21 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
@@ -119,9 +119,14 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabled(Features, F, true);

std::vector<std::string> UpdatedFeaturesVec;
bool HasEVEX512 = true;
std::vector<std::string> UpdatedAVX10FeaturesVec;
enum { FE_NOSET = -1, FE_FALSE, FE_TRUE };
int HasEVEX512 = FE_NOSET;
bool HasAVX512F = false;
bool HasAVX10 = false;
bool HasAVX10_512 = false;
std::string LastAVX10;
std::string LastAVX512;
for (const auto &Feature : FeaturesVec) {
// Expand general-regs-only to -x86, -mmx and -sse
if (Feature == "+general-regs-only") {
@@ -131,35 +136,51 @@ bool X86TargetInfo::initFeatureMap(
continue;
}

if (Feature.substr(0, 7) == "+avx10.") {
HasAVX10 = true;
HasAVX512F = true;
if (Feature.substr(Feature.size() - 3, 3) == "512") {
HasEVEX512 = true;
} else if (Feature.substr(7, 2) == "1-") {
HasEVEX512 = false;
if (Feature.substr(1, 6) == "avx10.") {
if (Feature[0] == '+') {
HasAVX10 = true;
if (Feature.substr(Feature.size() - 3, 3) == "512")
HasAVX10_512 = true;
LastAVX10 = Feature;
} else if (HasAVX10 && Feature == "-avx10.1-256") {
HasAVX10 = false;
HasAVX10_512 = false;
} else if (HasAVX10_512 && Feature == "-avx10.1-512") {
HasAVX10_512 = false;
}
// Postpone AVX10 features handling after AVX512 settled.
UpdatedAVX10FeaturesVec.push_back(Feature);
continue;
} else if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") {
HasAVX512F = true;
LastAVX512 = Feature;
} else if (HasAVX512F && Feature == "-avx512f") {
HasAVX512F = false;
} else if (HasAVX10 && Feature == "-avx10.1-256") {
HasAVX10 = false;
HasAVX512F = false;
} else if (!HasEVEX512 && Feature == "+evex512") {
HasEVEX512 = true;
} else if (HasEVEX512 && Feature == "-avx10.1-512") {
HasEVEX512 = false;
} else if (HasEVEX512 && Feature == "-evex512") {
HasEVEX512 = false;
} else if (HasEVEX512 != FE_TRUE && Feature == "+evex512") {
HasEVEX512 = FE_TRUE;
continue;
} else if (HasEVEX512 != FE_FALSE && Feature == "-evex512") {
HasEVEX512 = FE_FALSE;
continue;
}

UpdatedFeaturesVec.push_back(Feature);
}
if (HasAVX512F && HasEVEX512)
UpdatedFeaturesVec.push_back("+evex512");
else if (HasAVX10)
UpdatedFeaturesVec.push_back("-evex512");
llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it mean the flags for AVX10 Features will be in the vector UpdatedFeaturesVec 2 times?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, there is a continue in handling avx10* features

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.

// HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512
// according to other features.
if (HasAVX512F) {
UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512"
: "+evex512");
if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE)
Diags.Report(diag::warn_invalid_feature_combination)
<< LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512";
} else if (HasAVX10) {
if (HasEVEX512 != FE_NOSET)
Diags.Report(diag::warn_invalid_feature_combination)
<< LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512");
UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512");
}

if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
return false;
7 changes: 0 additions & 7 deletions clang/lib/Driver/ToolChains/Arch/X86.cpp
Original file line number Diff line number Diff line change
@@ -229,7 +229,6 @@ 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();
@@ -251,7 +250,6 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
#endif

Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
HasAVX10 = true;
}

// Now add any that the user explicitly requested on the command line,
@@ -271,14 +269,9 @@ 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));
}

8 changes: 6 additions & 2 deletions clang/lib/Headers/avx2intrin.h
Original file line number Diff line number Diff line change
@@ -15,8 +15,12 @@
#define __AVX2INTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx2"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx2"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx2,no-evex512"), __min_vector_width__(256)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the function targeted at avx2 need no-evex512?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have defined parts AVX512 intrinsics with no-evex512 and some of them will call into these AVX2 intrinsics.
Then we are facing a problem that we cannot call them in some cases because we didn't specify no-evex512 for them.

#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx2,no-evex512"), __min_vector_width__(128)))

/* SSE4 Multiple Packed Sums of Absolute Difference. */
/// Computes sixteen sum of absolute difference (SAD) operations on sets of
3 changes: 2 additions & 1 deletion clang/lib/Headers/avx512bf16intrin.h
Original file line number Diff line number Diff line change
@@ -23,7 +23,8 @@ typedef __bf16 __bfloat16 __attribute__((deprecated("use __bf16 instead")));
__attribute__((__always_inline__, __nodebug__, __target__("avx512bf16,evex512"), \
__min_vector_width__(512)))
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, __target__("avx512bf16")))
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512bf16,no-evex512")))

/// Convert One BF16 Data to One Single Float Data.
///
4 changes: 3 additions & 1 deletion clang/lib/Headers/avx512bwintrin.h
Original file line number Diff line number Diff line change
@@ -20,7 +20,9 @@ typedef unsigned long long __mmask64;
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS512 __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,evex512"), __min_vector_width__(512)))
#define __DEFAULT_FN_ATTRS64 __attribute__((__always_inline__, __nodebug__, __target__("avx512bw,evex512")))
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512bw")))
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512bw,no-evex512")))

static __inline __mmask32 __DEFAULT_FN_ATTRS
_knot_mask32(__mmask32 __M)
4 changes: 3 additions & 1 deletion clang/lib/Headers/avx512dqintrin.h
Original file line number Diff line number Diff line change
@@ -16,7 +16,9 @@

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS512 __attribute__((__always_inline__, __nodebug__, __target__("avx512dq,evex512"), __min_vector_width__(512)))
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512dq")))
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512dq,no-evex512")))

static __inline __mmask8 __DEFAULT_FN_ATTRS
_knot_mask8(__mmask8 __M)
8 changes: 6 additions & 2 deletions clang/lib/Headers/avx512fintrin.h
Original file line number Diff line number Diff line change
@@ -168,8 +168,12 @@ typedef enum

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS512 __attribute__((__always_inline__, __nodebug__, __target__("avx512f,evex512"), __min_vector_width__(512)))
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512f"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512f")))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512f,no-evex512"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512f,no-evex512")))

/* Create vectors with repeated elements */

6 changes: 4 additions & 2 deletions clang/lib/Headers/avx512fp16intrin.h
Original file line number Diff line number Diff line change
@@ -25,10 +25,12 @@ typedef _Float16 __m512h_u __attribute__((__vector_size__(64), __aligned__(1)));
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512fp16,evex512"), __min_vector_width__(512)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, __target__("avx512fp16"), \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512fp16,no-evex512"), \
__min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, __target__("avx512fp16"), \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512fp16,no-evex512"), \
__min_vector_width__(128)))

static __inline__ _Float16 __DEFAULT_FN_ATTRS512 _mm512_cvtsh_h(__m512h __a) {
10 changes: 8 additions & 2 deletions clang/lib/Headers/avx512ifmavlintrin.h
Original file line number Diff line number Diff line change
@@ -15,8 +15,14 @@
#define __IFMAVLINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512ifma,avx512vl"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512ifma,avx512vl"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512ifma,avx512vl,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512ifma,avx512vl,no-evex512"), \
__min_vector_width__(256)))

#define _mm_madd52hi_epu64(X, Y, Z) \
((__m128i)__builtin_ia32_vpmadd52huq128((__v2di)(X), (__v2di)(Y), \
5 changes: 0 additions & 5 deletions clang/lib/Headers/avx512pfintrin.h
Original file line number Diff line number Diff line change
@@ -14,9 +14,6 @@
#ifndef __AVX512PFINTRIN_H
#define __AVX512PFINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx512pf")))

#define _mm512_mask_prefetch_i32gather_pd(index, mask, addr, scale, hint) \
__builtin_ia32_gatherpfdpd((__mmask8)(mask), (__v8si)(__m256i)(index), \
(void const *)(addr), (int)(scale), \
@@ -92,6 +89,4 @@
__builtin_ia32_scatterpfqps((__mmask8)(mask), (__v8di)(__m512i)(index), \
(void *)(addr), (int)(scale), (int)(hint))

#undef __DEFAULT_FN_ATTRS

#endif
11 changes: 8 additions & 3 deletions clang/lib/Headers/avx512vbmivlintrin.h
Original file line number Diff line number Diff line change
@@ -15,9 +15,14 @@
#define __VBMIVLINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vbmi,avx512vl"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vbmi,avx512vl"), __min_vector_width__(256)))

#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vbmi,avx512vl,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vbmi,avx512vl,no-evex512"), \
__min_vector_width__(256)))

static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_permutex2var_epi8(__m128i __A, __m128i __I, __m128i __B)
14 changes: 8 additions & 6 deletions clang/lib/Headers/avx512vlbf16intrin.h
Original file line number Diff line number Diff line change
@@ -15,12 +15,14 @@
#ifndef __AVX512VLBF16INTRIN_H
#define __AVX512VLBF16INTRIN_H

#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl, avx512bf16"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl, avx512bf16"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bf16,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bf16,no-evex512"), \
__min_vector_width__(256)))

/// Convert Two Packed Single Data to One Packed BF16 Data.
///
10 changes: 8 additions & 2 deletions clang/lib/Headers/avx512vlbitalgintrin.h
Original file line number Diff line number Diff line change
@@ -15,8 +15,14 @@
#define __AVX512VLBITALGINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bitalg"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bitalg"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bitalg,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bitalg,no-evex512"), \
__min_vector_width__(256)))

static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_popcnt_epi16(__m256i __A)
10 changes: 8 additions & 2 deletions clang/lib/Headers/avx512vlbwintrin.h
Original file line number Diff line number Diff line change
@@ -15,8 +15,14 @@
#define __AVX512VLBWINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bw"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512bw"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bw,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512bw,no-evex512"), \
__min_vector_width__(256)))

/* Integer compare */

11 changes: 8 additions & 3 deletions clang/lib/Headers/avx512vlcdintrin.h
Original file line number Diff line number Diff line change
@@ -14,9 +14,14 @@
#define __AVX512VLCDINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512cd"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512cd"), __min_vector_width__(256)))

#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512cd,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512cd,no-evex512"), \
__min_vector_width__(256)))

static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_broadcastmb_epi64 (__mmask8 __A)
10 changes: 8 additions & 2 deletions clang/lib/Headers/avx512vldqintrin.h
Original file line number Diff line number Diff line change
@@ -15,8 +15,14 @@
#define __AVX512VLDQINTRIN_H

/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512dq"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl,avx512dq"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512dq,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512dq,no-evex512"), \
__min_vector_width__(256)))

static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_mullo_epi64 (__m256i __A, __m256i __B) {
4 changes: 2 additions & 2 deletions clang/lib/Headers/avx512vlfp16intrin.h
Original file line number Diff line number Diff line change
@@ -19,11 +19,11 @@
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512fp16, avx512vl"), \
__target__("avx512fp16,avx512vl,no-evex512"), \
__min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512fp16, avx512vl"), \
__target__("avx512fp16,avx512vl,no-evex512"), \
__min_vector_width__(128)))

static __inline__ _Float16 __DEFAULT_FN_ATTRS128 _mm_cvtsh_h(__m128h __a) {
10 changes: 8 additions & 2 deletions clang/lib/Headers/avx512vlintrin.h
Original file line number Diff line number Diff line change
@@ -14,8 +14,14 @@
#ifndef __AVX512VLINTRIN_H
#define __AVX512VLINTRIN_H

#define __DEFAULT_FN_ATTRS128 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 __attribute__((__always_inline__, __nodebug__, __target__("avx512vl"), __min_vector_width__(256)))
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,no-evex512"), \
__min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,no-evex512"), \
__min_vector_width__(256)))

typedef short __v2hi __attribute__((__vector_size__(4)));
typedef char __v4qi __attribute__((__vector_size__(4)));
Loading