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

--- Comment #15 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 45789
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45789&action=edit
gcc9-pr70341.patch

Untested fix for e.g.:
#define A(N) void foo##N (int);
#define B(N) A(N##0) A(N##1) A(N##2) A(N##3)
#define C(N) B(N##0) B(N##1) B(N##2) B(N##3)
#define D C(1) C(2)
D

struct E { int a, b, c, d; };
struct F { struct E e[1]; };

void
test (struct F *x, int y)
{
  struct E *p = &x->e[y];
#undef A
#define A(N) case N: foo##N (p->c); break;
  switch (p->b)
    {
    D
    default: __builtin_unreachable ();
    }
}

at -O2 on both arm and aarch64 - by making sure the casesi MEM load is mem/u/c
try_head_merge_bb is willing to move over the loads across the casesi.

Reply via email to