Bug 41555 - [4.5 regression] possible miscompilation in whole-program mode
Summary: [4.5 regression] possible miscompilation in whole-program mode
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-10-03 15:46 UTC by John Regehr
Modified: 2009-10-19 02:09 UTC (History)
4 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2009-10-19 02:09:18


Attachments
failure-inducing input (891 bytes, text/x-csrc)
2009-10-03 16:42 UTC, John Regehr
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Regehr 2009-10-03 15:46:00 UTC
The test input below is really gross but I couldn't easily reduce it more.  

The behavior leading to the apparent bad execution is actually pretty simple: the "if" test in func_19() is true and so the store to g_133 must execute.

regehr@john-home:~/volatile/tmp201$ current-gcc -O3 small.c -o small
regehr@john-home:~/volatile/tmp201$ ./small
checksum = 1
regehr@john-home:~/volatile/tmp201$ current-gcc -O3 -fwhole-program small.c -o small
regehr@john-home:~/volatile/tmp201$ ./small
checksum = 0

regehr@john-home:~/volatile/tmp201$ current-gcc -v

Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/home/regehr/z/tmp/gcc-r152425-install --program-prefix=r152425- --enable-languages=c,c++
Thread model: posix
gcc version 4.5.0 20091002 (experimental) (GCC) 

regehr@john-home:~/volatile/tmp201$ cat small.c

#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <limits.h>

static uint64_t safe_div_func_uint64_t_u_u (uint64_t _ui1, uint64_t _ui2)
{
  if (_ui2==0) return _ui1;
  return _ui1 / _ui2;
}

static int64_t safe_div_func_int64_t_s_s (int64_t _si1, int64_t _si2)
{
  if (_si2==0 || (_si1==INT64_MIN && _si2==-1)) return _si1;
  return _si1 / _si2;
}

#define safe_add_macro_int8_t_s_s(si1,si2) \
		((((((int8_t)(si1))>((int8_t)0)) && (((int8_t)(si2))>((int8_t)0)) && (((int8_t)(si1)) > ((INT8_MAX)-((int8_t)(si2))))) \
		  || ((((int8_t)(si1))<((int8_t)0)) && (((int8_t)(si2))<((int8_t)0)) && (((int8_t)(si1)) < ((INT8_MIN)-((int8_t)(si2)))))) \
		 ? ((int8_t)(si1)) \
		 : (((int8_t)(si1)) + ((int8_t)(si2))) \
		 ) 

static int8_t
safe_add_func_int8_t_s_s(int8_t _si1, int8_t _si2)
{
  return safe_add_macro_int8_t_s_s(_si1,_si2);
}

#define safe_rshift_macro_uint64_t_u_s(left,right) \
	(((((int)(right)) < ((uint64_t)0)) \
			 || (((int)(right)) >= sizeof(uint64_t)*CHAR_BIT)) \
			? ((uint64_t)(left)) \
			: (((uint64_t)(left)) >> ((int)(right))))

static uint64_t
safe_rshift_func_uint64_t_u_s(uint64_t _left, int _right)
{
  return safe_rshift_macro_uint64_t_u_s(_left,_right);
}

#define safe_mul_macro_int32_t_s_s(si1,si2) \
  ((((((int32_t)(si1)) > ((int32_t)0)) && (((int32_t)(si2)) > ((int32_t)0)) && (((int32_t)(si1)) > ((INT32_MAX) / ((int32_t)(si2))))) || \
  ((((int32_t)(si1)) > ((int32_t)0)) && (((int32_t)(si2)) <= ((int32_t)0)) && (((int32_t)(si2)) < ((INT32_MIN) / ((int32_t)(si1))))) || \
  ((((int32_t)(si1)) <= ((int32_t)0)) && (((int32_t)(si2)) > ((int32_t)0)) && (((int32_t)(si1)) < ((INT32_MIN) / ((int32_t)(si2))))) || \
  ((((int32_t)(si1)) <= ((int32_t)0)) && (((int32_t)(si2)) <= ((int32_t)0)) && (((int32_t)(si1)) != ((int32_t)0)) && (((int32_t)(si2)) < ((INT32_MAX) / ((int32_t)(si1)))))) \
  ? ((int32_t)(si1)) \
  : ((int32_t)(si1)) * ((int32_t)(si2)))

static int32_t
safe_mul_func_int32_t_s_s (int32_t _si1, int32_t _si2)
{
  return safe_mul_macro_int32_t_s_s(_si1,_si2);
}

int8_t g_39;
volatile uint8_t g_46;
uint8_t g_47;
uint8_t *g_62;
uint8_t g_79;
int8_t g_101 = -1L;
uint8_t *g_114;
uint8_t *g_126;
uint8_t g_133;

uint16_t func_35 (int32_t * p_36, uint64_t p_37, uint32_t p_38);
uint16_t func_35 (int32_t * p_36, uint64_t p_37, uint32_t p_38)
{
  assert (g_62 == 0);
  for (g_39 = 1; g_39 < 0; g_39 = 1)
    {
    }
  return 1;
}

int32_t func_19 (int32_t p_20);
int32_t func_19 (int32_t p_20)
{
  if (1 !=
      safe_div_func_uint64_t_u_u ((safe_div_func_int64_t_s_s (p_20, 1)),
				  g_101))
    {
      func_35 (0, 1 <= (safe_add_func_int8_t_s_s (g_47, g_46)) > p_20 < 1, 1);
      g_133 = 1;
      assert (g_114 == 0);
      assert (g_126 == 0);
    }
  return 1;
}

uint8_t func_2 (int32_t p_6);
uint8_t func_2 (int32_t p_6)
{
  for (1; p_6 > 1; 1)
    return 0;
  func_19 (g_79);
  if (safe_mul_func_int32_t_s_s
      ((0, 1 < (safe_rshift_func_uint64_t_u_s (1 ^ p_6, 1))),
       (func_35 (&p_6, 1, 1) < 1)))
    {
    }
  return 1;
}

int main (void)
{
  func_2 (1);
  printf ("checksum = %d\n", g_133);
  return 0;
}
Comment 1 Richard Biener 2009-10-03 16:33:10 UTC
Where do you get all this testcases from ... ;)

Btw, making more functions static probably results in the same failure
without -fwhole-program (well, reproducing the same inline decision, that is).
Comment 2 John Regehr 2009-10-03 16:42:37 UTC
Created attachment 18696 [details]
failure-inducing input

There is no problem here at -O3.  However if you make g_101 static then the wrong answer is returned at -O3.
Comment 3 John Regehr 2009-10-03 16:44:09 UTC
Making the variables static in addition to the functions causes the problem to happen at -O3.  

The bad behavior happens at -O3 only if g_101 is static.
Comment 4 Richard Biener 2009-10-11 11:22:16 UTC
I can't reproduce this failure anymore (with rev. 152638).  I'll add a testcase.
Comment 5 Richard Biener 2009-10-11 11:24:22 UTC
Subject: Bug 41555

Author: rguenth
Date: Sun Oct 11 11:24:10 2009
New Revision: 152639

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152639
Log:
2009-10-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/41555
	* gcc.dg/torture/pr41555.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr41555.c
Modified:
    trunk/gcc/testsuite/ChangeLog

Comment 6 Steve Ellcey 2009-10-13 16:05:13 UTC
The new test case (gcc.dg/torture/pr41555.c) is failing on ia64-hp-hpux11.23.
It looks like the *_MAX and *_MIN macros are only defined when in c99 mode so the test requires -std=c99 on this platform (and others?)
Comment 7 rguenther@suse.de 2009-10-15 08:41:24 UTC
Subject: Re:  [4.5 regression] possible
 miscompilation in whole-program mode

On Tue, 13 Oct 2009, sje at cup dot hp dot com wrote:

> ------- Comment #6 from sje at cup dot hp dot com  2009-10-13 16:05 -------
> The new test case (gcc.dg/torture/pr41555.c) is failing on ia64-hp-hpux11.23.
> It looks like the *_MAX and *_MIN macros are only defined when in c99 mode so
> the test requires -std=c99 on this platform (and others?)

I wondered about this before but the testcase worked without -std=c99
for me.  A patch to add it is pre-approved.

Richard.
Comment 8 hjl@gcc.gnu.org 2009-10-15 21:18:16 UTC
Subject: Bug 41555

Author: hjl
Date: Thu Oct 15 21:17:36 2009
New Revision: 152870

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152870
Log:
2009-10-15  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline:
	2009-10-13  Martin Jambor  <mjambor@suse.cz>

	* gcc.c-torture/compile/pr41661.c: New test.

	2009-10-12  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/41683
	* gfortran.dg/fmt_error_9.f: Add check for repeat count after P.

	2009-10-12  Dodji Seketeli  <dodji@redhat.com>

	PR c++/41570
	* g++.dg/debug/dwarf2/template-params-7.C: New test.

	2009-10-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/41555
	* gcc.dg/torture/pr41555.c: New testcase.

	2009-10-09  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/41634
	* gcc.c-torture/compile/pr41634.c: New testcase.

	2009-10-08  Michael Matz  <matz@suse.de>

	PR middle-end/41573
	* gcc.dg/pr41573.c: New test.

	2009-10-07  Joseph Myers  <joseph@codesourcery.com>

	PR c/41182
	* gcc.c-torture/compile/pr41182-1.c: New.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/debug/dwarf2/template-params-7.C
      - copied unchanged from r152869, trunk/gcc/testsuite/g++.dg/debug/dwarf2/template-params-7.C
    branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
      - copied unchanged from r152869, trunk/gcc/testsuite/gcc.c-torture/compile/pr41182-1.c
    branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr41634.c
      - copied unchanged from r152869, trunk/gcc/testsuite/gcc.c-torture/compile/pr41634.c
    branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr41661.c
      - copied unchanged from r152868, trunk/gcc/testsuite/gcc.c-torture/compile/pr41661.c
    branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr41573.c
      - copied unchanged from r152869, trunk/gcc/testsuite/gcc.dg/pr41573.c
    branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/torture/pr41555.c
      - copied unchanged from r152869, trunk/gcc/testsuite/gcc.dg/torture/pr41555.c
    branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/fmt_error_9.f
      - copied unchanged from r152869, trunk/gcc/testsuite/gfortran.dg/fmt_error_9.f
Modified:
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 9 John David Anglin 2009-10-19 01:31:28 UTC
Testcase also fails on hppa2.0w-hp-hpux11.11:

FAIL: gcc.dg/torture/pr41555.c  -O0  (test for excess errors)
Excess errors:
/mnt/gnu/gcc/gcc/gcc/testsuite/gcc.dg/torture/pr41555.c:4:20: error: stdint.h: N
o such file or directory
/mnt/gnu/gcc/gcc/gcc/testsuite/gcc.dg/torture/pr41555.c:9: error: expected '=', 
',', ';', 'asm' or '__attribute__' before 'safe_div_func_uint64_t_u_u'
...
Comment 10 John David Anglin 2009-10-19 01:32:36 UTC
Sorry, I should have added this on 4.4 branch.
Comment 11 John David Anglin 2009-10-19 02:09:18 UTC
> Where do you get all this testcases from ... ;)

Maybe from here: http://pics.regehr.org/panos_brooks_range_09/