Patchwork x86: emit tzcnt unconditionally

login
register
mail settings
Submitter Uros Bizjak
Date May 7, 2012, 2:42 p.m.
Message ID <CAFULd4Yk-EyS_r2E=KZ_L_Hr05ZBCBbyQBGu1F_-S8UREqHQxA@mail.gmail.com>
Download mbox | patch
Permalink /patch/157335/
State New
Headers show

Comments

Uros Bizjak - May 7, 2012, 2:42 p.m.
On Mon, May 7, 2012 at 10:00 AM, Jakub Jelinek <jakub@redhat.com> wrote:

>> > Shouldn't that be done only for generic tuning?  If somebody uses
>> > -mtune=native, then emitting rep; bsf is overkill, the code is intended
>> > to be run on a CPU without (or with TARGET_BMI with) tzcnt insn support.
>>
>> Yes, this is a good idea.
>>
>> Something like attached patch?
>
> Yeah, but probably with the TARGET_BMI and optimize_function_for_size_p
> lines swapped.
>
> Because i386.h defines
> CTZ_DEFINED_VALUE_AT_ZERO to 1 for TARGET_BMI, therefore it isn't
> undefined for TARGET_BMI, so even for -Os you can't just use bsf.

I have committed following patch:

2012-05-07  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/i386.md (ctz<mode>2): Emit rep;bsf
	only for TARGET_GENERIC, when not optimizing for size.
	(*ffs<mode>_1): Ditto.

Tested on x86_64-pc-linux-gnu {,-m32}.

Uros.

Patch

Index: i386.md
===================================================================
--- i386.md	(revision 187223)
+++ i386.md	(working copy)
@@ -12113,21 +12113,25 @@ 
 	(ctz:SWI48 (match_dup 1)))]
   ""
 {
-  if (optimize_function_for_size_p (cfun))
-    return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
-  else if (TARGET_BMI)
+  if (TARGET_BMI)
     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
-  else 
+  else if (optimize_function_for_size_p (cfun))
+    ;
+  else if (TARGET_GENERIC)
     /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI.  */
     return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
+
+  return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
 }
   [(set_attr "type" "alu1")
    (set_attr "prefix_0f" "1")
    (set (attr "prefix_rep")
      (if_then_else
-       (match_test "optimize_function_for_size_p (cfun)")
-       (const_string "0")
-       (const_string "1")))
+       (ior (match_test "TARGET_BMI")
+	    (and (not (match_test "optimize_function_for_size_p (cfun)"))
+		 (match_test "TARGET_GENERIC")))
+       (const_string "1")
+       (const_string "0")))
    (set_attr "mode" "<MODE>")])
 
 (define_insn "ctz<mode>2"
@@ -12136,21 +12140,25 @@ 
    (clobber (reg:CC FLAGS_REG))]
   ""
 {
-  if (optimize_function_for_size_p (cfun))
-    return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
-  else if (TARGET_BMI)
+  if (TARGET_BMI)
     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
-  else 
+  else if (optimize_function_for_size_p (cfun))
+    ;
+  else if (TARGET_GENERIC)
     /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI.  */
     return "rep; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
+
+  return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
 }
   [(set_attr "type" "alu1")
    (set_attr "prefix_0f" "1")
    (set (attr "prefix_rep")
      (if_then_else
-       (match_test "optimize_function_for_size_p (cfun)")
-       (const_string "0")
-       (const_string "1")))
+       (ior (match_test "TARGET_BMI")
+	    (and (not (match_test "optimize_function_for_size_p (cfun)"))
+		 (match_test "TARGET_GENERIC")))
+       (const_string "1")
+       (const_string "0")))
    (set_attr "mode" "<MODE>")])
 
 (define_expand "clz<mode>2"