summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2018-12-08 04:42:42 +0000
committerTom Stellard <tstellar@redhat.com>2018-12-08 04:42:42 +0000
commit5a9000ba8358f77796e23ba7ab13a3250b1b726d (patch)
tree35842d29d662011133e626285717652396360262
parentf98e746cba238f468ed4f9cdd3a3e0067c490db5 (diff)
downloadbcm5719-llvm-5a9000ba8358f77796e23ba7ab13a3250b1b726d.zip
bcm5719-llvm-5a9000ba8358f77796e23ba7ab13a3250b1b726d.tar.gz
Merging r345826:
------------------------------------------------------------------------ r345826 | erichkeane | 2018-11-01 05:50:37 -0700 (Thu, 01 Nov 2018) | 15 lines CPU-Dispatch-- Fix conflict between 'generic' and 'pentium' When a dispatch function was being emitted that had both a generic and a pentium configuration listed, we would assert. This is because neither configuration has any 'features' associated with it so they were both considered the 'default' version. 'pentium' lacks any features because we implement it in terms of __builtin_cpu_supports (instead of Intel proprietary checks), which is unable to decern between the two. The fix for this is to omit the 'generic' version from the dispatcher if both are present. This permits existing code to compile, and still will choose the 'best' version available (since 'pentium' is technically better than 'generic'). Change-Id: I4b69f3e0344e74cbdbb04497845d5895dd05fda0 ------------------------------------------------------------------------ llvm-svn: 348682
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp16
-rw-r--r--clang/test/CodeGen/attr-cpuspecific.c9
2 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 2654247..448a8b2 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 1b98b5d..6005456 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"
OpenPOWER on IntegriCloud