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

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
For some reason we think that the .UBSAN_NULL call doesn't clobber the load
from nullptr:

   <bb 2> [local count: 118111600]:
+  # VUSE <.MEM_3(D)>
+  pretmp_7 = MEM[(int *)0B];

   <bb 3> [local count: 1073741824]:
-  # .MEM_2 = PHI <.MEM_3(D)(2), .MEM_6(5)>
+  # .MEM_2 = PHI <.MEM_3(D)(2), .MEM_6(3)>
   # .MEM_4 = VDEF <.MEM_2>
   a = 0B;
   # .MEM_6 = VDEF <.MEM_4>
   # USE = nonlocal escaped 
   # CLB = nonlocal escaped 
   .UBSAN_NULL (0B, 0B, 4);
-  # VUSE <.MEM_6>
-  _1 = MEM[(int *)0B];
-  if (_1 != 0)
+  if (pretmp_7 != 0)

that's because

DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, ". R . ")

and thus .UBSAN_NULL only _reads_ from the first argument passed (but also
possibly constant NULL(?) valued operands are considered special).  The
same happens at -O2 btw.  At -O1 we eliminate the load.

Ah, and call_may_clobber_ref_p_1 has

  if (gimple_call_internal_p (call))
    switch (auto fn = gimple_call_internal_fn (call))
      {
        /* Treat these internal calls like ECF_PURE for aliasing,
           they don't write to any memory the program should care about.
           They have important other side-effects, and read memory,
           so can't be ECF_NOVOPS.  */
      case IFN_UBSAN_NULL:
      case IFN_UBSAN_BOUNDS:
      case IFN_UBSAN_VPTR:
      case IFN_UBSAN_OBJECT_SIZE:
      case IFN_UBSAN_PTR:
      case IFN_ASAN_CHECK:
        return false;

so they are not a barrier for the motion of loads which is what happens
here.

Note that only at -O3 we keep the trapping load because we fail to eliminate
the conditional there and have

  <bb 2> [local count: 118111600]:
  # VUSE <.MEM_3(D)>
  pretmp_7 = MEM[(int *)0B];
  if (pretmp_7 != 0)
    goto <bb 4>; [11.00%]
  else
    goto <bb 3>; [89.00%]

  <bb 3> [local count: 955630224]:
  # .MEM_1 = PHI <.MEM_3(D)(2)>
  # .MEM_8 = VDEF <.MEM_1>
  a = 0B;
  # .MEM_11 = VDEF <.MEM_8>
  # USE = anything
  # CLB = anything
  __builtin___ubsan_handle_type_mismatch_v1_abort (&*.Lubsan_data0, 0);

  <bb 4> [local count: 118111600]:
  # .MEM_4 = VDEF <.MEM_3(D)>
  a = 0B;
  # .MEM_10 = VDEF <.MEM_4>
  # USE = anything
  # CLB = anything
  __builtin___ubsan_handle_type_mismatch_v1_abort (&*.Lubsan_data1, 0);

in the end.

Reply via email to