diff options
author | Fangrui Song <i@maskray.me> | 2023-08-23 22:08:55 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2023-08-23 22:08:55 -0700 |
commit | 7a41af86041bd757b7f380d7f645403d4e1725ca (patch) | |
tree | 990cbfab93469ed07a8600b32d93738b547b933c /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 2289c7f76038660f5ecc8d54bdd428d5f162f810 (diff) | |
download | llvm-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.cpp | 23 |
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); |