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

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Testcase usable for the testsuite:
int a, b = 1;

__attribute__((noinline, noclone)) void
foo (int x)
{
  if (x != 5)
    __builtin_abort ();
}

int
main ()
{
  int i;
  for (i = 0; i < 56; i++)
    for (; a; a--)
      ;
  int *c = &b;
  if (*c)
    *c = 1 % (unsigned int) *c | 5;

  foo (b);

  return 0;
}

This indeed is a combiner bug.
Trying 28, 29 -> 30:
Failed to match this instruction:
(parallel [
        (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2]  <var_decl
0x7f3aa8245cf0 b>) [1 b+0 S4 A32])
            (const_int 5 [0x5]))
        (set (reg:SI 90 [ D.1884 ])
            (const_int 5 [0x5]))
    ])
Failed to match this instruction:
(parallel [
        (set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2]  <var_decl
0x7f3aa8245cf0 b>) [1 b+0 S4 A32])
            (const_int 5 [0x5]))
        (set (reg:SI 90 [ D.1884 ])
            (const_int 5 [0x5]))
    ])
Successfully matched this instruction:
(set (reg:SI 90 [ D.1884 ])
    (const_int 5 [0x5]))
Successfully matched this instruction:
(set (mem/c:SI (symbol_ref:DI ("b") [flags 0x2]  <var_decl 0x7f3aa8245cf0 b>)
[1 b+0 S4 A32])
    (const_int 5 [0x5]))
allowing combination of insns 28, 29 and 30
original costs 0 + 4 + 4 = 0
replacement costs 4 + 4 = 8
deferring deletion of insn with uid = 28.
deferring deletion of insn with uid = 27.
deferring deletion of insn with uid = 29.
modifying insn i3    30: [`b']=0x5
deferring rescan insn with uid = 30.

In the end it kept there only the b = 5; store, but not setting of pseudo 90 to
the same value, but pseudo 90 is used in the next basic block (to initialize
first argument to the function call).  Segher, can you please have a look?

Reply via email to