Bug 109138 - [10/11/12/13 Regression] wrong code at -O1 and above on x86_64-linux-gnu
Summary: [10/11/12/13 Regression] wrong code at -O1 and above on x86_64-linux-gnu
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P2 normal
Target Milestone: 10.5
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2023-03-15 05:20 UTC by Zhendong Su
Modified: 2023-03-15 10:54 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-03-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2023-03-15 05:20:32 UTC
This appears to be long latent, affecting at least 5.* and later. 

Compiler Explorer: https://godbolt.org/z/9rb354E51

[592] % gcctk -v
Using built-in specs.
COLLECT_GCC=gcctk
COLLECT_LTO_WRAPPER=/local/suz-local/software/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/13.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --disable-bootstrap --enable-checking=yes --prefix=/local/suz-local/software/local/gcc-trunk --enable-sanitizers --enable-languages=c,c++ --disable-werror --enable-multilib --with-system-zlib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.0.1 20230315 (experimental) [master r13-6679-gfd42a8fa4b7] (GCC) 
[593] % 
[593] % gcctk -O0 small.c; ./a.out
[594] % 
[594] % gcctk -O1 small.c
[595] % timeout -s 9 5 ./a.out
Killed
[596] % 
[596] % cat small.c
unsigned a = -1;
int main() {
  int b = 0;
  for (; b < 2; b++) {
  L:;
    int d;
    while (a <= 0)
      if (*&d)
        break;
    d = 1;
    a++;
  }
  return 0;
}
Comment 1 Andrew Pinski 2023-03-15 06:07:38 UTC
reassoc1 introduces the unconditional use of an unitialized variable.

From:
  <bb 3> [local count: 1014686025]:
  if (d_5(D) != 0)
    goto <bb 5>; [5.50%]
  else
    goto <bb 4>; [94.50%]

  <bb 4> [local count: 1073741824]:
  a.1_1 = a;
  if (a.1_1 == 0)
    goto <bb 3>; [94.50%]
  else
    goto <bb 5>; [5.50%]

To:

  a.1_1 = a;
  _12 = (unsigned int) d_5(D);
  _4 = _12 | a.1_1;
  _3 = _4 == 0;
  if (_3 != 0)
    goto <bb 3>; [94.50%]
  else
    goto <bb 4>; [5.50%]
Comment 2 Richard Biener 2023-03-15 08:40:59 UTC
So similar to PR107833, the solution might be similar as well.
Comment 3 Andrew Pinski 2023-03-15 08:51:00 UTC
(In reply to Richard Biener from comment #2)
> So similar to PR107833, the solution might be similar as well.

Actually it is closer related to PR 68083 .
Comment 4 Jakub Jelinek 2023-03-15 09:26:13 UTC
Started with r5-4606-g956623c1378de3c48e77b
Comment 5 Jakub Jelinek 2023-03-15 09:39:59 UTC
I don't think this has anything to do with reassoc though.
The testcase looks incorrect to me.
Because d is defined in the scope of the outer loop's body, for b == 0 a is -1U and
so the inner loop does nothing, d is set to 1, a is set to 0 and then d goes out of scope.
Then for b = 1, a scope with d variable is entered but the variable is again uninitialized, a <= 0 is true, and we use the uninitialized variable.
fixup_cfg1 dump shows this nicely with the clobber in there:

  <bb 2> :
  b = 0;
  goto <bb 6>; [INV]

  <bb 3> :
  d.0_1 = d;
  if (d.0_1 != 0)
    goto <bb 5>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 4> :
L:
  a.1_2 = a;
  if (a.1_2 == 0)
    goto <bb 3>; [INV]
  else
    goto <bb 5>; [INV]

  <bb 5> :
  d = 1;
  a.2_3 = a;
  _4 = a.2_3 + 1;
  a = _4;
  d = {CLOBBER(eol)};
  b = b + 1;

  <bb 6> :
  if (b <= 1)
    goto <bb 4>; [INV]
  else
    goto <bb 7>; [INV]

  <bb 7> :
  D.2753 = 0;
  return D.2753;
Comment 6 Zhendong Su 2023-03-15 10:54:47 UTC
Oh, good catch, Jakub! And sorry for the noise.