http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29776
Steven Bosscher <steven at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed|2011-12-24 00:00:00 |2012-07-29 0:00 CC| |uros at gcc dot gnu.org --- Comment #3 from Steven Bosscher <steven at gcc dot gnu.org> 2012-07-29 13:23:30 UTC --- Tested with trunk r189929 on x86-64 (generic). #define MODE signed // or unsigned unsigned mask[8]; unsigned foo(unsigned y, unsigned char x) { MODE int c = (MODE) __builtin_ctz(x); unsigned int m = mask[c]; return y & m; } With MODE==signed: movzbl %sil, %esi movl %edi, %eax rep; bsfl %esi, %esi movslq %esi, %rsi andl mask(,%rsi,4), %eax ret With MODE==unsigned: movzbl %sil, %esi movl %edi, %eax rep; bsfl %esi, %esi movl %esi, %esi andl mask(,%rsi,4), %eax ret The "movl %esi, %esi" is a zeroextendsidi: #(insn:TI 9 2 10 2 (parallel [ # (set (reg:SI 4 si [orig:60 D.1716 ] [60]) # (ctz:SI (reg:SI 4 si [orig:68 D.1715 ] [68]))) # (clobber (reg:CC 17 flags)) # ]) t.c:6 666 {ctzsi2} # (expr_list:REG_UNUSED (reg:CC 17 flags) # (nil))) rep; bsfl %esi, %esi # 9 ctzsi2 [length = 4] #(insn:TI 10 9 12 2 (set (reg:DI 4 si [orig:70 D.1716 ] [70]) # (zero_extend:DI (reg:SI 4 si [orig:60 D.1716 ] [60]))) t.c:7 113 {*zero_extendsidi2_rex64} # (nil)) movl %esi, %esi # 10 *zero_extendsidi2_rex64/1 [length = 2] Perhaps REE can be taught about ctz giving a non-negative result.