Bug 78725 - [7 Regression] wrong code at -O3 on x86_64-linux-gnu (in both 32-bit and 64-bit modes)
Summary: [7 Regression] wrong code at -O3 on x86_64-linux-gnu (in both 32-bit and 64-b...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 7.0
: P1 normal
Target Milestone: 7.0
Assignee: Michael Matz
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2016-12-07 22:39 UTC by Zhendong Su
Modified: 2016-12-13 14:50 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-12-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2016-12-07 22:39:59 UTC
$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.0 20161206 (experimental) [trunk revision 243299] (GCC) 
$ 
$ gcc-trunk -O2 small.c; ./a.out
1
$ gcc-6.2 -O3 small.c; ./a.out
1
$ 
$ gcc-trunk -O3 small.c; ./a.out
0
$ 


----------------------------------------------


int printf (const char *, ...);

int fn1 (int b, int c)
{
  return c < 0 || c > 31 ? 0 : b >> c;
}

unsigned char d = 255; 
int e, f;

int main ()
{
  for (; f < 2; f++)
    e = fn1 (1, d++);
  printf ("%d\n", e); 
  return 0; 
}
Comment 1 Marek Polacek 2016-12-08 09:48:19 UTC
This used to work correctly, then with introduction of loop splitting in r241374 it started to ICE:

/home/brq/mpolacek/2.c: In function ‘main’:
/home/brq/mpolacek/2.c:12:5: error: type mismatch in binary expression
 int main ()
     ^~~~
int

int

unsigned char

_38 = _37 - d_lsm.12_20;
/home/brq/mpolacek/2.c:12:5: internal compiler error: verify_gimple failed
0xe85c03 verify_gimple_in_cfg(function*, bool)
	../../gcc/tree-cfg.c:5208
0xd19da0 execute_function_todo
	../../gcc/passes.c:1965
0xd18e2b do_per_function
	../../gcc/passes.c:1649
0xd19f72 execute_todo
	../../gcc/passes.c:2015
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.

This ICE was fixed in r241551 but we've miscompiled this since.
Comment 2 Michael Matz 2016-12-09 13:30:33 UTC
Mine.
Comment 3 Zhendong Su 2016-12-11 16:11:05 UTC
Below is another test that might trigger the same miscompilation: 

$ gcc-trunk -O2 -fsplit-loops small.c; ./a.out
Aborted (core dumped)
$       
$ gcc-trunk -O3 -fno-split-loops small.c; ./a.out
$ 
$ gcc-trunk -O3 small.c; ./a.out
Aborted (core dumped)
$ 
$ cat small.c
int a, b, c;

int main ()
{
  int d; 
  for (; c < 1; c++)
    for (d = 0; d < 3; d++)
      for (b = 0; b < 1; b++)
        if (c >= d) 
          a = 1;

  if (a != 1) 
    __builtin_abort ();

  return 0; 
}
$ 
$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.0 20161211 (experimental) [trunk revision 243523] (GCC) 
$
Comment 4 Michael Matz 2016-12-12 15:31:48 UTC
Thanks for the second testcase as well.  It's not quite the same miscompilation
(the induction vars don't overflow), but a related one (the value of d
considered in the conditional statement is the final one after the d-loop
finishes, not the value at the use itself).  Fixed with v2 of the patch,
at https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01035.html .
Comment 5 Michael Matz 2016-12-12 15:32:52 UTC
(In reply to Michael Matz from comment #4)
> Thanks for the second testcase as well.  It's not quite the same
> miscompilation
> (the induction vars don't overflow), but a related one (the value of d
> considered in the conditional statement is the final one after the d-loop
> finishes, not the value at the use itself).  Fixed with v2 of the patch,
> at https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01035.html .

(Btw: nice testcases, I assume they are generated somehow by a code generator
that knows a bit about semantics?)
Comment 6 Michael Matz 2016-12-13 14:15:24 UTC
Author: matz
Date: Tue Dec 13 14:14:41 2016
New Revision: 243606

URL: https://gcc.gnu.org/viewcvs?rev=243606&root=gcc&view=rev
Log:
Fix pr78725

	PR tree-optimization/78725
	* tree-ssa-loop-split.c (split_at_bb_p): Check for overflow and
	at correct use point.

testsuite/
	PR tree-optimization/78725
	* gcc.dg/pr78725.c: New test.
	* gcc.dg/pr78725-2.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr78725-2.c
    trunk/gcc/testsuite/gcc.dg/pr78725.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-loop-split.c
Comment 7 Richard Biener 2016-12-13 14:50:33 UTC
Fixed.