aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
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);