http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52898
--- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-01 22:47:26 UTC --- I had a closer look at what is going on with cbranchdi and cmpeqdi_t. If cmpeqdi_t is enabled through the option -mcmpeqdi it will trigger the 'if (TARGET_CMPEQDI_T)' code paths in expand_cbranchdi4. These will then emit the cmpeqdi_t insn for EQ and NE cmp codes. The problem is then that for DImode comparisons with a constant there are no patterns that match e.g. (set (reg:SI T_REG) (eq:SI (match_operand:DI 0 "arith_reg_operand" "r") (const_int 2))) As far as I understand, basically what the cbranchdi pattern in the expand_cbranchdi4 function is trying to do is to fold the branches to turn something like this: cmp/eq r0,r2 bf 0f cmp/eq r1,r3 0: b{f|t} <target> into this: cmp/eq r0,r2 b{f|t} <target> cmp/eq r1,r2 b{f|t} <target> The function output_branchy_insn tries to do the same, but when emitting the asm output. When zero-displacement branches are fast, all DImode comparisons (if I'm not mistaken) can be done in constant 2 cycles in either 3 or 4 opcodes + the actual branch. Probably it would also be better to split out the first comparison insn from the fixed asm output and make the second comparison conditional (similar to the abs patterns).