https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79095
--- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to Jeffrey A. Law from comment #4) > So the simplified tests are interesting, but ultimately too simplified. You're right, the test case in comment #2 is oversimplified. The one in the thread on gcc-patches should be closer (it includes the ADD_OVERFLOW): $ cat t.C && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.C typedef __SIZE_TYPE__ size_t; struct S { int *p0, *p1, *p2; size_t size () const { return p1 - p0; } void f (size_t n) { if (n > size ()) // can't happen because foo (n - size ()); // n is in [1, MIN(size() - 1, 3)] else if (n < size ()) bar (p0 + n); } void foo (size_t n) { size_t left = (size_t)(p2 - p1); if (left >= n) __builtin_memset (p2, 0, n * sizeof *p2); } void bar (int*); }; void f (S &s) { size_t n = s.size (); if (n > 1 && n < 5) s.f (n - 1); } ;; Function void f(S&) (_Z1fR1S, funcdef_no=3, decl_uid=2296, cgraph_uid=3, symbol_order=3) Removing basic block 9 Removing basic block 10 Removing basic block 11 void f(S&) (struct S & s) { long unsigned int _1; long unsigned int _2; int * _7; int * _8; long int _9; long int _10; long int _11; long int _12; long unsigned int _13; long unsigned int _17; int * _22; long int _23; long int _24; __complex__ long unsigned int _25; long unsigned int _28; int * _29; <bb 2> [100.00%]: _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%] <bb 3> [36.64%]: _25 = ADD_OVERFLOW (_13, 18446744073709551615); _2 = REALPART_EXPR <_25>; _17 = IMAGPART_EXPR <_25>; if (_2 > _13) goto <bb 4>; [50.00%] else goto <bb 6>; [50.00%] <bb 4> [18.32%]: _22 = MEM[(int * *)s_5(D) + 16B]; _23 = (long int) _22; _24 = _23 - _9; if (_24 == -4) goto <bb 5>; [33.00%] else goto <bb 8>; [67.00%] <bb 5> [6.05%]: __builtin_memset (_22, 0, 18446744073709551612); [tail call] goto <bb 8>; [100.00%] <bb 6> [18.32%]: if (_17 != 0) goto <bb 7>; [36.64%] else goto <bb 8>; [63.36%] <bb 7> [6.71%]: _28 = _2 * 4; _29 = _7 + _28; S::bar (s_5(D), _29); [tail call] <bb 8> [100.00%]: return; } In function ‘void S::foo(size_t)’, inlined from ‘void S::f(size_t)’ at t.C:10:24, inlined from ‘void f(S&)’ at t.C:29:16: t.C:19:47: warning: ‘void* __builtin_memset(void*, int, long unsigned int)’: specified size 18446744073709551612 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=] __builtin_memset (p2, 0, n * sizeof *p2); ^