This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/56546] Using the divide operator on unsigned int produces incorrect code on AVR
- From: "gjl at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 07 Mar 2013 22:20:48 +0000
- Subject: [Bug target/56546] Using the divide operator on unsigned int produces incorrect code on AVR
- Auto-submitted: auto-generated
- References: <bug-56546-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56546
Georg-Johann Lay <gjl at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target| |avr
Priority|P3 |P4
Status|UNCONFIRMED |WAITING
Last reconfirmed| |2013-03-07
CC| |gjl at gcc dot gnu.org
Ever Confirmed|0 |1
Severity|critical |normal
--- Comment #1 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2013-03-07 22:20:48 UTC ---
(In reply to comment #0)
> Created attachment 29592 [details]
> Sample code to reproduce the issue
>
> Using the divide integer on unsigned int variables on an AVR target leads to
> wrong code being generated. The generated code uses the __umulhisi3 routine
> from libgcc which is a multiplication routine and the result is always zero.
Can't confirm this using the following, slightly extended test case:
$ avr-gcc-4.7.2 -O0 -mmcu=atmega8 foo.c -o foo.elf
#include <stdlib.h>
int main (void)
{
volatile unsigned int toto = 140;
toto /= 60;
if (toto != 2)
abort();
return 0;
}
The objdump shows that __umulhisi3 is actually called: It computes the high
part of 140 * 0x8889 which is 0x004a. This value is then unsigned-shifted by 5
to the right which is 2. This, in turn, is the expectet result of 140 / 60.
Runing a simulator hits exit (by returning from main).
> [snip unrelated text]workings of gcc, I
>
> I've come up with a very simple source file that allows to reproduce
> the issue.
>
> By the way I couldn't think of any case where transforming a udiv into a mult
> operating on integers would make sense and would be glad if someone could give
> me some hints on this.
AVR has no divide instruction and / 60 is performed by a multiplication and
some adjustment.
> Here's the command line I used:
>
> avr-gcc -O0 -g -Wall -Wextra -save-temps -mmcu=atmega8 -o main.elf main.c
>
> And the version of the toolchain components:
>
> binutils: efb7cff2df30eb792d30e8afc384aa88c193932b
> gcc: ef11013858b41453c4953ca8d4c25e3b1668e536
> avr-libc: 2ac01d285e23894ef3bcc65c75b39da8157b9fd9
These are no versions.
Please show the output of avr-gcc -v.
> gcc-4.7.2, binutils 2.23.1 and avr-libc 1.8.0 give the same result.
Is this an unpatched avr-gcc?