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.

Reply via email to