This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/65493] New: bug with 64/32 division sign related to various factors (-O3)
- From: "ml-gnubugzilla at worldspot dot net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 20 Mar 2015 13:02:30 +0000
- Subject: [Bug c/65493] New: bug with 64/32 division sign related to various factors (-O3)
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65493
Bug ID: 65493
Summary: bug with 64/32 division sign related to various
factors (-O3)
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: ml-gnubugzilla at worldspot dot net
Hi
Problem with a 64bit/32bit signed division with -O3 and various factors.
I found this weirg bug when using -O3 on various gcc versions.
platform: redhat el6.5 x84_64
tested gcc versions:
4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) target x86: 32 and 64bit (-m32 and -m64)
4.9.0 self compiled, target x86 32 and 64bit
4.8.0 self compiled, target sparc
the code:
#####################
#include<stdint.h>
#include<stdio.h>
void __attribute__ ((noinline)) xLoop16(
int64_t h
, int64_t hInc
, int32_t l
, int32_t lInc
, int nElem
){
for(;nElem>0;nElem-=1) {
{
int32_t x=h/l;
printf(">>%08llx/%08x = %08x \n",h,l,x);
h+=hInc;
l+=lInc;
}
{
int32_t x=h/l;
printf(">>%08llx/%08x = %08x \n",h,l,x);
h+=hInc;
l+=lInc;
}
}
}
int main(){
xLoop16(
0x4337d8c0000LL
, 0x233dcbc8LL
, 0x748974b0L
, 0x08235a18L
, 4
);
}
############################
The good result:
$ gcc test.c -O1 && ./a.out
>>4337d8c0000/748974b0 = 0000093a
>>433a0c9cbc8/7caccec8 = 000008a0
>>433c4079790/84d028e0 = fffff745
>>433e7456358/8cf382f8 = fffff6a6
>>4340a832f20/9516dd10 = fffff5f0
>>4342dc0fae8/9d3a3728 = fffff51b
>>43450fec6b0/a55d9140 = fffff420
>>434743c9278/ad80eb58 = fffff2f4
The bad result: the division result is always positive, it has become an
unsigned division:
$ gcc test.c -O3 && ./a.out
>>4337d8c0000/748974b0 = 0000093a
>>433a0c9cbc8/7caccec8 = 000008a0
>>433c4079790/84d028e0 = 00000819
>>433e7456358/8cf382f8 = 000007a2
>>4340a832f20/9516dd10 = 00000737
>>4342dc0fae8/9d3a3728 = 000006d8
>>43450fec6b0/a55d9140 = 00000682
>>434743c9278/ad80eb58 = 00000634
What changes the result to the good one:
- removing the noinline attribute
- change the for loop:
for(nElem=4;nElem>0;nElem-=1) {
instead of
for(;nElem>0;nElem-=1) {
- there are 2 identical blocks in the loop. removing one gives a good result!