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

--- Comment #3 from Franz Sirl <sirl at gcc dot gnu.org> ---
I managed to minimize the testcase a bit more:

unsigned int gvar1;
void fun1(int);
void fun2(unsigned int, char *);
int fun2_maxlen;
typedef struct {
  int exist;
  int mode;
} table_t;
table_t gtable[20];

void fun3(unsigned int idx)
{
  char buffer[257];
  if (idx >= 20)
    return;
  fun2(idx, buffer);
  if (gtable[idx].mode)
    fun2(idx, buffer);
}

void fun4()
{
  unsigned int idx = gvar1;
  fun3(idx);
}

void fun2(unsigned int idx, char * text)
{
  if (!(idx >= 20 || gtable[idx].exist == 0))
    fun1(fun2_maxlen);
}

and this is the resulting code modeled after the 085i.inline dump:

unsigned int gvar1;
void fun1(unsigned int);
int fun2_maxlen;
typedef struct {
  int exist;
  int mode;
} table_t;
table_t gtable[20];

__attribute__((noinline))
static void fun3_part_0(unsigned int idx)
{
  if (idx >= 20)
    goto lab1;
  if (gtable[idx].exist != 0)
    fun1(fun2_maxlen);
lab1:
  if (gtable[idx].mode != 0) {
    if (idx >= 20)
      return;
    if (gtable[idx].exist != 0)
      fun1(fun2_maxlen);
  }
}

void fun3(unsigned int idx)
{
  if (idx >= 20)
    return;
  fun3_part_0(idx);
}

void fun4()
{
  unsigned int idx = gvar1;
  if (idx >= 20)
    return;
  fun3_part_0(idx);
}

And so I wonder why the duplicated "if (idx >= 20) return" wasn't moved to
fun3.part.0?
If the reason is conflicting optimization goals, could something like an
"incoming range" be attached to the parameter of fun3.part.0? That would
probably help both the warning code and the following optimization passes.

BTW, is there a way to dump more details between 084i.fnsummary and
085i.inline?

Reply via email to