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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Looks like a bug in the sanopt pass.
For -O2, we have before sanopt in main:
  b.0_1 = b;
  e.2_3 = e;
  c.5_4 = c;
  .ASAN_CHECK (7, c.5_4, 8, 8);
  *c.5_4 = e.2_3;
  b.7_5 = b;
  .ASAN_CHECK (7, b.7_5, 4, 4);
  *b.7_5 = 2;
  .ASAN_CHECK (7, b.0_1, 4, 4);
  *b.0_1 = 2;
  return 2;
and in sanopt:
Leaving: .ASAN_CHECK (7, c.5_4, 8, 8);
Leaving: .ASAN_CHECK (7, b.7_5, 4, 4);
Optimizing out: .ASAN_CHECK (7, b.0_1, 4, 4);
Expanded: .ASAN_CHECK (7, c.5_4, 8, 8);
Expanded: .ASAN_CHECK (7, b.7_5, 4, 4);
Even that is incorrect, we don't generally know what b points to before the *c
store and after it, so neither of the stores is redundant because *c store can
change the value of b.
At -O1 we have before sanopt:
  b.0_1 = b;
  e.2_6 = e;
  e.3_7 = (long int) e.2_6;
  _9 = (int) e.3_7;
  .ASAN_CHECK (7, b.0_1, 4, 4);
  *b.0_1 = _9;
  c.5_10 = c;
  e.6_11 = e;
  .ASAN_CHECK (7, c.5_10, 8, 8);
  *c.5_10 = e.6_11;
  b.7_12 = b;
  .ASAN_CHECK (7, b.7_12, 4, 4);
  *b.7_12 = 2;
  *b.0_1 = 2;
  b.1_2 = b;
  .ASAN_CHECK (6, b.1_2, 4, 4);
  _5 = *b.1_2;
  return _5;
because we optimize less at that optimization level, and sanopt:
Leaving: .ASAN_CHECK (7, b.0_1, 4, 4);
Leaving: .ASAN_CHECK (7, c.5_10, 8, 8);
Optimizing out: .ASAN_CHECK (7, b.7_12, 4, 4);
Optimizing out: .ASAN_CHECK (6, b.1_2, 4, 4);
Expanded: .ASAN_CHECK (7, b.0_1, 4, 4);
Expanded: .ASAN_CHECK (7, c.5_10, 8, 8);
The b.1_2 .ASAN_CHECK is IMHO redundant (b couldn't change between b.7_12 = b
and b.1_2 = b;) but the b.7_12 .ASAN_CHECK is not redundant.

Reply via email to