i386.c (get_builtin_code_for_version): Add support for BMI and BMI2 multiversion...
authorAllan Sandfeld Jensen <sandfeld@kde.org>
Sun, 25 Jan 2015 18:17:46 +0000 (18:17 +0000)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 25 Jan 2015 18:17:46 +0000 (19:17 +0100)
gcc/ChangeLog:

* config/i386/i386.c (get_builtin_code_for_version): Add
support for BMI and BMI2 multiversion functions.
(fold_builtin_cpu): Add F_BMI and F_BMI2.

libgcc/ChangeLog:

* config/i386/cpuinfo.c (enum processor_features): Add FEATURE_BMI and
FEATURE_BMI2.
(get_available_features): Detect FEATURE_BMI and FEATURE_BMI2.

testsuite/ChangeLog:

* gcc.target/i386/funcspec-5.c: Test new multiversion targets.
* g++.dg/ext/mv17.C: Test BMI/BMI2 multiversion dispatcher.

Co-Authored-By: Uros Bizjak <ubizjak@gmail.com>
From-SVN: r220095

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/mv17.C [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/funcspec-5.c
libgcc/ChangeLog
libgcc/config/i386/cpuinfo.c

index fe3a6eab7d8639f40daa8712176e0b60e9680f96..f35e3c701441cb7e6be7aac26b33a0d5f112e6af 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-25  Allan Sandfeld Jensen  <sandfeld@kde.org>
+           Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.c (get_builtin_code_for_version): Add
+       support for BMI and BMI2 multiversion functions.
+
 2015-01-25  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        * emit-rtl.h (store_bit_field): Move prototype to expmed.h.
index 9ec40cb86370a7863956548e2f3601db81e70d96..441911d9b7ef56eb35af756792a0a16c7ab76c64 100644 (file)
@@ -34289,15 +34289,18 @@ 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_AVX,
     P_PROC_AVX,
+    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,
@@ -34323,12 +34326,14 @@ 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},
       {"avx", P_AVX},
+      {"bmi", P_BMI},
       {"fma4", P_FMA4},
       {"xop", P_XOP},
       {"fma", P_FMA},
+      {"bmi2", P_BMI2},
       {"avx2", P_AVX2},
       {"avx512f", P_AVX512F}
     };
@@ -34423,7 +34428,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";
@@ -35310,6 +35315,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
     F_XOP,
     F_FMA,
     F_AVX512F,
+    F_BMI,
+    F_BMI2,
     F_MAX
   };
 
@@ -35403,7 +35410,9 @@ fold_builtin_cpu (tree fndecl, tree *args)
       {"xop",    F_XOP},
       {"fma",    F_FMA},
       {"avx2",   F_AVX2},
-      {"avx512f",F_AVX512F}
+      {"avx512f",F_AVX512F},
+      {"bmi",    F_BMI},
+      {"bmi2",   F_BMI2}
     };
 
   tree __processor_model_type = build_processor_model_struct ();
index d1677593f246773dbc32a48bfc1d45fce48130e9..6f062e3d2be27e2ada1675ccb2007efe84316eca 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-25  Allan Sandfeld Jensen  <sandfeld@kde.org>
+
+       * gcc.target/i386/funcspec-5.c: Test new multiversion targets.
+       * g++.dg/ext/mv17.C: Test BMI/BMI2 multiversion dispatcher.
+
 2015-01-25  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/54236
diff --git a/gcc/testsuite/g++.dg/ext/mv17.C b/gcc/testsuite/g++.dg/ext/mv17.C
new file mode 100644 (file)
index 0000000..87c1324
--- /dev/null
@@ -0,0 +1,93 @@
+// Test case to check if Multiversioning works for BMI and BMI2.
+
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+// { 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 (__builtin_cpu_supports ("bmi"))
+    assert (val == 1);
+  else
+    assert (val == 0);
+
+  val = bar ();
+
+  if (__builtin_cpu_is ("btver2"))
+    assert (val == 5);
+  else if (__builtin_cpu_is ("haswell"))
+    assert (val == 6);
+  else if (__builtin_cpu_supports ("bmi2"))
+    assert (val == 2);
+  else if (__builtin_cpu_supports ("bmi"))
+    assert (val == 1);
+  else
+    assert (val == 0);
+
+  return 0;
+}
+
+int __attribute__ ((target("default")))
+foo ()
+{
+  return 0;
+}
+
+int __attribute__ ((target("bmi")))
+foo ()
+{
+  return 1;
+}
+int __attribute__ ((target("bmi2")))
+foo ()
+{
+  return 2;
+}
+
+int __attribute__ ((target("default")))
+bar ()
+{
+  return 0;
+}
+
+int __attribute__ ((target("bmi")))
+bar ()
+{
+  return 1;
+}
+int __attribute__ ((target("bmi2")))
+bar ()
+{
+  return 2;
+}
+
+int __attribute__ ((target("arch=btver2")))
+bar ()
+{
+  return 5;
+}
+
+int __attribute__ ((target("arch=haswell")))
+bar ()
+{
+  return 6;
+}
+
index d796484d7b34951dfef563c2276a1ad7f3662085..7185b5cb3297e3f9d9ffe209fdb69017349227b6 100644 (file)
@@ -25,6 +25,8 @@ extern void test_tbm (void)                   __attribute__((__target__("tbm")));
 extern void test_avx (void)                    __attribute__((__target__("avx")));
 extern void test_avx2 (void)                   __attribute__((__target__("avx2")));
 extern void test_avx512f (void)                        __attribute__((__target__("avx512f")));
+extern void test_bmi (void)                    __attribute__((__target__("bmi")));
+extern void test_bmi2 (void)                   __attribute__((__target__("bmi2")));
 
 extern void test_no_abm (void)                 __attribute__((__target__("no-abm")));
 extern void test_no_aes (void)                 __attribute__((__target__("no-aes")));
@@ -48,6 +50,8 @@ extern void test_no_tbm (void)                        __attribute__((__target__("no-tbm")));
 extern void test_no_avx (void)                 __attribute__((__target__("no-avx")));
 extern void test_no_avx2 (void)                __attribute__((__target__("no-avx2")));
 extern void test_no_avx512f (void)             __attribute__((__target__("no-avx512f")));
+extern void test_no_bmi (void)                 __attribute__((__target__("no-bmi")));
+extern void test_no_bmi2 (void)                        __attribute__((__target__("no-bmi2")));
 
 extern void test_arch_i386 (void)              __attribute__((__target__("arch=i386")));
 extern void test_arch_i486 (void)              __attribute__((__target__("arch=i486")));
index 3949c0adbc7d441bb2dfc69f4040a1eca9458cab..be24ed4c9bec4fb816732bb4ec80f6e4cac9475c 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-25  Allan Sandfeld Jensen  <sandfeld@kde.org>
+
+       * config/i386/cpuinfo.c (enum processor_features): Add FEATURE_BMI and
+       FEATURE_BMI2.
+       (get_available_features): Detect FEATURE_BMI and FEATURE_BMI2.
+
 2015-01-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/cpuinfo.c (processor_subtypes): Add
index c80083eec5053323aad4842da71e28395ed6f7c1..eaf2f100d59c050db91700e0e9f5e78761bd0782 100644 (file)
@@ -98,7 +98,9 @@ enum processor_features
   FEATURE_FMA4,
   FEATURE_XOP,
   FEATURE_FMA,
-  FEATURE_AVX512F
+  FEATURE_AVX512F,
+  FEATURE_BMI,
+  FEATURE_BMI2
 };
 
 struct __processor_model
@@ -289,8 +291,12 @@ get_available_features (unsigned int ecx, unsigned int edx,
     {
       unsigned int eax, ebx, ecx, edx;
       __cpuid_count (7, 0, eax, ebx, ecx, edx);
+      if (ebx & bit_BMI)
+        features |= (1 << FEATURE_BMI);
       if (ebx & bit_AVX2)
        features |= (1 << FEATURE_AVX2);
+      if (ebx & bit_BMI2)
+        features |= (1 << FEATURE_BMI2);
       if (ebx & bit_AVX512F)
        features |= (1 << FEATURE_AVX512F);
     }