tzcnt is encoded as "rep;bsf" and unlike lzcnt is a drop-in replacement if we don't care about the flags (it has the same semantics for non-zero values).
Since bsf is usually slower, just emit tzcnt unconditionally. However, write it as rep;bsf unless -mbmi is in use, to cater for old assemblers. Bootstrapped on a non-BMI x86_64-linux host, regtest in progress. Ok for mainline? Paolo 2012-04-27 Paolo Bonzini <bonz...@gnu.org> * config/i386/i386.md (ctz<mode>2): Emit tzcnt (as rep;bsf) instead of bsf. Index: i386/i386.md =================================================================== --- i386/i386.md (revisione 186904) +++ i386/i386.md (copia locale) @@ -12082,14 +12082,15 @@ (define_insn "ctz<mode>2" (clobber (reg:CC FLAGS_REG))] "" { + /* tzcnt expands to rep;bsf and we can use it even if !TARGET_BMI. */ if (TARGET_BMI) return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; else - return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; + return "rep;bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; } [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") - (set (attr "prefix_rep") (symbol_ref "TARGET_BMI")) + (set_attr "prefix_rep" "1") (set_attr "mode" "<MODE>")]) (define_expand "clz<mode>2"