https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92180

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |segher at gcc dot gnu.org,
                   |                            |uros at gcc dot gnu.org
          Component|tree-optimization           |rtl-optimization

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think that is because the combiner doesn't even try to combine into
instruction setting a hard register.
Consider:
unsigned int
foo (void)
{
  return __builtin_ia32_rdtsc ();
}

void
bar (unsigned int *p)
{
  *p = __builtin_ia32_rdtsc ();
}
Both have pretty much the same code before the combine, except
(insn 14 7 15 2 (set (reg/i:SI 0 ax)
        (subreg:SI (reg:DI 84) 0)) "pr92180.c":5:1 67 {*movsi_internal}
     (expr_list:REG_DEAD (reg:DI 84)
        (nil)))
(insn 15 14 0 2 (use (reg/i:SI 0 ax)) "pr92180.c":5:1 -1
     (nil))
in foo and
(insn 10 8 0 2 (set (mem:SI (reg/v/f:DI 84 [ p ]) [1 *p_5(D)+0 S4 A32])
        (subreg:SI (reg:DI 85) 0)) "pr92180.c":10:6 67 {*movsi_internal}
     (expr_list:REG_DEAD (reg:DI 85)
        (expr_list:REG_DEAD (reg/v/f:DI 84 [ p ])
            (nil))))
in bar.
For bar, combine uses the nonzero_bits to optimize the (unsigned int) ((x <<
32) | y) into (unsigned int) y, but in foo, probably because of the hard
register in there, it doesn't try anything.  Of course propagating anything
into an insn setting a hard register is risky, but in this case we'd just
replace one pseudo in the SUBREG_REG of the SET_SRC with another one.
GIMPLE optimizations can't do anything here, because the (x << 32) | y isn't
exposed there, we'd need a builtin with two return values for that kind of
thing.

Reply via email to