public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/51445] New: g++ sometimes miscompiles code for the avr target
@ 2011-12-07  0:33 dhowells at redhat dot com
  2011-12-11 14:08 ` [Bug target/51445] " dhowells at redhat dot com
  2012-02-11 10:55 ` gjl at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: dhowells at redhat dot com @ 2011-12-07  0:33 UTC (permalink / raw)
  To: gcc-bugs

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

             Bug #: 51445
           Summary: g++ sometimes miscompiles code for the avr target
    Classification: Unclassified
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: dhowells@redhat.com


Created attachment 26013
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26013
Test data: Reduced version of w5100.cpp

I'm trying to build stuff for my Arduino board, but the compiler occasionally
clobbers the return value of a function it just called.  This is notable in the
Arduino Ethernet library where the interactions with the W5100 chipset go
interestingly wrong.

Someone pointed me at a fix they'd come up with:

    http://code.google.com/p/arduino/issues/detail?id=605&start=200

whereby they observe the results of two 8-bit function calls are not being
correctly assembled into a 16-bit result in the following code:

    ...
    static uint16_t read##name(SOCKET _s) {                  \
        uint16_t res = readSn(_s, address);                  \
        res = (res << 8) + readSn(_s, address + 1);          \
        return res;                                          \
    }

However, replacing the above with:

    ...
    static uint16_t read##name(SOCKET _s) {                  \
        uint16_t res = readSn(_s, address);                  \
        uint16_t res2 = readSn(_s,address + 1);              \
        res = res << 8;                                      \
        res2 = res2 & 0xFF;                                  \
        res = res | res2;                                    \
        return res;                                          \
    }

Works.  I have also fallen foul of this problem.  They used 4.5.1 of their gcc,
I'm using 4.6.1:

Using built-in specs.
COLLECT_GCC=/usr/bin/avr-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/avr/4.6.1/lto-wrapper
Target: avr
Configured with: ../gcc-4.6.1/configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --target=avr --enable-languages=c,c++ --disable-nls
--disable-libssp --with-system-zlib --enable-version-specific-runtime-libs
--with-pkgversion='Fedora 4.6.1-3.fc16'
--with-bugurl=https://bugzilla.redhat.com/
Thread model: single
gcc version 4.6.1 (Fedora 4.6.1-3.fc16) 

obtained by download from the Fedora 16 yum repository.  The associated
binutils is:

avr-binutils-2.20-2.fc16.x86_64

I've had a colleague build my testcase on a Debian system using the binary
packages available there and the resulting binary from that misbehaves in the
same way as building on Fedora.

Compiling the attached testcase file with the following command:

avr-gcc -g -Os -w -mmcu=atmega328p -ffunction-sections -fdata-sections -o tmp.o
-c tmp.cpp

and then disassembling the resulting object file:

avr-objdump -C -d tmp.o | less

I see that the W5100Class::send_data_processing() method incorrectly clobbers
the result of the first call to W5100Class::readSn() as made by
W5100::readSnTX_WR():

  26:   0e 94 00 00     call    0       ; 0x0
<W5100Class::send_data_processing(unsigned char, unsigned char*, unsigned int)>
  2a:   81 2f           mov     r24, r17
  2c:   65 e2           ldi     r22, 0x25       ; 37
  2e:   70 e0           ldi     r23, 0x00       ; 0
  30:   0e 94 00 00     call    0       ; 0x0
<W5100Class::send_data_processing(unsigned char, unsigned char*, unsigned int)>

The problem, if I understand the calling convention correctly, is that the
function returns its result in R24 - but this is being clobbered by the very
next instruction which overwrites it with the contents of R17 (the destination
register is supposed to be on the left).

I can't seem to remove much else from the test case without the problem going
away (snip off the implementation of W5100Class::execCmdSn() for example).

Also, there's a #if in testcase.  Flip the condition from 1 to 0 and the
resulting code is markedly different:

  24:   0e 94 00 00     call    0       ; 0x0
<W5100Class::send_data_processing(unsigned char, unsigned char*, unsigned int)>
  28:   e8 2e           mov     r14, r24
  2a:   81 2f           mov     r24, r17
  2c:   65 e2           ldi     r22, 0x25       ; 37
  2e:   70 e0           ldi     r23, 0x00       ; 0
  30:   0e 94 00 00     call    0       ; 0x0
<W5100Class::send_data_processing(unsigned char, unsigned char*, unsigned int)>

As can be seen, an extra line has appeared after the first CALL instruction,
saving the result of that call into R14 before copying R17 into R24.


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

* [Bug target/51445] g++ sometimes miscompiles code for the avr target
  2011-12-07  0:33 [Bug c++/51445] New: g++ sometimes miscompiles code for the avr target dhowells at redhat dot com
@ 2011-12-11 14:08 ` dhowells at redhat dot com
  2012-02-11 10:55 ` gjl at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: dhowells at redhat dot com @ 2011-12-11 14:08 UTC (permalink / raw)
  To: gcc-bugs

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

dhowells@redhat.com <dhowells at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |FIXED

--- Comment #1 from dhowells at redhat dot com <dhowells at redhat dot com> 2011-12-11 13:56:37 UTC ---
The problem appears to be fixed in gcc-4.6.2.


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

* [Bug target/51445] g++ sometimes miscompiles code for the avr target
  2011-12-07  0:33 [Bug c++/51445] New: g++ sometimes miscompiles code for the avr target dhowells at redhat dot com
  2011-12-11 14:08 ` [Bug target/51445] " dhowells at redhat dot com
@ 2012-02-11 10:55 ` gjl at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: gjl at gcc dot gnu.org @ 2012-02-11 10:55 UTC (permalink / raw)
  To: gcc-bugs

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

Georg-Johann Lay <gjl at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |gjl at gcc dot gnu.org
         Resolution|FIXED                       |DUPLICATE

--- Comment #2 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2012-02-11 10:54:54 UTC ---


*** This bug has been marked as a duplicate of bug 46779 ***


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

end of thread, other threads:[~2012-02-11 10:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-07  0:33 [Bug c++/51445] New: g++ sometimes miscompiles code for the avr target dhowells at redhat dot com
2011-12-11 14:08 ` [Bug target/51445] " dhowells at redhat dot com
2012-02-11 10:55 ` gjl 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).