This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto


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

--- Comment #22 from Martin Sebor <msebor at gcc dot gnu.org> ---
In areas where the authors of the proposal find the standard open to
interpretation and when they feel it doesn't contradict the surveyed
implementation practice they tend to suggest to tighten the requirements on
implementations (I think they surveyed mainly Clang and GCC) to make code valid
that may be questionable today.  Their implementation survey isn't
comprehensive and so in some cases they may be suggesting changes that would
invalidate some optimizations.  It's not entirely clear to me that this is one
such case -- they may only be thinking of allocated storage and not auto/static
objects as suggested in 2.3.3 Q9b in N2263.

WG14 takes a different view from the authors: where we agree that the standard
is unclear we would like to tighten the requirements on programs to allow
better analysis, better optimization, and better detection of bugs.  WG14 has
formed a study group to try to come up with the next revision of the proposal
that's closer to WG14's goal.

With respect to objects and their subobjects, the existing requirements are
sufficiently clear and existing practice shows that compilers have been relying
on those requirements for some time (GCC well over a decade).  For example:

struct S { char a[4], b[4]; };

void f (struct S *p, int i)
{
  if (i < 4) i = 4;
  char b = p->b[0];
  p->a[i] = 0;            // assumed not to change p->b (undefined otherwise)
  if (p->b[0] != b)       // folded to false
    __builtin_abort ();   // eliminated
}
In function ‘f’:
warning: array subscript 4 is above array bounds of ‘char[4]’ [-Warray-bounds]
   p->a[i] = 0;            // assumed not to change p->b (undefined if it did)
   ~~~~^~~

;; Function f (f, funcdef_no=0, decl_uid=1960, cgraph_uid=0, symbol_order=0)

f (struct S * p, int i)
{
  <bb 2> [local count: 1073741825]:
  i_6 = MAX_EXPR <i_2(D), 4>;
  p_4(D)->a[i_6] = 0;
  return;

}

Besides GCC, Intel ICC also performs the same optimization.

The test cases in this report are variations on this theme.  The only
difference is that they use built-in functions to access the elements of the
distinct subobjects rather than accessing them directly.  GCC has just extended
the optimization above to a subset of calls of built-in functions.  Besides
strlen(), here's another example from GCC 7:

struct S { char a[4], b[4]; };

void f (struct S *p, int i)
{
  int n = __builtin_snprintf (0, 0, "%s", p->a);   // n must be between 0 and 3
  if (n > 3)                                       // folded to false
    __builtin_abort ();                            // eliminated
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]