https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66163
Jan Hubicka <hubicka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com --- Comment #5 from Jan Hubicka <hubicka at gcc dot gnu.org> --- Hmm, interesting. I tried a testcase: $ more t.C struct test {int a; int foo (int &b);}; int test2 (test *t, int *q) { if (t && q) return t->a+*q; else return 1; } int test::foo(int &b) { return test2(this,&b); } compiled with -O3 -fsanitize=null. I would expect test2 to have no sanitizer checks (since it returns 1 at NULL) and test to have them. Curiously enough test2 gets compiled as: int test2(test*, int*) (struct test * t, int * q) { int _1; bool _3; bool _5; bool _6; int _8; int _9; int _10; <bb 2>: _3 = t_2(D) != 0B; _5 = q_4(D) != 0B; _6 = _3 & _5; if (_6 != 0) goto <bb 3>; else goto <bb 8>; <bb 3>: if (t_2(D) == 0B) goto <bb 4>; else goto <bb 5>; <bb 4>: __builtin___ubsan_handle_type_mismatch (&*.Lubsan_data0, 0); <bb 5>: _8 = t_2(D)->a; if (q_4(D) == 0B) goto <bb 6>; else goto <bb 7>; <bb 6>: __builtin___ubsan_handle_type_mismatch (&*.Lubsan_data1, 0); <bb 7>: _9 = *q_4(D); _10 = _8 + _9; <bb 8>: # _1 = PHI <_10(7), 1(2)> return _1; } Why we do not simplify the checks here? _3 = t_2(D) != 0B; _5 = q_4(D) != 0B; _6 = _3 & _5; if (_6 != 0) goto <bb 3>; else goto <bb 8>; <bb 3>: if (t_2(D) == 0B) goto <bb 4>; else goto <bb 5>; this is certainly jump-threadable. I am adding Jeff for this. simplified testcase: struct test {int a; int foo (int &b);}; int test2 (test *t, int *q) { if (t) return t->a; else return 1; } int test::foo(int &b) { return test2(this,&b); } gets compiled as: int test2(test*, int*) (struct test * t, int * q) { int _1; int _4; <bb 2>: if (t_2(D) != 0B) goto <bb 3>; else goto <bb 6>; <bb 3>: if (t_2(D) == 0B) goto <bb 4>; else goto <bb 5>; <bb 4>: __builtin___ubsan_handle_type_mismatch (&*.Lubsan_data0, 0); <bb 5>: _4 = t_2(D)->a; <bb 6>: # _1 = PHI <_4(5), 1(2)> return _1; } so still no jump threading, but RTL gets it: _Z5test2P4testPi: .LFB0: .cfi_startproc testq %rdi, %rdi movl $1, %eax je .L2 movl (%rdi), %eax .L2: however test:foo is also compiled as: _ZN4test3fooERi: .LFB1: .cfi_startproc testq %rdi, %rdi movl $1, %eax je .L8 movl (%rdi), %eax .L8: rep ret whic is wrong, it should complain about undefined behaviour for NULL this.