This is the mail archive of the gcc-patches@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]

Re: [PATCH] avoid calling memset et al. with excessively large sizes (PR 79095)


On 01/20/2017 04:34 PM, Jakub Jelinek wrote:
On Fri, Jan 20, 2017 at 04:32:19PM -0700, Jeff Law wrote:
then the loop does the same thing as will memset (p, 6, 3U * 1024 * 1024 * 1024);
do.  On such large objects some operations may not work properly, e.g.
&p[i] - &p[0] might be negative etc., but that is not something the above
loop does or memset will do internally.  If the loop doesn't use just 3/4 of
the address space, but much more, e.g. more than whole address space minus
one page, which is what happens in the testcase, it is indeed quite sure it
will crash if invoked, but the problem with the warning is the same with
many other late warnings or warnings excessively using VRP etc.
Not in my mind, it's different.  It's not triggered by path isolation. It's
standard const propagation + simplification.

So where does the constant -1 length appear there?  The test clearly just
attempts to clear some variable length - 1.  I admit I haven't looked at the
dumps in detail, I should...
At least in Martin's simplified test it's just a series of standard constant propagations and obvious simplifications. No threading, no path isolation.

;;   basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;;    prev block 0, next block 3, flags: (NEW, REACHABLE, VISITED)
;;    pred:       ENTRY [100.0%]  (FALLTHRU,EXECUTABLE)
  _7 = MEM[(int * *)s_5(D)];
  _8 = MEM[(int * *)s_5(D) + 8B];
  _9 = (long int) _8;
  _10 = (long int) _7;
  _11 = _9 - _10;
  _12 = _11 /[ex] 4;
  _13 = (long unsigned int) _12;
  _1 = _13 + 18446744073709551614;
  if (_1 <= 2)
    goto <bb 3>; [36.64%]
  else
    goto <bb 8>; [63.36%]
;;    succ:       3 [36.6%]  (TRUE_VALUE,EXECUTABLE)
;;                8 [63.4%]  (FALSE_VALUE,EXECUTABLE)

;;   basic block 3, loop depth 0, count 0, freq 3664, maybe hot
;;    prev block 2, next block 4, flags: (NEW, REACHABLE, VISITED)
;;    pred:       2 [36.6%]  (TRUE_VALUE,EXECUTABLE)
  _2 = _13 + 18446744073709551615;
  _14 = MEM[(int * *)s_5(D)];
  _15 = MEM[(int * *)s_5(D) + 8B];
  _16 = (long int) _15;
  _17 = (long int) _14;
  _18 = _16 - _17;
  _19 = _18 /[ex] 4;
  _20 = (long unsigned int) _19;
  if (_2 > _20)
    goto <bb 4>; [50.00%]
  else
    goto <bb 6>; [50.00%]
;;    succ:       4 [50.0%]  (TRUE_VALUE,EXECUTABLE)
;;                6 [50.0%]  (FALSE_VALUE,EXECUTABLE)

;;   basic block 4, loop depth 0, count 0, freq 1832, maybe hot
;;    prev block 3, next block 5, flags: (NEW, REACHABLE, VISITED)
;;    pred:       3 [50.0%]  (TRUE_VALUE,EXECUTABLE)
  _21 = _2 - _20;
  _22 = MEM[(int * *)s_5(D) + 16B];
  _23 = (long int) _22;
  _24 = _23 - _16;
  _25 = _24 /[ex] 4;
  left_26 = (size_t) _25;
  if (_21 <= left_26)
    goto <bb 5>; [33.00%]
  else
    goto <bb 8>; [67.00%]
;;    succ:       5 [33.0%]  (TRUE_VALUE,EXECUTABLE)
;;                8 [67.0%]  (FALSE_VALUE,EXECUTABLE)

;;   basic block 5, loop depth 0, count 0, freq 605, maybe hot
;;    prev block 4, next block 6, flags: (NEW, REACHABLE, VISITED)
;;    pred:       4 [33.0%]  (TRUE_VALUE,EXECUTABLE)
  _27 = _21 * 4;
  __builtin_memset (_22, 0, _27);
  goto <bb 8>; [100.00%]
;;    succ:       8 [100.0%]  (FALLTHRU,EXECUTABLE)


In particular look at _27, which is _21 * 4.

_21 is _2 - _20

If you follow things though the use-def chains and simplify you'll see that _2 - 20 is always -1.


Jeff


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