Bug 97888 - [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu
Summary: [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P1 normal
Target Milestone: 11.0
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2020-11-18 09:49 UTC by Zhendong Su
Modified: 2020-11-18 21:57 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-11-18 00:00:00


Attachments
gcc11-pr97888.patch (1023 bytes, patch)
2020-11-18 10:33 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2020-11-18 09:49:03 UTC
[525] % 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/11.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --disable-bootstrap --prefix=/local/suz-local/software/local/gcc-trunk --enable-languages=c,c++ --disable-werror --enable-multilib --with-system-zlib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.0.0 20201118 (experimental) [master revision b03be74bad0:b7ec4b4b7a1:4b81528241ca682025d92558ff6aeec91dafdca8] (GCC) 
[526] % 
[526] % gcctk -O1 small.c; ./a.out
[527] % 
[527] % gcctk -Os small.c
[528] % ./a.out
Illegal instruction
[529] % 
[529] % cat small.c
int a = 1, b, c = 4, d, e;

int main() {
  int f = 2273363750;
  for (; b < 10; b++) {
    int g = f % (~0 && a) && g, h = 0, i = 0;
    if (c)
      h = f;
    if (h > -2021603546)
      e = d / i;
    f = h;
  }
  return 0;
}
Comment 1 Jakub Jelinek 2020-11-18 09:54:48 UTC
Started with r11-5111-g1e27e7a582a9b86bcf86f5c103cd947672746e97
Comment 2 Jakub Jelinek 2020-11-18 10:00:32 UTC
The comments in that commit look incorrect btw,
// if a & b >=0 , then a >= 0.
should have been
// if a % b >=0 , then a >= 0.
(ditto the other one).
Comment 3 Jakub Jelinek 2020-11-18 10:20:36 UTC
And I think the commit doesn't implement what Bruno wrote.
In particular, it was
b >= 0 && a % b > 0 implies a >= 0
b >= 0 && a % b < 0 implies a <= 0
while the patch implemented
b >= 0 && a % b >= 0 implies a >= 0
b >= 0 && a % b < 0 implies a <= 0

Consider -4 % 4, b >= 0 and a % b == 0, which is >= 0, but a is < 0.

So, another miscompiled testcase is:
__attribute__((noipa)) void
foo (int i)
{
  if ((i % 7) >= 0)
    {
      if (i >= 0)
        __builtin_abort ();
    }
}

int
main ()
{
  foo (-7);
  foo (-21);
  return 0;
}
Comment 4 Jakub Jelinek 2020-11-18 10:33:56 UTC
Created attachment 49585 [details]
gcc11-pr97888.patch

Untested fix.
Comment 5 Andrew Macleod 2020-11-18 13:35:37 UTC
Doh, yeah. Patch looks good.
Comment 6 GCC Commits 2020-11-18 21:17:39 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4

commit r11-5150-g71c9d2b088c9d409a1bd3b50523ac4623a5bf1b4
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Nov 18 22:13:06 2020 +0100

    vrp: Fix operator_trunc_mod::op1_range [PR97888]
    
    As mentioned in the PR, in (x % y) >= 0 && y >= 0, we can't deduce
    x's range to be x >= 0, as e.g. -7 % 7 is 0.  But we can deduce it
    from (x % y) > 0.  The patch also fixes up the comments.
    
    2020-11-18  Jakub Jelinek  <jakub@redhat.com>
    
            PR tree-optimization/91029
            PR tree-optimization/97888
            * range-op.cc (operator_trunc_mod::op1_range): Only set op1
            range to >= 0 if lhs is > 0, rather than >= 0.  Fix up comments.
    
            * gcc.dg/pr91029.c: Add comment with PR number.
            (f2): Use > 0 rather than >= 0.
            * gcc.c-torture/execute/pr97888-1.c: New test.
            * gcc.c-torture/execute/pr97888-2.c: New test.
Comment 7 Jakub Jelinek 2020-11-18 21:57:25 UTC
Fixed.