Re: [PATCH] Function Multiversioning Bug, checking for function versions

2013-01-02 Thread Sriraman Tallam
I committed this trivial patch to fix some corner case bugs in
Function Multiversioning.

* config/i386/i386.c (ix86_get_function_versions_dispatcher): Fix bug
in loop predicate.
(fold_builtin_cpu): Do not share cpu model decls across statements.

Index: config/i386/i386.c
===
--- config/i386/i386.c  (revision 194817)
+++ config/i386/i386.c  (working copy)
@@ -29290,7 +29290,7 @@ ix86_get_function_versions_dispatcher (void *decl)

   /* Set the dispatcher for all the versions.  */
   it_v = default_version_info;
-  while (it_v-next != NULL)
+  while (it_v != NULL)
 {
   it_v-dispatcher_resolver = dispatch_decl;
   it_v = it_v-next;
@@ -29626,8 +29626,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
   {avx2,   F_AVX2}
 };

-  static tree __processor_model_type = NULL_TREE;
-  static tree __cpu_model_var = NULL_TREE;
+  tree __processor_model_type = NULL_TREE;
+  tree __cpu_model_var = NULL_TREE;

   if (__processor_model_type == NULL_TREE)
 __processor_model_type = build_processor_model_struct ();



Thanks,
-Sri.

On Thu, Dec 27, 2012 at 2:05 AM, Andreas Schwab sch...@linux-m68k.org wrote:
 diff --git a/gcc/ChangeLog b/gcc/ChangeLog
 index 148388d..575e03a 100644
 --- a/gcc/ChangeLog
 +++ b/gcc/ChangeLog
 @@ -1,4 +1,7 @@
 - .mine
 +2012-12-27  Andreas Schwab  sch...@linux-m68k.org
 +
 +   * target.def (supports_function_versions): Fix typo.
 +
  2012-12-26  Sriraman Tallam  tmsri...@google.com

 * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
 @@ -15,12 +18,10 @@
 * (is_function_default_version): Check target string.
 * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.

 -===
  2012-12-27  Steven Bosscher  ste...@gcc.gnu.org

 * cgraph.c (verify_cgraph_node): Don't allocate/free visited_nodes 
 set.

 - .r194729
  2012-12-25  John David Anglin  dave.ang...@nrc-cnrc.gc.ca

 PR target/53789
 diff --git a/gcc/target.def b/gcc/target.def
 index 79bb955..d0547be 100644
 --- a/gcc/target.def
 +++ b/gcc/target.def
 @@ -2839,7 +2839,7 @@ DEFHOOK
  (supports_function_versions,
   ,
   bool, (void),
 - hool_bool_void_false)
 + hook_bool_void_false)

  /* Function to determine if one function can inline another function.  */
  #undef HOOK_PREFIX
 --
 1.8.0.2


 --
 Andreas Schwab, sch...@linux-m68k.org
 GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
 And now for something completely different.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2013-01-02 Thread Jakub Jelinek
On Wed, Jan 02, 2013 at 12:23:45PM -0800, Sriraman Tallam wrote:
 --- config/i386/i386.c  (revision 194817)
 +++ config/i386/i386.c  (working copy)
 @@ -29290,7 +29290,7 @@ ix86_get_function_versions_dispatcher (void *decl)
 
/* Set the dispatcher for all the versions.  */
it_v = default_version_info;
 -  while (it_v-next != NULL)
 +  while (it_v != NULL)
  {
it_v-dispatcher_resolver = dispatch_decl;
it_v = it_v-next;
 @@ -29626,8 +29626,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
{avx2,   F_AVX2}
  };
 
 -  static tree __processor_model_type = NULL_TREE;
 -  static tree __cpu_model_var = NULL_TREE;
 +  tree __processor_model_type = NULL_TREE;
 +  tree __cpu_model_var = NULL_TREE;
 
if (__processor_model_type == NULL_TREE)
  __processor_model_type = build_processor_model_struct ();

If __processor_model_type is always NULL_TREE above, then you should write
  tree __processor_model_type = build_processor_model_struct ();
rather than the extra if with an always true condition.

Jakub


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2013-01-02 Thread Sriraman Tallam
On Wed, Jan 2, 2013 at 1:01 PM, Jakub Jelinek ja...@redhat.com wrote:
 On Wed, Jan 02, 2013 at 12:23:45PM -0800, Sriraman Tallam wrote:
 --- config/i386/i386.c  (revision 194817)
 +++ config/i386/i386.c  (working copy)
 @@ -29290,7 +29290,7 @@ ix86_get_function_versions_dispatcher (void *decl)

/* Set the dispatcher for all the versions.  */
it_v = default_version_info;
 -  while (it_v-next != NULL)
 +  while (it_v != NULL)
  {
it_v-dispatcher_resolver = dispatch_decl;
it_v = it_v-next;
 @@ -29626,8 +29626,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
{avx2,   F_AVX2}
  };

 -  static tree __processor_model_type = NULL_TREE;
 -  static tree __cpu_model_var = NULL_TREE;
 +  tree __processor_model_type = NULL_TREE;
 +  tree __cpu_model_var = NULL_TREE;

if (__processor_model_type == NULL_TREE)
  __processor_model_type = build_processor_model_struct ();

 If __processor_model_type is always NULL_TREE above, then you should write
   tree __processor_model_type = build_processor_model_struct ();
 rather than the extra if with an always true condition.

Right, sorry! Oversight in a hurry to fix the bug.

-Sri.


 Jakub


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2013-01-02 Thread Sriraman Tallam
On Wed, Jan 2, 2013 at 1:01 PM, Jakub Jelinek ja...@redhat.com wrote:
 On Wed, Jan 02, 2013 at 12:23:45PM -0800, Sriraman Tallam wrote:
 --- config/i386/i386.c  (revision 194817)
 +++ config/i386/i386.c  (working copy)
 @@ -29290,7 +29290,7 @@ ix86_get_function_versions_dispatcher (void *decl)

/* Set the dispatcher for all the versions.  */
it_v = default_version_info;
 -  while (it_v-next != NULL)
 +  while (it_v != NULL)
  {
it_v-dispatcher_resolver = dispatch_decl;
it_v = it_v-next;
 @@ -29626,8 +29626,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
{avx2,   F_AVX2}
  };

 -  static tree __processor_model_type = NULL_TREE;
 -  static tree __cpu_model_var = NULL_TREE;
 +  tree __processor_model_type = NULL_TREE;
 +  tree __cpu_model_var = NULL_TREE;

if (__processor_model_type == NULL_TREE)
  __processor_model_type = build_processor_model_struct ();

 If __processor_model_type is always NULL_TREE above, then you should write
   tree __processor_model_type = build_processor_model_struct ();
 rather than the extra if with an always true condition.

Submitted this patch to fix this.

* config/i386/i386.c (fold_builtin_cpu): Remove unnecessary checks for
NULL.

--- config/i386/i386.c (revision 194827)
+++ config/i386/i386.c (working copy)
@@ -29626,16 +29626,10 @@ fold_builtin_cpu (tree fndecl, tree *args)
   {avx2,   F_AVX2}
 };

-  tree __processor_model_type = NULL_TREE;
-  tree __cpu_model_var = NULL_TREE;
+  tree __processor_model_type = build_processor_model_struct ();
+  tree __cpu_model_var = make_var_decl (__processor_model_type,
+  __cpu_model);

-  if (__processor_model_type == NULL_TREE)
-__processor_model_type = build_processor_model_struct ();
-
-  if (__cpu_model_var == NULL_TREE)
-__cpu_model_var = make_var_decl (__processor_model_type,
- __cpu_model);
-
   gcc_assert ((args != NULL)  (*args != NULL));

   param_string_cst = *args;

Thanks,
-Sri.



 Jakub


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-27 Thread Andreas Schwab
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 148388d..575e03a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,7 @@
- .mine
+2012-12-27  Andreas Schwab  sch...@linux-m68k.org
+
+   * target.def (supports_function_versions): Fix typo.
+
 2012-12-26  Sriraman Tallam  tmsri...@google.com
 
* doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
@@ -15,12 +18,10 @@
* (is_function_default_version): Check target string.
* TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.
 
-===
 2012-12-27  Steven Bosscher  ste...@gcc.gnu.org
 
* cgraph.c (verify_cgraph_node): Don't allocate/free visited_nodes set.
 
- .r194729
 2012-12-25  John David Anglin  dave.ang...@nrc-cnrc.gc.ca
 
PR target/53789
diff --git a/gcc/target.def b/gcc/target.def
index 79bb955..d0547be 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2839,7 +2839,7 @@ DEFHOOK
 (supports_function_versions,
  ,
  bool, (void),
- hool_bool_void_false)
+ hook_bool_void_false)
 
 /* Function to determine if one function can inline another function.  */
 #undef HOOK_PREFIX
-- 
1.8.0.2


-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-27 Thread Sriraman Tallam
On Thu, Dec 27, 2012 at 2:05 AM, Andreas Schwab sch...@linux-m68k.org wrote:
 diff --git a/gcc/ChangeLog b/gcc/ChangeLog
 index 148388d..575e03a 100644
 --- a/gcc/ChangeLog
 +++ b/gcc/ChangeLog
 @@ -1,4 +1,7 @@
 - .mine
 +2012-12-27  Andreas Schwab  sch...@linux-m68k.org
 +
 +   * target.def (supports_function_versions): Fix typo.
 +

  2012-12-26  Sriraman Tallam  tmsri...@google.com

 * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
 @@ -15,12 +18,10 @@
 * (is_function_default_version): Check target string.
 * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.

 -===
  2012-12-27  Steven Bosscher  ste...@gcc.gnu.org

 * cgraph.c (verify_cgraph_node): Don't allocate/free visited_nodes 
 set.

 - .r194729
  2012-12-25  John David Anglin  dave.ang...@nrc-cnrc.gc.ca

 PR target/53789
 diff --git a/gcc/target.def b/gcc/target.def
 index 79bb955..d0547be 100644
 --- a/gcc/target.def
 +++ b/gcc/target.def
 @@ -2839,7 +2839,7 @@ DEFHOOK
  (supports_function_versions,
   ,
   bool, (void),
 - hool_bool_void_false)
 + hook_bool_void_false)

Thanks for the fix.

-Sri.


  /* Function to determine if one function can inline another function.  */
  #undef HOOK_PREFIX
 --
 1.8.0.2


 --
 Andreas Schwab, sch...@linux-m68k.org
 GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
 And now for something completely different.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-27 Thread Alexander Ivchenko
I'm sorry - I didn't notice that it works only for c++ frontend. It
works for me now!

thanks,
Alexander

2012/12/27 Sriraman Tallam tmsri...@google.com:
 On Thu, Dec 27, 2012 at 2:05 AM, Andreas Schwab sch...@linux-m68k.org wrote:
 diff --git a/gcc/ChangeLog b/gcc/ChangeLog
 index 148388d..575e03a 100644
 --- a/gcc/ChangeLog
 +++ b/gcc/ChangeLog
 @@ -1,4 +1,7 @@
 - .mine
 +2012-12-27  Andreas Schwab  sch...@linux-m68k.org
 +
 +   * target.def (supports_function_versions): Fix typo.
 +

  2012-12-26  Sriraman Tallam  tmsri...@google.com

 * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
 @@ -15,12 +18,10 @@
 * (is_function_default_version): Check target string.
 * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.

 -===
  2012-12-27  Steven Bosscher  ste...@gcc.gnu.org

 * cgraph.c (verify_cgraph_node): Don't allocate/free visited_nodes 
 set.

 - .r194729
  2012-12-25  John David Anglin  dave.ang...@nrc-cnrc.gc.ca

 PR target/53789
 diff --git a/gcc/target.def b/gcc/target.def
 index 79bb955..d0547be 100644
 --- a/gcc/target.def
 +++ b/gcc/target.def
 @@ -2839,7 +2839,7 @@ DEFHOOK
  (supports_function_versions,
   ,
   bool, (void),
 - hool_bool_void_false)
 + hook_bool_void_false)

 Thanks for the fix.

 -Sri.


  /* Function to determine if one function can inline another function.  */
  #undef HOOK_PREFIX
 --
 1.8.0.2


 --
 Andreas Schwab, sch...@linux-m68k.org
 GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
 And now for something completely different.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-26 Thread Sriraman Tallam
I committed this patch with the fix.

Thanks,
-Sri.

On Tue, Dec 18, 2012 at 4:13 PM, Diego Novillo dnovi...@google.com wrote:
 On Tue, Dec 18, 2012 at 6:38 PM, Sriraman Tallam tmsri...@google.com wrote:

 The function versions are now determined purely based on the string
 value and not on DECL_FUNCTION_SPECIFIC_TARGET fields. So, this check
 is not necessary.

 Ah, OK.  Thanks.

 The patch is OK with that minor fix then.


 Diego.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-18 Thread Diego Novillo

On 2012-11-16 14:55 , Sriraman Tallam wrote:

Hi,

The previous patch was incomplete because the front-end strips off
invalid target attributes which I did not consider. The attached
updated patch handles this with updated test cases.

Thanks,
-Sri.

On Thu, Nov 15, 2012 at 2:08 PM, Sriraman Tallam tmsri...@google.com wrote:

Hi,

Currently, function multiversioning determines that two functions
are different by comparing the arch type and isa flags that are set
after the target string is processed. This leads to cases where  the
versions become identical when the command-line target options are
altered.

For example, these two versions:

__attribute__ target ((sse4.2)))
int foo ()
{
}

__attribute__ target ((popcnt)))
int foo ()
{
}

become identical when -mpopcnt and -msse4.2 are used while building,
leading to build errors.

To avoid this, I have modified the function version determination to
just compare the target string.
Patch attached. Is this alright to submit?

Thanks,
-Sri.


* doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
new target hook.
* doc/tm.texi: Regenerate.
* c-family/c-common.c (handle_target_attribute): Retain target attribute
for targets that support versioning.
* target.def (supports_function_versions): New hook.
* config/i386/i386.c (ix86_function_versions): Use target string
to check for function versions instead of target flags.
* testsuite/g++.dg/mv1.C: Remove target options.
* testsuite/g++.dg/mv2.C: Ditto.
* testsuite/g++.dg/mv3.C: Ditto.
* testsuite/g++.dg/mv4.C: Ditto.
* testsuite/g++.dg/mv5.C: Ditto.
* cp/class.c (add_method): Remove calls
to DECL_FUNCTION_SPECIFIC_TARGET.
* config/i386/i386.c (ix86_function_versions): Use target string
to check for function versions instead of target flags.
* (ix86_supports_function_versions): New function.
* (is_function_default_version): Check target string.
* TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.



Looks mostly OK.


Index: cp/class.c
===
--- cp/class.c  (revision 193486)
+++ cp/class.c  (working copy)
@@ -1095,8 +1095,6 @@ add_method (tree type, tree method, tree using_dec
   TREE_CODE (method) == FUNCTION_DECL
   !DECL_EXTERN_C_P (fn)
   !DECL_EXTERN_C_P (method)
-  (DECL_FUNCTION_SPECIFIC_TARGET (fn)
- || DECL_FUNCTION_SPECIFIC_TARGET (method))


I don't follow.  Given the new hook, why do you need to remove this check?


+/* This function returns true if FN1 and FN2 are versions of the same function,
+   that is, the target strings of the function decls are different.  This 
assumes
+   that FN1 and FN2 have the same signature.  */
+
+static bool
+ix86_function_versions (tree fn1, tree fn2)
+{


Any particular reason why you moved this function down here?


+  tree attr1, attr2;
+  const char *attr_str1, *attr_str2;
+  char *target1, *target2;
+  bool result;
+
+  if (TREE_CODE (fn1) != FUNCTION_DECL
+  || TREE_CODE (fn2) != FUNCTION_DECL)
+return false;
+
+  attr1 = lookup_attribute (target, DECL_ATTRIBUTES (fn1));
+  attr2 = lookup_attribute (target, DECL_ATTRIBUTES (fn2));
+
+  /* Atleast one function decl should have the target attribute specified.  */


s/Atleast/At least/


Diego.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-18 Thread Sriraman Tallam
Hi Diego,

   Thanks for the review.

On Tue, Dec 18, 2012 at 8:04 AM, Diego Novillo dnovi...@google.com wrote:
 On 2012-11-16 14:55 , Sriraman Tallam wrote:

 Hi,

 The previous patch was incomplete because the front-end strips off
 invalid target attributes which I did not consider. The attached
 updated patch handles this with updated test cases.

 Thanks,
 -Sri.

 On Thu, Nov 15, 2012 at 2:08 PM, Sriraman Tallam tmsri...@google.com
 wrote:

 Hi,

 Currently, function multiversioning determines that two functions
 are different by comparing the arch type and isa flags that are set
 after the target string is processed. This leads to cases where  the
 versions become identical when the command-line target options are
 altered.

 For example, these two versions:

 __attribute__ target ((sse4.2)))
 int foo ()
 {
 }

 __attribute__ target ((popcnt)))
 int foo ()
 {
 }

 become identical when -mpopcnt and -msse4.2 are used while building,
 leading to build errors.

 To avoid this, I have modified the function version determination to
 just compare the target string.
 Patch attached. Is this alright to submit?

 Thanks,
 -Sri.


 * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS):
 Document
 new target hook.
 * doc/tm.texi: Regenerate.
 * c-family/c-common.c (handle_target_attribute): Retain target
 attribute
 for targets that support versioning.
 * target.def (supports_function_versions): New hook.
 * config/i386/i386.c (ix86_function_versions): Use target string
 to check for function versions instead of target flags.
 * testsuite/g++.dg/mv1.C: Remove target options.
 * testsuite/g++.dg/mv2.C: Ditto.
 * testsuite/g++.dg/mv3.C: Ditto.
 * testsuite/g++.dg/mv4.C: Ditto.
 * testsuite/g++.dg/mv5.C: Ditto.
 * cp/class.c (add_method): Remove calls
 to DECL_FUNCTION_SPECIFIC_TARGET.
 * config/i386/i386.c (ix86_function_versions): Use target string
 to check for function versions instead of target flags.
 * (ix86_supports_function_versions): New function.
 * (is_function_default_version): Check target string.
 * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.



 Looks mostly OK.

 Index: cp/class.c
 ===
 --- cp/class.c  (revision 193486)
 +++ cp/class.c  (working copy)
 @@ -1095,8 +1095,6 @@ add_method (tree type, tree method, tree using_dec
TREE_CODE (method) == FUNCTION_DECL
!DECL_EXTERN_C_P (fn)
!DECL_EXTERN_C_P (method)
 -  (DECL_FUNCTION_SPECIFIC_TARGET (fn)
 - || DECL_FUNCTION_SPECIFIC_TARGET (method))


 I don't follow.  Given the new hook, why do you need to remove this check?

The function versions are now determined purely based on the string
value and not on DECL_FUNCTION_SPECIFIC_TARGET fields. So, this check
is not necessary.



 +/* This function returns true if FN1 and FN2 are versions of the same
 function,
 +   that is, the target strings of the function decls are different.  This
 assumes
 +   that FN1 and FN2 have the same signature.  */
 +
 +static bool
 +ix86_function_versions (tree fn1, tree fn2)
 +{


 Any particular reason why you moved this function down here?

Just refactoring, keeping functions that are related to
ix86_dispatch_versions together.


 +  tree attr1, attr2;
 +  const char *attr_str1, *attr_str2;
 +  char *target1, *target2;
 +  bool result;
 +
 +  if (TREE_CODE (fn1) != FUNCTION_DECL
 +  || TREE_CODE (fn2) != FUNCTION_DECL)
 +return false;
 +
 +  attr1 = lookup_attribute (target, DECL_ATTRIBUTES (fn1));
 +  attr2 = lookup_attribute (target, DECL_ATTRIBUTES (fn2));
 +
 +  /* Atleast one function decl should have the target attribute
 specified.  */


 s/Atleast/At least/

I will make this change.

Thanks,
-Sri.



 Diego.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-12-18 Thread Diego Novillo
On Tue, Dec 18, 2012 at 6:38 PM, Sriraman Tallam tmsri...@google.com wrote:

 The function versions are now determined purely based on the string
 value and not on DECL_FUNCTION_SPECIFIC_TARGET fields. So, this check
 is not necessary.

Ah, OK.  Thanks.

The patch is OK with that minor fix then.


Diego.


Re: [PATCH] Function Multiversioning Bug, checking for function versions

2012-11-16 Thread Sriraman Tallam
Hi,

   The previous patch was incomplete because the front-end strips off
invalid target attributes which I did not consider. The attached
updated patch handles this with updated test cases.

Thanks,
-Sri.

On Thu, Nov 15, 2012 at 2:08 PM, Sriraman Tallam tmsri...@google.com wrote:
 Hi,

Currently, function multiversioning determines that two functions
 are different by comparing the arch type and isa flags that are set
 after the target string is processed. This leads to cases where  the
 versions become identical when the command-line target options are
 altered.

 For example, these two versions:

 __attribute__ target ((sse4.2)))
 int foo ()
 {
 }

 __attribute__ target ((popcnt)))
 int foo ()
 {
 }

 become identical when -mpopcnt and -msse4.2 are used while building,
 leading to build errors.

 To avoid this, I have modified the function version determination to
 just compare the target string.
 Patch attached. Is this alright to submit?

 Thanks,
 -Sri.

* doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
new target hook.
* doc/tm.texi: Regenerate.
* c-family/c-common.c (handle_target_attribute): Retain target attribute
for targets that support versioning.
* target.def (supports_function_versions): New hook.
* config/i386/i386.c (ix86_function_versions): Use target string
to check for function versions instead of target flags.
* testsuite/g++.dg/mv1.C: Remove target options.
* testsuite/g++.dg/mv2.C: Ditto.
* testsuite/g++.dg/mv3.C: Ditto.
* testsuite/g++.dg/mv4.C: Ditto.
* testsuite/g++.dg/mv5.C: Ditto.
* cp/class.c (add_method): Remove calls
to DECL_FUNCTION_SPECIFIC_TARGET.
* config/i386/i386.c (ix86_function_versions): Use target string
to check for function versions instead of target flags.
* (ix86_supports_function_versions): New function.
* (is_function_default_version): Check target string.
* TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.


Index: doc/tm.texi
===
--- doc/tm.texi (revision 193485)
+++ doc/tm.texi (working copy)
@@ -9937,6 +9937,11 @@ different target specific attributes, that is, the
 different target machines.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS (void)
+This target hook returns @code{true} if the target supports function
+multiversioning.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree 
@var{callee})
 This target hook returns @code{false} if the @var{caller} function
 cannot inline @var{callee}, based on target specific information.  By
Index: doc/tm.texi.in
===
--- doc/tm.texi.in  (revision 193485)
+++ doc/tm.texi.in  (working copy)
@@ -9798,6 +9798,11 @@ different target specific attributes, that is, the
 different target machines.
 @end deftypefn
 
+@hook TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
+This target hook returns @code{true} if the target supports function
+multiversioning.
+@end deftypefn
+
 @hook TARGET_CAN_INLINE_P
 This target hook returns @code{false} if the @var{caller} function
 cannot inline @var{callee}, based on target specific information.  By
Index: c-family/c-common.c
===
--- c-family/c-common.c (revision 193485)
+++ c-family/c-common.c (working copy)
@@ -8720,8 +8720,12 @@ handle_target_attribute (tree *node, tree name, tr
   warning (OPT_Wattributes, %qE attribute ignored, name);
   *no_add_attrs = true;
 }
+  /* Do not strip invalid target attributes for targets which support function
+ multiversioning as the target string is used to determine versioned
+ functions.  */
   else if (! targetm.target_option.valid_attribute_p (*node, name, args,
- flags))
+ flags)
+   ! targetm.target_option.supports_function_versions ())
 *no_add_attrs = true;
 
   return NULL_TREE;
Index: target.def
===
--- target.def  (revision 193485)
+++ target.def  (working copy)
@@ -2826,6 +2826,14 @@ DEFHOOK
  bool, (tree decl1, tree decl2),
  hook_bool_tree_tree_false)
 
+/* This function returns true if the target supports function
+   multiversioning.  */
+DEFHOOK
+(supports_function_versions,
+ ,
+ bool, (void),
+ hool_bool_void_false)
+
 /* Function to determine if one function can inline another function.  */
 #undef HOOK_PREFIX
 #define HOOK_PREFIX TARGET_
Index: testsuite/g++.dg/mv2.C
===
--- testsuite/g++.dg/mv2.C  (revision 193485)
+++ testsuite/g++.dg/mv2.C  (working copy)
@@ -2,7 +2,7 @@
dispatching order