aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2023-08-23 22:08:55 -0700
committerFangrui Song <i@maskray.me>2023-08-23 22:08:55 -0700
commit7a41af86041bd757b7f380d7f645403d4e1725ca (patch)
tree990cbfab93469ed07a8600b32d93738b547b933c /clang/lib/CodeGen/CodeGenFunction.cpp
parent2289c7f76038660f5ecc8d54bdd428d5f162f810 (diff)
downloadllvm-7a41af86041bd757b7f380d7f645403d4e1725ca.zip
llvm-7a41af86041bd757b7f380d7f645403d4e1725ca.tar.gz
llvm-7a41af86041bd757b7f380d7f645403d4e1725ca.tar.bz2
[X86] Support arch=x86-64{,-v2,-v3,-v4} for target_clones attribute
GCC 12 (https://gcc.gnu.org/PR101696) allows `arch=x86-64` `arch=x86-64-v2` `arch=x86-64-v3` `arch=x86-64-v4` in the target_clones function attribute. This patch ports the feature. * Set KeyFeature to `x86-64{,-v2,-v3,-v4}` in `Processors[]`, to be used by X86TargetInfo::multiVersionSortPriority * builtins: change `__cpu_features2` to an array like libgcc. Define `FEATURE_X86_64_{BASELINE,V2,V3,V4}` and depended ISA feature bits. * CGBuiltin.cpp: update EmitX86CpuSupports to handle `arch=x86-64*`. Close https://github.com/llvm/llvm-project/issues/55830 Reviewed By: pengfei Differential Revision: https://reviews.llvm.org/D158329
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 89138dd..7b456ed 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2681,8 +2681,27 @@ llvm::Value *CodeGenFunction::FormX86ResolverCondition(
const MultiVersionResolverOption &RO) {
llvm::Value *Condition = nullptr;
- if (!RO.Conditions.Architecture.empty())
- Condition = EmitX86CpuIs(RO.Conditions.Architecture);
+ if (!RO.Conditions.Architecture.empty()) {
+ StringRef Arch = RO.Conditions.Architecture;
+ std::array<uint32_t, 4> Mask{};
+ // If arch= specifies an x86-64 micro-architecture level, test a special
+ // feature named FEATURE_X86_64_*, otherwise we use __builtin_cpu_is.
+ if (Arch.consume_front("x86-64")) {
+ if (Arch.empty()) // FEATURE_X86_64_BASELINE 95=2*32+31
+ Mask[2] = 1u << 31;
+ else if (Arch == "-v2") // FEATURE_X86_64_V2 96==3*32+0
+ Mask[3] = 1u << 0;
+ else if (Arch == "-v3") // FEATURE_X86_64_V3 97==3*32+1
+ Mask[3] = 1u << 1;
+ else if (Arch == "-v4") // FEATURE_X86_64_V3 98==3*32+2
+ Mask[3] = 1u << 2;
+ else
+ llvm_unreachable("invalid x86-64 micro-architecture level");
+ Condition = EmitX86CpuSupports(Mask);
+ } else {
+ Condition = EmitX86CpuIs(Arch);
+ }
+ }
if (!RO.Conditions.Features.empty()) {
llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);