I recently wanted to use multiversioning for BMI2 specific extensions
PDEP/PEXT, and noticed it wasn't there. So I wrote this patch to add it, and
also added AES, F16C and BMI1 for completeness.
Happy new year
`Allan
commit 062c09d45d22302ffbd4f86d88e16a1a0d49cd80
Author: Allan Sandfeld Jensen allan.jen...@digia.com
Date: Fri Dec 26 21:14:01 2014 +0100
AES, F16C BMI and BMI2 multiversion support
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff8a5e6..83f16a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-29 Allan Sandfeld Jensen sandf...@kde.org
+
+ * config/i386/i386.c (get_builtin_code_for_version): Add
+ support for AES, BMI, BMI2 and F16C multiversion functions.
+
2014-12-27 H.J. Lu hongjiu...@intel.com
PR target/64409
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d693fdb..a1b74dc 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -34261,15 +34261,22 @@ get_builtin_code_for_version (tree decl, tree
*predicate_list)
P_PROC_SSE4_A,
P_SSE4_1,
P_SSE4_2,
-P_PROC_SSE4_2,
P_POPCNT,
+P_PROC_SSE4_2,
+P_AES,
+P_PROC_AES,
P_AVX,
P_PROC_AVX,
+P_F16C,
+P_PROC_F16C,
+P_BMI,
+P_PROC_BMI,
P_FMA4,
P_XOP,
P_PROC_XOP,
P_FMA,
P_PROC_FMA,
+P_BMI2,
P_AVX2,
P_PROC_AVX2,
P_AVX512F,
@@ -34295,12 +34302,16 @@ get_builtin_code_for_version (tree decl, tree
*predicate_list)
{sse4a, P_SSE4_A},
{ssse3, P_SSSE3},
{sse4.1, P_SSE4_1},
- {sse4.2, P_SSE4_2},
{popcnt, P_POPCNT},
+ {sse4.2, P_SSE4_2},
+ {aes, P_AES},
{avx, P_AVX},
+ {f16c, P_F16C},
+ {bmi, P_BMI},
{fma4, P_FMA4},
{xop, P_XOP},
{fma, P_FMA},
+ {bmi2, P_BMI2},
{avx2, P_AVX2},
{avx512f, P_AVX512F}
};
@@ -34350,21 +34361,25 @@ get_builtin_code_for_version (tree decl, tree
*predicate_list)
priority = P_PROC_SSSE3;
break;
case PROCESSOR_NEHALEM:
- if (new_target-x_ix86_isa_flags OPTION_MASK_ISA_AES)
+ if (new_target-x_ix86_isa_flags OPTION_MASK_ISA_AES) {
arg_str = westmere;
- else
+priority = P_PROC_AES;
+ } else {
/* We translate arch=corei7 and arch=nehalem to
corei7 so that it will be mapped to M_INTEL_COREI7
as cpu type to cover all M_INTEL_COREI7_XXXs. */
arg_str = corei7;
- priority = P_PROC_SSE4_2;
+priority = P_PROC_SSE4_2;
+ }
break;
case PROCESSOR_SANDYBRIDGE:
- if (new_target-x_ix86_isa_flags OPTION_MASK_ISA_F16C)
+ if (new_target-x_ix86_isa_flags OPTION_MASK_ISA_F16C) {
arg_str = ivybridge;
- else
+ priority = P_PROC_F16C;
+ } else {
arg_str = sandybridge;
- priority = P_PROC_AVX;
+ priority = P_PROC_AVX;
+ }
break;
case PROCESSOR_HASWELL:
if (new_target-x_ix86_isa_flags OPTION_MASK_ISA_ADX)
@@ -34395,7 +34410,7 @@ get_builtin_code_for_version (tree decl, tree
*predicate_list)
break;
case PROCESSOR_BTVER2:
arg_str = btver2;
- priority = P_PROC_AVX;
+ priority = P_PROC_BMI;
break;
case PROCESSOR_BDVER1:
arg_str = bdver1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef6ddcc..5b11622 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-29 Allan Sandfeld Jensen sandf...@kde.org
+
+ * gcc.target/i386/funcspec-5.c: Test new multiversion targets.
+ * g++.dg/ext/mv17.C: Test BMI/BMI2 multiversion dispatcher.
+
2014-12-28 H.J. Lu hongjiu...@intel.com
* gcc.target/i386/pr57003.c: Skip on x32.
diff --git a/gcc/testsuite/g++.dg/ext/mv17.C b/gcc/testsuite/g++.dg/ext/mv17.C
new file mode 100644
index 000..311f217
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv17.C
@@ -0,0 +1,91 @@
+/* Test case to check if Multiversioning works for BMI and BMI2. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options -O2 } */
+
+#include assert.h
+
+// Check BMI feature selection works
+int foo () __attribute__((target(default)));
+int foo () __attribute__((target(bmi)));
+int foo () __attribute__((target(bmi2)));
+
+// Check specialized versions for archs with BMI is chosen over generic BMI
versions.
+int bar () __attribute__((target(default)));
+int bar () __attribute__((target(bmi)));
+int bar () __attribute__((target(bmi2)));
+int bar () __attribute__((target(arch=btver2)));
+int bar () __attribute__((target(arch=haswell)));
+
+int main ()
+{
+ int val = foo ();
+
+ if (__builtin_cpu_supports (bmi2))
+assert (val == 2);
+ else if