Bug 68083 - [6 Regression] wrong code at -O3 on x86_64-linux-gnu
Summary: [6 Regression] wrong code at -O3 on x86_64-linux-gnu
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: 6.0
Assignee: Alexandre Oliva
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2015-10-24 22:57 UTC by Zhendong Su
Modified: 2015-11-03 00:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.2.0
Known to fail:
Last reconfirmed: 2015-10-26 00:00:00


Attachments
Patch I'm testing to fix the problem (1.36 KB, patch)
2015-10-30 13:15 UTC, Alexandre Oliva
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2015-10-24 22:57:59 UTC
The current gcc trunk miscompiles the following code on x86_64-linux-gnu at -O3 in both 32-bit and 64-bit modes. 

This is a regression from 5.2.x.


$ 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/6.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --prefix=/usr/local/gcc-trunk --enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 6.0.0 20151023 (experimental) [trunk revision 229251] (GCC) 
$ 
$ gcc-trunk -O2 small.c; ./a.out
$ gcc-5.2 -O3 small.c; ./a.out
$ 
$ gcc-trunk -O3 small.c
$ ./a.out
Aborted (core dumped)
$ 


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


int a = 2, b = 1, c = 1;

int
fn1 ()
{
  int d;
  for (; a; a--)
    {
      for (d = 0; d < 4; d++)
	{
	  int k;
	  if (c < 1)
	    if (k)
	      c = 0;
	  if (b)
	    continue;
	  return 0;
	}
      b = !1;
    }
  return 0;
}

int
main ()
{
  fn1 ();

  if (a != 1) 
    __builtin_abort (); 

  return 0;
}
Comment 1 Richard Biener 2015-10-26 11:42:26 UTC
Confirmed.
Comment 2 Marek Polacek 2015-10-26 11:56:11 UTC
Started with r226901.
Comment 3 Alexandre Oliva 2015-10-30 11:03:17 UTC
This is a latent problem in ifcvt, that pulls the computation involving the uninitialized k out of the always-false condition.  Things go down the hill when k's default def gets coalesced with b, and rtl optimizers further mess things up.
Comment 4 Alexandre Oliva 2015-10-30 11:18:54 UTC
s/ifcvt/ifcombine/ above, sorry
Comment 5 Richard Biener 2015-10-30 13:05:50 UTC
Ok, we shouldn't introduce uninitialized uses.  It's going to be interesting to
teach this to ifcombine ;)
Comment 6 Alexandre Oliva 2015-10-30 13:15:57 UTC
Created attachment 36622 [details]
Patch I'm testing to fix the problem

This patch stops ifcombine from introducing this kind of undefined behavior.  I'm testing it now, and I'll post it to the list if that completes successfully.
Comment 7 Alexandre Oliva 2015-11-03 00:30:39 UTC
Author: aoliva
Date: Tue Nov  3 00:30:07 2015
New Revision: 229690

URL: https://gcc.gnu.org/viewcvs?rev=229690&root=gcc&view=rev
Log:
[PR68083] don't introduce undefined behavior in ifcombine

The ifcombine pass may move a conditional access to an uninitialized
value before the condition that ensures it is always well-defined,
thus introducing undefined behavior.  Stop it from doing so.

for  gcc/ChangeLog

	PR tree-optimization/68083
	* tree-ssa-ifcombine.c: Include tree-ssa.h.
	(bb_no_side_effects_p): Test for undefined uses too.
	* tree-ssa.c (gimple_uses_undefined_value_p): New.
	* tree-ssa.h (gimple_uses_undefined_value_p): Declare.

for  gcc/testsuite/ChangeLog

	PR tree-optimization/68083
	* gcc.dg/torture/pr68083.c: New.  From Zhendong Su.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr68083.c
Modified:
    trunk/ChangeLog
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-ifcombine.c
    trunk/gcc/tree-ssa.c
    trunk/gcc/tree-ssa.h
Comment 8 Alexandre Oliva 2015-11-03 00:48:55 UTC
Fixed