https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82259
--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Peter Cordes from comment #0) > Related: > > bool bt_unsigned(unsigned x, unsigned bit) { > //bit = 13; > return !(x & (1<<bit)); // 1U avoids test/set > } > > movl %esi, %ecx > movl $1, %eax > sall %cl, %eax > testl %edi, %eax > sete %al > ret > > This is weird. The code generated with 1U << bit is like the bt_signed > code above and has identical results, so gcc should emit whatever is optimal > for both cases. There are similar differences on ARM32. > > (With a fixed count, it just makes the difference between NOT vs. XOR $1.) > > If we're going to use setcc, it's definitely *much* better to use bt > instead of a variable-count shift + test. > > bt %esi, %edi > setz %al > ret A couple of *scc_bt patterns are missing. These are similar to already existing *jcc_bt patterns. Combine wants: Failed to match this instruction: (set (reg:QI 97) (eq:QI (zero_extract:SI (reg/v:SI 91 [ x ]) (const_int 1 [0x1]) (zero_extend:SI (subreg:QI (reg/v:SI 92 [ bit ]) 0))) (const_int 0 [0])))