public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/53916] New: [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option
@ 2012-07-10 16:03 anmin_deng at yahoo dot com.tw
  2012-07-13 11:41 ` [Bug rtl-optimization/53916] " anmin_deng at yahoo dot com.tw
  2013-05-25 16:15 ` rsandifo at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: anmin_deng at yahoo dot com.tw @ 2012-07-10 16:03 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53916

             Bug #: 53916
           Summary: [mips16] divide operation compiled result incorrect
                    with GCC-4.6.3 '-O2' option
    Classification: Unclassified
           Product: gcc
           Version: 4.6.3
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: anmin_deng@yahoo.com.tw


A simple C code with a simple divide operation to have incorrect compile result
with '-O2' option (hence incorrect run time execution result).

The very same C code compile result is OK with '-Os' option.

I have not tested with other version of GCC, the compiler in question is a
cross compiler GCC-4.6.3, target: mips-elf, host/build: i686-pc-cygwin.
Here is the details...


=== full command line options =====
$ /cygdrive/c/Progra~1/vendor/tool-chain4/bin/mipsel-vendor-elf-gcc -mips16
-mips4 -msym32 -membedded-data -muninit-const-in-rodata -mcode-readable=pcrel
-fno-common -msoft-float -EL -ansi -Wall -Wextra -G 0 -O2 -S afvals.c -o
afvals.O2.S -v -save-temps

=== full console output messages =====
Using built-in specs.
COLLECT_GCC=/cygdrive/c/Progra~1/vendor/tool-chain4/bin/mipsel-vendor-elf-gcc
COLLECT_LTO_WRAPPER=/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/4.6.3/lto-wrapper.exe
Target: mipsel-vendor-elf
Configured with: ../gcc-4.6.3/configure NEWLIB_CFLAGS=-D_R3000 LDFLAGS=--static
--prefix='/cygdrive/c/Progra~1/vendor/tool-chain4' --target=mipsel-vendor-elf
--build=i686-pc-cygwin --host=i686-pc-cygwin
--with-sysroot='/cygdrive/c/Progra~1/vendor/tool-chain4' --with-gnu-as
--with-gnu-ld --with-float=hard --disable-threads --with-stabs --disable-nls
--disable-shared --with-newlib --without-headers --disable-biendian
--with-divide=breaks --without-llsc --without-synci --disable-initfini-array
--enable-version-specific-runtime-libs --enable-languages=c,c++
--disable-libssp --disable-libquadmath --disable-libgomp --disable-lto
--disable-add-ons --enable-target-optspace --disable-profile
--disable-nss-crypt --disable-nss --enable-cloog-backend=isl
--with-host-libstdcxx=-Wl,-Bstatic,-lstdc++
Thread model: single
gcc version 4.6.3
COLLECT_GCC_OPTIONS='-mips16' '-mips4' '-msym32' '-membedded-data'
'-muninit-const-in-rodata' '-mcode-readable=pcrel' '-fno-common' '-msoft-float'
'-EL' '-ansi' '-Wall' '-Wextra' '-G' '0' '-O2' '-S' '-o' 'afvals.O2.S' '-v'
'-save-temps' '-mdivide-breaks' '-mno-llsc' '-mno-synci'

/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/4.6.3/cc1.exe
-E -quiet -v -imultilib soft-float afvals.c -G 0 -mel -mips16 -mips4 -msym32
-membedded-data -muninit-const-in-rodata -mcode-readable=pcrel -msoft-float
-mdivide-breaks -mno-llsc -mno-synci -ansi -Wall -Wextra -fno-common -O2
-fpch-preprocess -o afvals.i
ignoring nonexistent directory
"/cygdrive/c/Progra~1/vendor/tool-chain4/usr/local/include"
ignoring nonexistent directory
"/cygdrive/c/Progra~1/vendor/tool-chain4/usr/include"
#include "..." search starts here:
#include <...> search starts here:

/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/include

/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/include-fixed

/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/../../../../mipsel-vendor-elf/include
End of search list.
COLLECT_GCC_OPTIONS='-mips16' '-mips4' '-msym32' '-membedded-data'
'-muninit-const-in-rodata' '-mcode-readable=pcrel' '-fno-common' '-msoft-float'
'-EL' '-ansi' '-Wall' '-Wextra' '-G' '0' '-O2' '-S' '-o' 'afvals.O2.S' '-v'
'-save-temps' '-mdivide-breaks' '-mno-llsc' '-mno-synci'
/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/4.6.3/cc1.exe
-fpreprocessed afvals.i -G 0 -mel -quiet -dumpbase afvals.c -mips16 -mips4
-msym32 -membedded-data -muninit-const-in-rodata -mcode-readable=pcrel
-msoft-float -mdivide-breaks -mno-llsc -mno-synci -auxbase-strip afvals.O2.S
-O2 -Wall -Wextra -ansi -version -fno-common -o afvals.O2.S
GNU C version 4.6.3 (mipsel-vendor-elf)
        compiled by GNU C version 4.5.3, GMP version 5.0.4, MPFR version
3.1.0-p7, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C version 4.6.3 (mipsel-vendor-elf)
        compiled by GNU C version 4.5.3, GMP version 5.0.4, MPFR version
3.1.0-p7, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 301b4a641126d25934d363679c94e6be
COMPILER_PATH=/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/4.6.3/:/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/4.6.3/:/cygdrive/c/Progra~1/vendor/tool-chain4/libexec/gcc/mipsel-vendor-elf/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/../../../../mipsel-vendor-elf/bin/
LIBRARY_PATH=/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/soft-float/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/../../../../mipsel-vendor-elf/lib/soft-float/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/gcc/mipsel-vendor-elf/4.6.3/../../../../mipsel-vendor-elf/lib/:/cygdrive/c/Progra~1/vendor/tool-chain4/lib/
COLLECT_GCC_OPTIONS='-mips16' '-mips4' '-msym32' '-membedded-data'
'-muninit-const-in-rodata' '-mcode-readable=pcrel' '-fno-common' '-msoft-float'
'-EL' '-ansi' '-Wall' '-Wextra' '-G' '0' '-O2' '-S' '-o' 'afvals.O2.S' '-v'
'-save-temps' '-mdivide-breaks' '-mno-llsc' '-mno-synci'


=== file contents of "afvals.i" ====
# 1 "afvals.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "afvals.c"
unsigned short afx = 3;
unsigned short afy = 2;
extern unsigned int afval1[6];
extern unsigned int afval2[6];
unsigned int myarray1[16][16];
unsigned int myarray2[16][16];

void
fs(void)
{
 unsigned short c1;
 for (c1=0; c1<afx*afy; ++c1) {
  unsigned int x, y;
  x = c1 % afx;
  y = c1 / afx;
  myarray1[y][x] = afval1[c1];
  myarray2[y][x] = afval2[c1];
 }
}

=== hints ===
If to use '-Os' option instead of '-O2' option or to insert "__asm__ volatile
("nop");" just after "y = c1 / afx;", the compile result will be OK.

=== The result assembly where I think incorrect ("nl afvals.O2.S") ====
...
    34  $L3:
    35          move    $3,$11
    36          divu    $0,$2,$3
    37          bnez    $3,1f
...
    46          sll     $3,$3,4
    47          move    $6,$9
    48          addu    $3,$3,$6
...
===

1. (major problem) the value of register "$9" is never initialized before line
47.  Run time execution result of this code could be incorrect.

2. (minor issue) the divide operations have type "unsigned short" for both the
operands and are supposed to be integer-promoted to "int".  so the divide
instruction should be 'div' instead of 'divu', no?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug rtl-optimization/53916] [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option
  2012-07-10 16:03 [Bug rtl-optimization/53916] New: [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option anmin_deng at yahoo dot com.tw
@ 2012-07-13 11:41 ` anmin_deng at yahoo dot com.tw
  2013-05-25 16:15 ` rsandifo at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: anmin_deng at yahoo dot com.tw @ 2012-07-13 11:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53916

--- Comment #1 from anmin_deng at yahoo dot com.tw 2012-07-13 11:41:37 UTC ---
I recently tried the very same configurations and codes and tests with
GCC-4.7.1.  It seems that the generated disassemble by GCC-4.7.1 is OK (I have
not yet checked very closely to confirm).

However, the generated results by GCC-4.7.1 with '-O2' and '-Os' are not very
optimal compared to the results by GCC-4.6.3 with '-Os'.  The generated code by
GCC-4.6.3 with '-Os' runs 'divu' instruction once (per loop) and using HI and
LO registers resulted from the same 'divu' as remainder and quotient.  The
generated code by GCC-4.7.1 runs 'divu' instruction twice, one 'divu' for HI
(remainder) and the other 'divu' for LO (quotient).


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug rtl-optimization/53916] [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option
  2012-07-10 16:03 [Bug rtl-optimization/53916] New: [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option anmin_deng at yahoo dot com.tw
  2012-07-13 11:41 ` [Bug rtl-optimization/53916] " anmin_deng at yahoo dot com.tw
@ 2013-05-25 16:15 ` rsandifo at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: rsandifo at gcc dot gnu.org @ 2013-05-25 16:15 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53916

rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |rsandifo at gcc dot gnu.org
         Resolution|---                         |FIXED

--- Comment #2 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> ---
Thanks for the report.  As you say, the bug was fixed in the 4.7 timeframe.
The fix was rather invasive and probably wouldn't be safe to backport to 4.6.

I'm therefore going to treat this bug report as being about the poor
quality of the code produced by 4.7.  This was actually an unintended
consequence of same the fix.

I've just applied a patch to allow the same division to be used once
again for both results:

  http://gcc.gnu.org/ml/gcc-patches/2013-05/msg01568.html

Here too I don't think it's suitable for a backport.  The earliest
candidate would be 4.8.2, but it seems too risky for what by then
would be a relatively mature branch.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-05-25 16:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-10 16:03 [Bug rtl-optimization/53916] New: [mips16] divide operation compiled result incorrect with GCC-4.6.3 '-O2' option anmin_deng at yahoo dot com.tw
2012-07-13 11:41 ` [Bug rtl-optimization/53916] " anmin_deng at yahoo dot com.tw
2013-05-25 16:15 ` rsandifo at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).