diff options
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 16 | ||||
-rw-r--r-- | clang/test/CodeGen/attr-cpuspecific.c | 9 |
2 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 2654247b959..448a8b298e8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2505,6 +2505,22 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { return CodeGenFunction::GetX86CpuSupportsMask(LHS.Conditions.Features) > CodeGenFunction::GetX86CpuSupportsMask(RHS.Conditions.Features); }); + + // If the list contains multiple 'default' versions, such as when it contains + // 'pentium' and 'generic', don't emit the call to the generic one (since we + // always run on at least a 'pentium'). We do this by deleting the 'least + // advanced' (read, lowest mangling letter). + while (Options.size() > 1 && + CodeGenFunction::GetX86CpuSupportsMask( + (Options.end() - 2)->Conditions.Features) == 0) { + StringRef LHSName = (Options.end() - 2)->Function->getName(); + StringRef RHSName = (Options.end() - 1)->Function->getName(); + if (LHSName.compare(RHSName) < 0) + Options.erase(Options.end() - 2); + else + Options.erase(Options.end() - 1); + } + CodeGenFunction CGF(*this); CGF.EmitMultiVersionResolver(ResolverFunc, Options); } diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 1b98b5dc967..6005456f0b2 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -96,6 +96,15 @@ void HasGeneric(void); // CHECK: ret void ()* @HasGeneric.A // CHECK-NOT: call void @llvm.trap +__attribute__((cpu_dispatch(atom, generic, pentium))) +int GenericAndPentium(int i, double d); +// CHECK: define i32 (i32, double)* @GenericAndPentium.resolver() +// CHECK: call void @__cpu_indicator_init +// CHECK: ret i32 (i32, double)* @GenericAndPentium.O +// CHECK: ret i32 (i32, double)* @GenericAndPentium.B +// CHECK-NOT: ret i32 (i32, double)* @GenericAndPentium.A +// CHECK-NOT: call void @llvm.trap + // CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" // CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" // CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87" |