On Mon, May 7, 2012 at 10:00 AM, Jakub Jelinek <ja...@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 <ubiz...@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.
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"