Bug 107273 - wrong code at -O3 on x86_64-linux-gnu by r13-3281
Summary: wrong code at -O3 on x86_64-linux-gnu by r13-3281
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 107269 (view as bug list)
Depends on:
Blocks:
 
Reported: 2022-10-15 20:53 UTC by Zhendong Su
Modified: 2022-10-18 01:05 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-10-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2022-10-15 20:53:04 UTC
It appears to be a recent regression.

Compiler Explorer: https://godbolt.org/z/Mo8sPhYW7


[538] % 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.0/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.0 20221015 (experimental) [master r13-3311-gbaeec7cc83b] (GCC) 
[539] % 
[539] % gcctk -O2 small.c; ./a.out
[540] % 
[540] % gcctk -O3 small.c
[541] % ./a.out
Segmentation fault
[542] % 
[542] % cat small.c
int printf(const char *, ...);
int a[1] = {1};
short b, c = 5500;
int d;
long e;
char f = 1;
int main() {
  while (1) {
    long g = b < 1;
    e = g;
    break;
  }
  for (; f; f--) {
    if (e) {
      d = -(6L | -(c & 1000));
    }
    char h = d;
    if (b)
      b = 0;
    if (d < 200)
      while (1)
        printf("%d", a[c]);
    short i = h * 210;
    c = i;
  }
  return 0;
}
Comment 1 Zhendong Su 2022-10-15 20:57:22 UTC
Likely a related instance (although it fails also at -Os and -O2 besides -O3).

Compiler Explorer: https://godbolt.org/z/rdajs47K6

[515] % 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.0/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.0 20221015 (experimental) [master r13-3311-gbaeec7cc83b] (GCC)
[516] %
[516] % gcctk -O1 small.c; ./a.out
[517] %
[517] % gcctk -Os small.c
[518] % ./a.out
Illegal instruction
[519] %
[519] % cat small.c
int a, d, f;
char b, g;
unsigned i;
int main() {
  int c = 300, h = 40;
  char e = 1;
  for (; a < 1; a++) {
    c = ~((i - ~c) | e);
  L1:
    e = f = c;
    if (c)
      if (c > -200)
        e = g % (1 << h);
    char k = 0;
  L2:;
  }
  if (b) {
    if (d)
      goto L2;
    if (!b)
      goto L1;
  }
  return 0;
}
Comment 2 Zhendong Su 2022-10-15 21:00:31 UTC
Another likely related instance that is miscompiled at -O1 and above.

Compiler Explorer: https://godbolt.org/z/xqz7f4c7v

[570] % 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.0/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.0 20221015 (experimental) [master r13-3311-gbaeec7cc83b] (GCC) 
[571] % 
[571] % gcctk -O0 small.c; ./a.out
[572] % 
[572] % gcctk -O1 small.c
[573] % timeout -s 9 5 ./a.out
Killed
[574] % cat small.c
int a = 1, b, c;
int main() {
  unsigned d = 1;
  char e = 1, f = 150;
  if (f > 0)
    goto L2;
 L1:
  d = -(d << a || f);
  if (a)
  L2:
    f = ~e;
  char i = 1 ^ d;
  if (b) {
    e = d | c;
    goto L2;
  }
  if (a < 1)
    goto L1;
  while (!d)
    ;
  return 0;
}
Comment 3 Zhendong Su 2022-10-15 21:04:53 UTC
Another likely related instance that is miscompiled at -Os, -O2 and -O3.

Compiler Explorer: https://godbolt.org/z/3TbG51Ph3

[628] % 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.0/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.0 20221015 (experimental) [master r13-3311-gbaeec7cc83b] (GCC) 
[629] % 
[629] % gcctk -O1 small.c; ./a.out
[630] % 
[630] % gcctk -Os small.c
[631] % timeout -s 9 5 ./a.out
Killed
[632] % 
[632] % cat small.c
struct a {
  int b;
};
int c;
int main() {
  struct a d = {0};
  int e;
  short f = 1;
  for (; c < 1; c++) {
    if (d.b < 1)
      e = -~(f ^ 500000000L ^ -1);
    f = e;
    while (e > -100000)
      ;
  }
  return 0;
}
Comment 4 Hongtao.liu 2022-10-17 03:21:45 UTC
Looks like the same issue as PR107172 since below change can also pass all the testcase in the PR.

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 8e847520491..be815341af5 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -21335,7 +21335,7 @@ (define_insn "*x86_mov<mode>cc_0_m1_neg"
 (define_expand "x86_mov<mode>cc_0_m1_neg"
   [(parallel
     [(set (match_operand:SWI48 0 "register_operand")
-         (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
+         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
      (clobber (reg:CC FLAGS_REG))])])

 (define_split
Comment 5 Richard Biener 2022-10-17 07:55:55 UTC
dup then

*** This bug has been marked as a duplicate of bug 107172 ***
Comment 6 H.J. Lu 2022-10-17 16:12:35 UTC
(In reply to Hongtao.liu from comment #4)
> Looks like the same issue as PR107172 since below change can also pass all
> the testcase in the PR.
> 
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 8e847520491..be815341af5 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -21335,7 +21335,7 @@ (define_insn "*x86_mov<mode>cc_0_m1_neg"
>  (define_expand "x86_mov<mode>cc_0_m1_neg"
>    [(parallel
>      [(set (match_operand:SWI48 0 "register_operand")
> -         (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
> +         (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
>       (clobber (reg:CC FLAGS_REG))])])
> 
>  (define_split

This doesn't fix the -O3 issue in the first testcase nor the second testcase.
Comment 7 H.J. Lu 2022-10-17 19:07:31 UTC
*** Bug 107269 has been marked as a duplicate of this bug. ***
Comment 8 H.J. Lu 2022-10-17 20:42:40 UTC
-O2 -funswitch-loops also triggers this bug.
Comment 9 Andrew Macleod 2022-10-17 21:03:35 UTC
Working on it.

Looks like an 8 bit value somehow got considered as a 32 bit partial equivalence.

  _8 = -_7;
  _9 = (int) _8;
  h_30 = (char) _9;

<..>

h_30 is an 8 bit slice of _9, yet :

This is ok:
Checking Partial equiv ( pe32 ) _8
CACHE: BB 11 DOM query for _8, found [irange] unsigned int [1, +INF] NONZERO 0xfffffffa at BB10
CACHE: Range for DOM returns : [irange] unsigned int [1, +INF] NONZERO 0xfffffffa

but this is not:

Checking Partial equiv ( pe32 ) h_30
CACHE: BB 11 DOM query for h_30, found [irange] char VARYING at BB10
CACHE: Range for DOM returns : [irange] char VARYING
Partial equiv update! :  h_30 has range  :  [irange] int [-128, 127] refining range to :[irange] int [-128, -1][1, 127] NONZERO 0xfffffffa

That changed the value of _9 in an incorrect way. h_30 is a char, that should be pe8, and as that is smaller than the 32 bits in _9, that value should have been rejected. 

THis is occurring during the path_ranger used by threading, still working on figuring where the root issue lies.
Comment 10 GCC Commits 2022-10-18 01:05:04 UTC
The master branch has been updated by Andrew Macleod <amacleod@gcc.gnu.org>:

https://gcc.gnu.org/g:0205fbb91be022055c632973caa95e398b33db39

commit r13-3350-g0205fbb91be022055c632973caa95e398b33db39
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Mon Oct 17 19:00:49 2022 -0400

    Merge partial relation precisions properly
    
    When merging 2 groups of PE's, one group was simply being set to the
    other instead of properly merging them.
    
            PR tree-optimization/107273
            gcc/
            * value-relation.cc (equiv_oracle::add_partial_equiv): Merge
            instead of copying precison of each member.
    
            gcc/testsuite/
            * gcc.dg/tree-ssa/pr107273-1.c: New.
            * gcc.dg/tree-ssa/pr107273-2.c: New.
Comment 11 Andrew Macleod 2022-10-18 01:05:48 UTC
fixed.