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).

Reply via email to