This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

c++/7443: gcc (mips) 3.0.3 incorrectly optimizes arithmetic containing 0x80000000


>Number:         7443
>Category:       c++
>Synopsis:       gcc (mips) 3.0.3 incorrectly optimizes arithmetic containing 0x80000000
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 30 07:36:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     David Dolson
>Release:        3.0.3
>Organization:
>Environment:
Compiler running on cygwin on win2k
>Description:
There are several cases in which incorrect code is generated when the constant 0x80000000u is used in source code. Two such cases are included below.

Very simple code to reproduce: 48 lines of source and 62 lines of disassembly to demonstrate several cases.
The entire source code required is in the following bug.cpp
The objdump output is in the following bug.dmp

The defects are found at addresses 0x08, 0x30 and 0x58 of the disassembly: the function argument a0 is compared to zero without involving 0xf0000000 in any way.
Correct behaviour is shown in good_fn1(), in which a subu instruction is issued at address 0x88.

I could not work-around the issue with any variations in casting.

--------- Compiler config
Here is the first part of the -v output (wrapped at 80 cols):

Reading specs from ../../../Tornado/host/x86-win32/bin/../lib/gcc-lib/mips-wrs-v
xworks/3.0.3/specs
Configured with: ../gcc/configure --target=mips-wrs-vxworks --enable-languages=c
,c++
Thread model: vxworks
gcc version 3.0.3
 ../../../Tornado/host/x86-win32/bin/../lib/gcc-lib/mips-wrs-vxworks/3.0.3/cc1pl
us.exe -v -iprefix ../../../Tornado/host/x86-win32/bin/../lib/gcc-lib/mips-wrs-v
xworks/3.0.3/ -M -MF bug.d -MP -MQ bug.o -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNU
C_PATCHLEVEL__=3 -D__mips__ -D__MIPSEB__ -D__R3000__ -D__mips__ -D_MIPSEB -D_R30
00 -D__mips -D__MIPSEB -D__R3000 -D__mips -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -Wa
ll -D__LANGUAGE_C -D_LANGUAGE_C -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=
int -U__mips -D__mips=3 -D__mips64 -D__mipsfp64 -UMIPSEB -U_MIPSEB -U__MIPSEB -U
__MIPSEB__ -D_MIPSEL -D__MIPSEL -D__MIPSEL__ bug.cpp -D__GNUG__=3 -D__GXX_DEPREC
ATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -D__STRICT_ANSI__ -trigraphs -$ -mfp
64 -mgp64 -G 0 -mel -quiet -dumpbase bug.cpp -mcpu=r4000 -mips3 -ansi -O1 -Wall
-ansi -version -o C:/Programs/cygwin/tmp/ccvgdZnl.s
GNU CPP version 3.0.3 (cpplib) [AL 1.1, MM 40] BSD Mips
GNU C++ version 3.0.3 (mips-wrs-vxworks)
        compiled by GNU C version 2.95.3-5 (cygwin special).


-------  bug.cpp starts here
void another_function();

// This function should return true in the following cases:
//              0 <= u <= 0x70000000
//     0xf0000000 <  u <= 0xffffffff
bool bad_fn1(unsigned u)
{
    if( 0xf0000000u - u >= 0x80000000u )
    {
        another_function();
        return true;
    }
    return false;
}

// This function should return true in the following cases:
//              0 <= u <= 0x70000000
//     0xf0000000 <  u <= 0xffffffff
bool bad_fn2(unsigned u)
{
    if( (0xf0000000u - u) & 0x80000000u )
    {
        another_function();
        return true;
    }
    return false;
}

// Should be same as bad_fn2, rephrased using signed arithmetic.
bool bad_fn3( unsigned u )
{
    if( (signed int)( 0xf0000000u - u ) < 0 )
    {
        another_function();
        return true;
    }
    return false;
}

bool good_fn1(unsigned u)
{
    static unsigned u1 = 0xf0000000u;
    if( u1 - u >= 0x80000000u )
    {
        another_function();
        return true;
    }
    return false;
}
-------  bug.dmp starts here

bug.o:     file format elf32-littlemips

Disassembly of section .text:

0000000000000000 <bad_fn1(unsigned)>:
   0:	27bdffd8 	addiu	sp,sp,-40
   4:	ffbf0020 	sd	ra,32(sp)
   8:	04800004 	bltz	a0,1c <bad_fn1(unsigned)+0x1c>
   c:	0000102d 	move	v0,zero
  10:	0c000000 	jal	0 <bad_fn1(unsigned)>
			10: R_MIPS_26	another_function()
  14:	00000000 	nop
  18:	24020001 	li	v0,1
  1c:	dfbf0020 	ld	ra,32(sp)
  20:	03e00008 	jr	ra
  24:	27bd0028 	addiu	sp,sp,40

0000000000000028 <bad_fn2(unsigned)>:
  28:	27bdffd8 	addiu	sp,sp,-40
  2c:	ffbf0020 	sd	ra,32(sp)
  30:	04800004 	bltz	a0,44 <bad_fn2(unsigned)+0x1c>
  34:	0000102d 	move	v0,zero
  38:	0c000000 	jal	0 <bad_fn1(unsigned)>
			38: R_MIPS_26	another_function()
  3c:	00000000 	nop
  40:	24020001 	li	v0,1
  44:	dfbf0020 	ld	ra,32(sp)
  48:	03e00008 	jr	ra
  4c:	27bd0028 	addiu	sp,sp,40

0000000000000050 <bad_fn3(unsigned)>:
  50:	27bdffd8 	addiu	sp,sp,-40
  54:	ffbf0020 	sd	ra,32(sp)
  58:	04800004 	bltz	a0,6c <bad_fn3(unsigned)+0x1c>
  5c:	0000102d 	move	v0,zero
  60:	0c000000 	jal	0 <bad_fn1(unsigned)>
			60: R_MIPS_26	another_function()
  64:	00000000 	nop
  68:	24020001 	li	v0,1
  6c:	dfbf0020 	ld	ra,32(sp)
  70:	03e00008 	jr	ra
  74:	27bd0028 	addiu	sp,sp,40

0000000000000078 <good_fn1(unsigned)>:
  78:	27bdffd8 	addiu	sp,sp,-40
  7c:	ffbf0020 	sd	ra,32(sp)
  80:	3c030000 	lui	v1,0x0
			80: R_MIPS_HI16	.data
  84:	8c630000 	lw	v1,0(v1)
			84: R_MIPS_LO16	.data
  88:	00641823 	subu	v1,v1,a0
  8c:	04610004 	bgez	v1,a0 <good_fn1(unsigned)+0x28>
  90:	0000102d 	move	v0,zero
  94:	0c000000 	jal	0 <bad_fn1(unsigned)>
			94: R_MIPS_26	another_function()
  98:	00000000 	nop
  9c:	24020001 	li	v0,1
  a0:	dfbf0020 	ld	ra,32(sp)
  a4:	03e00008 	jr	ra
  a8:	27bd0028 	addiu	sp,sp,40
  ac:	00000000 	nop
---------- end of bug.dmp
>How-To-Repeat:
$ ccmips -MD -MP -EL -mcpu=r4000 -mips3 -G 0 -ansi -O1 -Wall -c bug.cpp -o bug.o
$ objdumpmips -drC bug.o > bug.dmp
>Fix:
I can work around the problem by changing the constant 0x80000000 to something else (e.g., 0x80000001).  Or, if the constants are put in global variables and cannot be "optimized" at compile time, correct code is generated.
>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]