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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Before the rev. DOM2 removes the call to  __warn_memset_zero_len while with
the change the condition guarding the call changes like this:

   <bb 3> [local count: 1073741824]:
   _4 = MEM[(unsigned int *)this_2(D) + 12B];
-  # RANGE [0, 4294967295] NONZERO 4294967295
-  _6 = (long unsigned int) _4;
-  _7 = __builtin_constant_p (_6);
-  _11 = _6 == 0;
-  _12 = _7 != 0;
-  _13 = _11 & _12;
-  if (_13 != 0)
+  if (_4 == 0)
     goto <bb 4>; [100.00%]
   else
     goto <bb 5>; [0.00%]

  <bb 4> [local count: 1073741824]:
  # USE = nonlocal
  # CLB = nonlocal
  __warn_memset_zero_len ();

  <bb 5> [count: 0]:
  __builtin_unreachable ();

and the first change caused by the rev. is

--- a/pr34850.C.025t.einline    2019-06-27 10:53:11.462941555 +0200
+++ b/pr34850.C.025t.einline    2019-06-27 10:52:27.146152524 +0200
@@ -71,6 +71,7 @@

   <bb 2> :
   _1 = (long unsigned int) n_2(D);
+  # RANGE ~[0, 0]
   _6 = __builtin_constant_p (_1);
   if (_6 != 0)
     goto <bb 3>; [100.00%]
   else
     goto <bb 5>; [0.00%]

   <bb 5> [count: 0]:
   __builtin_unreachable ();

which causes the __builtin_constant_p call to be eliminated way earlier
which IMHO is reasonable in principle but it breaks the

    void * memset (void *__dest, int __ch, size_t __len) throw () {
        if (__builtin_constant_p (__len) && __len == 0)
            __warn_memset_zero_len ();
    }

intent.  Of course the testcase is simply reduced too much here and
the C++ FE puts the unreachable() in because of the missing return.

Reply via email to