]> granicus.if.org Git - clang/commitdiff
Merging r345826:
authorTom Stellard <tstellar@redhat.com>
Sat, 8 Dec 2018 04:42:42 +0000 (04:42 +0000)
committerTom Stellard <tstellar@redhat.com>
Sat, 8 Dec 2018 04:42:42 +0000 (04:42 +0000)
------------------------------------------------------------------------
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
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_70@348682 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGen/attr-cpuspecific.c

index 2654247b95972a4ec322f87d53767c2ba2f5477a..448a8b298e83f5fd1f5ac4d72514324512f0c611 100644 (file)
@@ -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);
 }
index 1b98b5dc9678074ac1be0493af56daf81755fbfb..6005456f0b29893577f5031b365521f7788d08fd 100644 (file)
@@ -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"