[Bug tree-optimization/68911] [6 Regression] wrong code at -Os and above on x86-64-linux-gnu (in 32- and 64-bit modes)

amker at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Dec 23 17:45:00 GMT 2015


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

--- Comment #4 from amker at gcc dot gnu.org ---
(In reply to Jakub Jelinek from comment #2)
> This goes wrong during vrp1.
> Analyzing # of iterations of loop 2
>   exit condition [e_6, + , 1] <= 93
>   bounds on difference of bases: -4294967202 ... 93
>   result:
>     zero if e_6 > 94
>     # of iterations 94 - e_6, bounded by 94
> looks wrong to me, e_6 as well as the additions and comparison are performed
> in unsigned type, therefore 94 - e_6 is I believe not bounded by 94.  The
> value ranges for e_6 clearly allow (and in the testcase are) some very large
> unsigned numbers, so 94 - e_6.  If assuming the value of f is arbitrary (it
> is not), then the possible values of e before entering the
> while (e < 94)
>   e++;
> loop are either 2, 94, 0xffffffffU or 0xfffffffeU (of course f is not
> arbitrary and as b and d are both 0, it will be actually 0xffffffffU each
> time.
> But from those 4 numbers the number of iterations would be bound by 96.

The immediate dump of loop before vrp1 is as below:

  <bb 8>:
  e_15 = e_1 + 1;

  <bb 13>:
  # e_1 = PHI <e_2(3), e_15(8), e_12(7)>
  if (e_1 <= 93)
    goto <bb 8>;
  else
    goto <bb 10>;

The loop niter analyzed before/after r224020 are both like below:
Analyzing # of iterations of loop 2
  exit condition [e_8, + , 1] <= 93
  bounds on difference of bases: -4294967202 ... 93
  result:
    zero if e_8 > 94
    # of iterations 94 - e_8, bounded by 94
Analyzing # of iterations of loop 2
  exit condition [e_8, + , 1] <= 93
  bounds on difference of bases: -4294967202 ... 93
  result:
    zero if e_8 > 94
    # of iterations 94 - e_8, bounded by 94

The only difference after patching is now we explicitly record {e_8, 1}_loop as
a no-wrap control_iv.

Seems to me the bound information is correct because that information must be
used when "zero if e_8 > 94" is satisfied, as commented in source code:

  tree may_be_zero;     /* The boolean expression.  If it evaluates to true,
                           the loop will exit in the first iteration (i.e.
                           its latch will not be executed), even if the niter
                           field says otherwise.  */
  tree niter;           /* The expression giving the number of iterations of
                           a loop (provided that assumptions == true and
                           may_be_zero == false), more precisely the number
                           of executions of the latch of the loop.  */

So no_overflow property of control_iv should also be used only when may_be_zero
is false. 

For now VRP tries to update range information using loop niter bound when the
control iv doesn't wrap/overflow, but I think that is not enough.  We can not
assume any information from loop if the loop exits immediately.

So, IMHO, we should only update value range with loop niter bound when
may_be_zero is false.  This will fix this issue and won't hurt other cases
because when the loop exits immediately, there is no useful loop niter bound
information anyway.


More information about the Gcc-bugs mailing list