Bug 28230 - [4.2 Regression] -O2 -fwrapv miscompiles gcc, binutils, gzip.
Summary: [4.2 Regression] -O2 -fwrapv miscompiles gcc, binutils, gzip.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.2.0
: P1 blocker
Target Milestone: 4.2.0
Assignee: Richard Biener
URL:
Keywords: wrong-code
: 28272 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-07-03 08:40 UTC by Pawel Sikora
Modified: 2006-10-11 16:06 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.2.0 4.1.2
Last reconfirmed: 2006-10-10 14:32:50


Attachments
testcase (13.17 KB, text/plain)
2006-09-20 20:44 UTC, Pawel Sikora
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pawel Sikora 2006-07-03 08:40:07 UTC
/home/users/pluto/rpm/BUILD/trunk/builddir/./gcc/xgcc
-B/home/users/pluto/rpm/BUILD/trunk/builddir/./gcc/
-B/usr/x86_64-pld-linux/bin/ -B/usr/x86_64-pld-linux/lib/
-isystem /usr/x86_64-pld-linux/include
-isystem /usr/x86_64-pld-linux/sys-include
-O2 -O2 -O2 -fno-strict-aliasing -fwrapv -march=x86-64 -pipe
-DIN_GCC    -W -Wall -Wwrite-strings -Wstrict-prototypes
-Wmissing-prototypes -Wold-style-definition  -isystem ./include
-I. -I. -I../../gcc -I../../gcc/. -I../../gcc/../include
-I../../gcc/../libcpp/include  -I../../gcc/../libdecnumber
-I../libdecnumber  -g0 -finhibit-size-directive -fno-inline-functions
-fno-exceptions -fno-zero-initialized-in-bss -fno-toplevel-reorder
-fno-omit-frame-pointer -fno-asynchronous-unwind-tables 
-c ../../gcc/crtstuff.c -DCRT_BEGIN -o crtbegin.o
../../gcc/crtstuff.c:1: internal compiler error: Segmentation fault

(gdb) set args -fpreprocessed crtstuff.i -quiet -dumpbase crtstuff.i -mtune=generic -auxbase crtstuff -version -o /tmp/ccenndGf.s

(gdb) r
Starting program: /home/users/pluto/rpm/BUILD/trunk/builddir/gcc/cc1 -fpreprocessed crtstuff.i -quiet -dumpbase crtstuff.i -mtune=generic -auxbase crtstuff -version -o /tmp/ccenndGf.s
GNU C version 4.2.0 20060702 (experimental) (PLD-Linux) (x86_64-pld-linux)
        compiled by GNU C version 4.2.0 20060702 (experimental) (PLD-Linux).
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096

Program received signal SIGSEGV, Segmentation fault.
0x000000000091cf26 in lshift_significand ()
(gdb) bt
#0  0x000000000091cf26 in lshift_significand ()
#1  0x000000000091fbb4 in normalize ()
#2  0x0000000000921b6c in real_from_integer ()
#3  0x000000000067f18f in init_emit_once ()
#4  0x000000000098f289 in toplev_main ()
#5  0x00000000004a0c91 in main ()

$ ./xgcc -v
Reading specs from /usr/lib64/gcc/x86_64-pld-linux/4.2.0/specs
Target: x86_64-pld-linux
Configured with: ../configure --prefix=/usr
--with-local-prefix=/usr/local
--libdir=/usr/lib64 --libexecdir=/usr/lib64
--infodir=/usr/share/info --mandir=/usr/share/man
--x-libraries=/usr/lib64 --enable-shared
--enable-threads=posix --enable-languages=c,c++,fortran,objc,obj-c++,java
--enable-c99 --enable-long-long --enable-multilib --enable-nls
--disable-werror --with-gnu-as --with-gnu-ld --with-demangler-in-ld
--with-system-zlib --with-slibdir=/lib64 --without-system-libunwind
--enable-cmath --with-long-double-128
--with-gxx-include-dir=/usr/include/c++/4.2.0 --disable-libstdcxx-pch
--enable-__cxa_atexit --enable-libstdcxx-allocator=new
--disable-libjava-multilib --enable-libgcj --enable-libgcj-multifile
--enable-libgcj-database --enable-gtk-cairo --enable-java-awt=qt,gtk,xlib
--enable-jni --enable-xmlj --enable-alsa --enable-dssi --enable-bootstrap x86_64-pld-linux
Thread model: posix
gcc version 4.2.0 20060702 (experimental) (PLD-Linux)
Comment 1 Pawel Sikora 2006-07-03 11:24:50 UTC
without profiling boostrap fails too.

Program received signal SIGSEGV, Segmentation fault.
0x000000000074c419 in lshift_significand (r=0xc97980, a=0xc97980, n=63)
                   at ../../gcc/real.c:254
254             r->sig[SIGSZ-1-i]

(gdb) p *r
$2 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0,
      uexp = 1, sig = {0, 1, 9223372036854775808}}
(gdb) p *a
$3 = {cl = 1, decimal = 0, sign = 0, signalling = 0, canonical = 0,
      uexp = 1, sig = {0, 1, 9223372036854775808}}

(gdb) bt
#0  0x000000000074c419 in lshift_significand (r=0xc97980, a=0xc97980, n=63)
    at ../../gcc/real.c:254
#1  0x000000000074fcbc in real_from_integer (r=0xc97980, mode=DFmode,
    low=<value optimized out>, high=1, unsigned_p=<value optimized out>)
    at ../../gcc/real.c:2062
#2  0x00000000005ac6e2 in init_emit_once (line_numbers=<value optimized out>)
    at ../../gcc/emit-rtl.c:5194
#3  0x000000000079a18b in toplev_main (argc=<value optimized out>,
    argv=<value optimized out>) at ../../gcc/toplev.c:1825
Comment 2 Pawel Sikora 2006-07-04 21:16:44 UTC
works fine with BOOT_CFLAGS="-01" && STAGE1_CFLAGS="-O0".
with BOOT_CFLAGS="-O2" ices as above.
Comment 3 Pawel Sikora 2006-08-03 20:39:11 UTC
now i'm sure that `-O2 -fwrapv` causes wrong-code in stage2 binaries.

to reproduce this failure try to build gcc with:
STAGE1_CFLAGS="-O1" 
BOOT_CFLAGS="-O2 -fwrapv"

$ xgcc -v
Using built-in specs.
Target: x86_64-pld-linux
Configured with: ../configure --prefix=/usr --with-local-prefix=/usr/local
--libdir=/usr/lib64 --libexecdir=/usr/lib64 --infodir=/usr/share/info
--mandir=/usr/share/man --x-libraries=/usr/lib64 --enable-shared
--enable-threads=posix --enable-languages=c --enable-c99
--enable-long-long --enable-multilib --enable-nls --disable-werror
--with-gnu-as --with-gnu-ld --with-demangler-in-ld --with-system-zlib
--with-slibdir=/lib64 --without-system-libunwind --without-x
--with-long-double-128 --enable-bootstrap x86_64-pld-linux
Thread model: posix
gcc version 4.2.0 20060803 (experimental) (PLD-Linux)
Comment 4 Pawel Sikora 2006-08-03 20:41:23 UTC
(In reply to comment #2)
> works fine with BOOT_CFLAGS="-01" && STAGE1_CFLAGS="-O0".
> with BOOT_CFLAGS="-O2" ices as above.

please ignore this comment. i missed note about my common cflags
(-fwrpav -fno-strict-aliasing)
Comment 5 Pawel Sikora 2006-08-03 20:42:23 UTC
*** Bug 28272 has been marked as a duplicate of this bug. ***
Comment 6 Pawel Sikora 2006-09-01 20:11:21 UTC
I have a smaller testcase.

`-march=x86-64 -O2 -fno-strict-aliasing -fwrapv` generates wrong code
for gas/write.c from binutils-2.17.50.0.3 and assembler fails on every
file with an error message:

/tmp/ccsCHgd4.s: Assembler messages:
/tmp/ccsCHgd4.s:3: Fatal error: Infinite loop encountered whilst attempting
                   to compute the addresses of symbols in section .text
Comment 7 Pawel Sikora 2006-09-19 13:08:07 UTC
and one more misscompiled program -> gzip-1.3.5.
this time 4.1.2 with -O2 -fwrapv produces wrong code.

$ dd if=/dev/zero of=foo count=10
$ gzip foo
$ gzip -d foo.gz
$ gzip: foo.gz: invalid compressed data--format violated
Comment 8 Pawel Sikora 2006-09-20 20:44:24 UTC
(In reply to comment #7)
> and one more misscompiled program -> gzip-1.3.5.
> this time 4.1.2 with -O2 -fwrapv produces wrong code.
> 
> $ dd if=/dev/zero of=foo count=10
> $ gzip foo
> $ gzip -d foo.gz
> $ gzip: foo.gz: invalid compressed data--format violated

further investigation shows that only `-O1 -ftree-vrp -fwrapv'
miscompiles the gzip/inflate.o.
Comment 9 Pawel Sikora 2006-09-20 20:44:59 UTC
Created attachment 12302 [details]
testcase
Comment 10 Pawel Sikora 2006-09-20 23:31:12 UTC
i have a reduced testcase:

$ cat tmp.c
void foo( unsigned long bb, unsigned short tn, unsigned e, unsigned* w )
{
        unsigned n = tn + bb;
        do {
                e = (e > n) ? e : *w;
                n -= (e > n) ? n : e;
                if (*w)
                        *w = 0;
        } while ( n );
}
int main()
{
        unsigned w = 0;
        foo( 0, 0, 0, &w );
        return 0;
}

with `-O1 -fwrapv -ftree-vrp' gcc-4.2 produces an infinite loop.
without -ftree-vrp it reaches an exit point. gcc-4.1 works fine
in both cases.
Comment 11 Andrew Pinski 2006-09-21 03:31:17 UTC
Confirmed with the testcase in comment #10.
Comment 12 Andrew Pinski 2006-09-21 03:37:24 UTC
Actually note here is one for 32bit targets also:
void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w );
void foo( unsigned long long bb, unsigned short tn, unsigned e, unsigned* w )
{
        unsigned n = tn + bb;
        do {
                e = (e > n) ? e : *w;
                n -= (e > n) ? n : e;
                if (*w)
                        *w = 0;
        } while ( n );
}
int main()
{
        unsigned w = 0;
        foo( 0, 0, 0, &w );
        return 0;
}
Comment 13 Steven Bosscher 2006-09-24 09:58:51 UTC
VRP bug.
Comment 14 Steven Bosscher 2006-09-24 10:05:06 UTC
Value ranges after VRP without -fwrapv:

e_1: VARYING
n_2: VARYING
e_3: VARYING
tn_4: VARYING
D.1875_5: [0, 65535]  EQUIVALENCES: { } (0 elements)
bb_6: VARYING
D.1876_7: [0, +INF]  EQUIVALENCES: { } (0 elements)
n_8: [0, +INF]  EQUIVALENCES: { } (0 elements)
e_9: VARYING
e_11: VARYING
e_12: [n_2 + 1, +INF]  EQUIVALENCES: { e_1 e_21 } (2 elements)
e_13: [e_3, e_3]  EQUIVALENCES: { e_3 } (1 elements)
D.1878_14: [0, +INF]  EQUIVALENCES: { } (0 elements)
n_15: [0, +INF]  EQUIVALENCES: { } (0 elements)
D.1879_16: VARYING
SMT.5_17: VARYING
SMT.5_18: VARYING
e_21: [n_2 + 1, +INF]  EQUIVALENCES: { e_1 } (1 elements)




Value ranges after VRP with -fwrapv:

e_1: VARYING
n_2: [0, 65534]  EQUIVALENCES: { } (0 elements)
e_3: VARYING
tn_4: VARYING
D.1875_5: [0, 65535]  EQUIVALENCES: { } (0 elements)
bb_6: VARYING
D.1876_7: [0, +INF]  EQUIVALENCES: { } (0 elements)
n_8: [0, 65534]  EQUIVALENCES: { } (0 elements)
e_9: VARYING
e_11: VARYING
e_12: [1, +INF]  EQUIVALENCES: { e_1 e_21 } (2 elements)
e_13: [e_3, e_3]  EQUIVALENCES: { e_3 } (1 elements)
D.1878_14: [0, +INF]  EQUIVALENCES: { } (0 elements)
n_15: [1, 65534]  EQUIVALENCES: { } (0 elements)
D.1879_16: VARYING
SMT.5_17: VARYING
SMT.5_18: VARYING
e_21: [1, +INF]  EQUIVALENCES: { e_1 } (1 elements)
Comment 15 Steven Bosscher 2006-09-24 10:08:15 UTC
Significant difference:

n_15: [0, +INF]  EQUIVALENCES: { } (0 elements)  without -fwrapv
n_15: [1, 65534]  EQUIVALENCES: { } (0 elements) with -fwrapv

With -fwrapv this results in:

Folding predicate n_15 != 0 to 1
Folded statement: if (n_15 != 0) goto <L7>; else goto <L6>;
            into: if (1) goto <L7>; else goto <L6>;

which is the infinite loop here.
Comment 16 Steven Bosscher 2006-09-24 10:11:15 UTC
Actually looks like SCEV derives the wrong range.
Comment 17 Richard Biener 2006-10-10 14:32:50 UTC
No, it's extract_range_from_binary_expr operating on [0, +INF] + [0, 65535] and
blindly using int_const_binop to compute the resulting range...

I believe the following is completely bogus and we cannot ignore overflows
in range arithmetic for wrapv either.

static inline tree
vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
{
  tree res;

  if (flag_wrapv)
    return int_const_binop (code, val1, val2, 0);
Comment 18 patchapp@dberlin.org 2006-10-11 10:45:20 UTC
Subject: Bug number PR28230

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00607.html
Comment 19 Richard Biener 2006-10-11 16:05:49 UTC
Subject: Bug 28230

Author: rguenth
Date: Wed Oct 11 16:05:37 2006
New Revision: 117637

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

	PR tree-optimization/28230
	* tree-vrp.c (vrp_int_const_binop): Move flag_wrapv handling
	to the correct place.

	* gcc.dg/torture/pr28230.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/torture/pr28230.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-vrp.c

Comment 20 Richard Biener 2006-10-11 16:06:11 UTC
Fixed.