From 939911c558653f1514f1280c67f04b4bae0297c8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Sun, 25 Jan 2015 18:17:46 +0000 Subject: [PATCH] i386.c (get_builtin_code_for_version): Add support for BMI and BMI2 multiversion functions. 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 From-SVN: r220095 --- gcc/ChangeLog | 6 ++ gcc/config/i386/i386.c | 17 +++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/ext/mv17.C | 93 ++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/funcspec-5.c | 4 + libgcc/ChangeLog | 6 ++ libgcc/config/i386/cpuinfo.c | 8 +- 7 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/mv17.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe3a6eab7d8..f35e3c70144 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-01-25 Allan Sandfeld Jensen + Uros Bizjak + + * config/i386/i386.c (get_builtin_code_for_version): Add + support for BMI and BMI2 multiversion functions. + 2015-01-25 Prathamesh Kulkarni * emit-rtl.h (store_bit_field): Move prototype to expmed.h. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9ec40cb8637..441911d9b7e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1677593f24..6f062e3d2be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-25 Allan Sandfeld Jensen + + * 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 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 index 00000000000..87c13246ed2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/mv17.C @@ -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 + +// 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; +} + diff --git a/gcc/testsuite/gcc.target/i386/funcspec-5.c b/gcc/testsuite/gcc.target/i386/funcspec-5.c index d796484d7b3..7185b5cb329 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-5.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-5.c @@ -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"))); diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 3949c0adbc7..be24ed4c9be 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2015-01-25 Allan Sandfeld Jensen + + * 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 * config/i386/cpuinfo.c (processor_subtypes): Add diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c index c80083eec50..eaf2f100d59 100644 --- a/libgcc/config/i386/cpuinfo.c +++ b/libgcc/config/i386/cpuinfo.c @@ -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); } -- 2.30.2