Bug 1823 - -ftrapv aborts with pointer difference due to division optimization
Summary: -ftrapv aborts with pointer difference due to division optimization
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.0
: P3 normal
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
: 9067 9088 (view as bug list)
Depends on:
Blocks:
 
Reported: 2001-01-31 12:06 UTC by meeberdt
Modified: 2003-10-17 17:48 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
example.ii.gz (33.21 KB, application/x-gzip )
2003-05-21 15:17 UTC, meeberdt
Details
suggested patch (316 bytes, patch)
2003-07-06 18:09 UTC, Falk Hueffner
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description meeberdt 2001-01-31 12:06:00 UTC
A simple program (included in How-To-Repeat) is compiled like so:

g++ -Wall -W -g -ftrapv -save-temps -v example.cc

The output from this command appears at the end of this section.
Simply executing the resulting a.out yields this:

[falcon.cacc]/ncsu/meeberdt/tmp/Gcc-bug> a.out
Abort
[falcon.cacc]/ncsu/meeberdt/tmp/Gcc-bug>

Running it gdb (sorry, I don't have a newer version handy) gives this:

[falcon.cacc]/ncsu/meeberdt/tmp/Gcc-bug> gdb a.out
GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.5.1"...
(gdb) run

Program received signal SIGABRT, Aborted.
0xef6748d8 in kill ()
(gdb) bt
#0  0xef6748d8 in kill ()
#1  0xef63a66c in abort ()
#2  0x10dc8 in __mulvsi3 (a=42, b=-1431655765)
#3  0x11054 in _ZNKSt15_Deque_iteratorI10my_struct2RS0_PS0_EmiERKS3_ (
    this=0xffffffd6, __x=@0xeffff8b8)
    at /ncsu/meeberdt/local/gcc-curr/include/g++-v3/bits/stl_deque.h:118
#4  0x10f48 in _ZNKSt5dequeI10my_struct2SaIS0_EE4sizeEv (this=0xeffff8c8)
    at /ncsu/meeberdt/local/gcc-curr/include/g++-v3/bits/stl_deque.h:524
#5  0x10ebc in _ZNKSt5queueI10my_struct2St5dequeIS0_SaIS0_EEE4sizeEv (
    this=0xeffff8b0)
    at /ncsu/meeberdt/local/gcc-curr/include/g++-v3/bits/stl_queue.h:91
#6  0x10c54 in main () at example.cc:15
(gdb)

Compiling without -ftrapv gives the expected output.

Creating a queue for a simpler object (e.g. my_struct1 alone,
instead of my_struct1 nested within my_struct2) doesn't exhibit this problem.

Here's the output from the compilation command:

Reading specs from /ncsu/meeberdt/local/gcc-curr/bin/../lib/gcc-lib/sparc-sun-solaris2.5.1/2.97/specs
Configured with: /tmp/gcc-20010129/configure --prefix=/ncsu/meeberdt/local/gcc-0129 --enable-shared --enable-languages=c++ --with-as=/ncsu/meeberdt/local/bin/as --with-ld=/ncsu/meeberdt/local/bin/ld
gcc version 2.97 20010129 (experimental)
GNU CPP version 2.97 20010129 (experimental) (cpplib) (sparc)
ignoring nonexistent directory "/usr/local/include"
ignoring duplicate directory "/ncsu/meeberdt/local/gcc-0129/include/g++-v3"
ignoring duplicate directory "/ncsu/meeberdt/local/gcc-0129/lib/gcc-lib/sparc-sun-solaris2.5.1/2.97/include"
ignoring duplicate directory "/ncsu/meeberdt/local/gcc-0129/sparc-sun-solaris2.5.1/include"
#include "..." search starts here:
#include <...> search starts here:
 /ncsu/meeberdt/local/gcc-curr/include/g++-v3
 /ncsu/meeberdt/local/gcc-curr/lib/gcc-lib/sparc-sun-solaris2.5.1/2.97/include
 /ncsu/meeberdt/local/gcc-curr/sparc-sun-solaris2.5.1/include
 /ncsu/meeberdt/local/gcc-0129/sparc-sun-solaris2.5.1/include/g++-v3
 /usr/include
End of search list.
 /ncsu/meeberdt/local/gcc-curr/bin/../lib/gcc-lib/sparc-sun-solaris2.5.1/2.97/cc1plus -fpreprocessed example.ii -quiet -dumpbase example.cc -g -Wall -W -version -ftrapv -o example.s
GNU CPP version 2.97 20010129 (experimental) (cpplib) (sparc)
GNU C++ version 2.97 20010129 (experimental) (sparc-sun-solaris2.5.1)
        compiled by GNU C version 2.97 20010129 (experimental).
 /ncsu/meeberdt/local/bin/as -V -Qy -s -o example.o example.s
GNU assembler version 2.10.1 (sparc-sun-solaris2.5.1) using BFD version 2.10.1
GNU ld version 2.10.1 (with BFD 2.10.1)
  Supported emulations:
   elf32_sparc

Release:
gcc version 2.97 20010129, 3.0 20010305.

Environment:
tools built, and example run, under Solaris 2.5.1 on a
Sun Ultra 5/10 UPA/PCI (UltraSPARC-IIi 270MHz)
and i686-pc-linux-gnu (Red Hat Linux 7)

How-To-Repeat:
Compile this with the -ftrapv option:

#include <queue>
#include <cstdio>

typedef  struct { int some_num; char* some_str; }  my_struct1;

typedef  struct { int some_other_num; my_struct1 s; }  my_struct2;


int
main()
{
    std::queue<my_struct2>  my_queue;

    if (my_queue.size() == 0)
        std::printf( "things work as expected\n" );
}
Comment 1 Alexandre Oliva 2001-03-11 09:32:24 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Duplicated on i686-pc-linux-gnu (Red Hat Linux 7) with 2001-03-05's snapshot.  Seems to be a library error.
Comment 2 Alexandre Oliva 2001-03-11 17:32:24 UTC
From: aoliva@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, meeberdt@unity.ncsu.edu, nobody@gcc.gnu.org
Cc:  
Subject: Re: libstdc++/1823
Date: 11 Mar 2001 17:32:24 -0000

 Synopsis: program compiled with -ftrapv aborts in std::queue<>.size()
 
 State-Changed-From-To: open->analyzed
 State-Changed-By: aoliva
 State-Changed-When: Sun Mar 11 09:32:24 2001
 State-Changed-Why:
     Duplicated on i686-pc-linux-gnu (Red Hat Linux 7) with 2001-03-05's snapshot.  Seems to be a library error.
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=1823&database=gcc
Comment 3 Benjamin Kosnik 2002-11-01 18:01:06 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Cannot duplicate on i686-pc-linux-gnu (Red Hat Linux 7) with 2002-11-01 sources.
Comment 4 Falk Hueffner 2003-07-06 17:09:26 UTC
Here's a test case (works for me on alpha-linux mainline):

struct s { char c[3]; };

__PTRDIFF_TYPE__ frob (struct s *cur, struct s *last) {
    return last - cur;
}

int main (void) {
    struct s a[17];

    if (frob(a, a + 17) != 17)
	abort ();

    return 0;
}

The problem is caused by the optimization of the division by three to a
multiplication with 0xaaaaaaaaaaaaaaab; this works since the difference
is known to be a multiple of 3.

However, the multiplication is done with a trapping instruction:

subq/v  a1,a0,t2
ldq     t3,32256(t0)	# 0xaaaaaaaaaaaaaaab
mulq/v  t2,t3,v0	# traps
ret
Comment 5 Falk Hueffner 2003-07-06 17:27:46 UTC
*** Bug 9067 has been marked as a duplicate of this bug. ***
Comment 6 Falk Hueffner 2003-07-06 17:30:52 UTC
*** Bug 9088 has been marked as a duplicate of this bug. ***
Comment 7 Falk Hueffner 2003-07-06 18:09:07 UTC
Created attachment 4354 [details]
suggested patch

This patch fixes it. I don't think it's worth bothering to "save" the 
optimization, -ftrapv code sucks anyway. Probably there are more similar
pitfalls
in expmed, I didn't check carefully. Opinions?
Comment 8 CVS Commits 2003-09-05 18:28:51 UTC
Subject: Bug 1823

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	sayle@gcc.gnu.org	2003-09-05 18:28:48

Modified files:
	gcc            : ChangeLog expmed.c 

Log message:
	PR optimization/1823
	* expmed.c (expand_divmod <EXACT_DIV_EXPR>): Use an unsigned
	multiplication to implement division by constant integer.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.980&r2=2.981
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/expmed.c.diff?cvsroot=gcc&r1=1.140&r2=1.141

Comment 9 roger 2003-09-06 01:31:02 UTC
This has now been fixed on mainline.