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.