[Bug tree-optimization/107986] [12/13 Regression] Bogus -Warray-bounds diagnostic with std::sort

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Dec 6 07:43:32 GMT 2022


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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |85316
                 CC|                            |aldyh at gcc dot gnu.org
           Keywords|                            |missed-optimization

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
One of the reasons we diagnose this is that we fail to compute a range
for 'qa_7'.  Before the VRP pass that diagnoses the -Warray-bounds violation we
have

  <bb 6> [local count: 1073741824]:
  # qa_7 = PHI <0(2), qa_6(5)>
  # RANGE [irange] int [0, 3] NONZERO 0x3
  # i_8 = PHI <0(2), i_16(5)>
  if (i_8 != 3)
    goto <bb 3>; [75.00%]
  else
    goto <bb 7>; [25.00%]

  <bb 7> [local count: 268435456]:
  # RANGE [irange] long unsigned int [0, 2147483647][18446744071562067968,
+INF]
  _3 = (long unsigned int) qa_7;
  # RANGE [irange] long unsigned int [0, 8589934588][18446744065119617024,
18446744073709551612] NONZERO 0xfffffffffffffffc
  _4 = _3 * 4;
  # PT = { D.18799 } (escaped)
  # ALIGN = 4, MISALIGN = 0
  _5 = &a + _4;
  if (&a != _5)
    goto <bb 8>; [53.47%]
  else
    goto <bb 17>; [46.53%]

  <bb 8> [local count: 143532440]:
  _11 = (signed long) _4;
  # RANGE [irange] long int [-2305843009213693952, 2305843009213693951]
  _20 = _11 /[ex] 4;
  # RANGE [irange] long unsigned int [0,
2305843009213693951][16140901064495857664, +INF]
  __n.3_21 = (long unsigned int) _20;
  # RANGE [irange] int [0, 63] NONZERO 0x3f
  _22 = __builtin_clzl (__n.3_21);
  # RANGE [irange] int [0, 63] NONZERO 0x3f
  _23 = 63 - _22;
  # RANGE [irange] long int [0, 63] NONZERO 0x3f
  _24 = (long int) _23;
  # RANGE [irange] long int [0, 126] NONZERO 0x7e
  _25 = _24 * 2;
  # USE = nonlocal escaped null { D.18799 } (escaped)
  # CLB = nonlocal escaped null { D.18799 } (escaped)
  std::__introsort_loop.isra (&a, _5, _25);
  if (_11 > 64)
    goto <bb 9>; [50.00%]
  else
    goto <bb 15>; [50.00%]

and we fail to eliminate this last conditional.  We also fail to
eliminate the (long)(((unsigned long)qa_37) * 4) /[ex] 4 round-trip
(because of possible overflow).

So even proving qa_7 is [0, +INF] would help a bit (not the diagnostic),
realizing qa_7 is [0, 3] like i_8 would be even better.  A testcase
for this could look like

void bar ();
void foo (int *a)
{
  int qa = 0;
  for (int i = 0; i < 3; i++)
    if (a[i])
      a[qa++] = 0;
  if (qa > 3)
    bar ();
}

where we should be able to eliminate the call to bar ().


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85316
[Bug 85316] [meta-bug] VRP range propagation missed cases


More information about the Gcc-bugs mailing list