NO

Author Topic: Compiler optimization bug [Fixed in 8.00 RC 8]  (Read 2881 times)

tfo

  • Guest
Compiler optimization bug [Fixed in 8.00 RC 8]
« on: August 03, 2014, 07:16:29 PM »
Tested with 8.00 RC6 and 7.00 (refresh).

With any of the optimization options, bad code is generated.
With optimization on, gcd returns 0. With optimization off it returns 1, which is the correct result.

Code: [Select]
int gcd(int a, int b)
{
    if(b) return gcd(b,a%b);
    else return a;
}

int main(void)
{
    return gcd(1,1);
}
« Last Edit: March 10, 2015, 04:49:55 AM by tfo »

neo313

  • Guest
Re: Compiler optimization bug
« Reply #1 on: August 03, 2014, 10:43:49 PM »
Using a temp variable removes the bug, when optimizations are present.

Code: [Select]
#include <stdio.h>

int gcd(int a, int b)
{
    if( b != 0 )
{
const int c = a%b ;
return gcd( b , c ) ;
}
    else
{
return a ;
}
}

int main(void)
{
printf("%d\n" , gcd(1,1) ) ;

    return 0 ;
}


Both examples are with optimization, the problem is with the last two mov instructions, otherwise the code is the same.



« Last Edit: August 03, 2014, 10:54:55 PM by neo313 »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Compiler optimization bug
« Reply #2 on: August 04, 2014, 11:31:03 AM »
Very nice the optimization that doesn't recall the sub sparing stack space and speeding-up execution!  :)
The error is the same in the 32 and 64 bits version:
Code: [Select]
;;;;; 32 Bits version
_gcd:
push              ebx
mov               ebx,dword ptr [esp+8]
mov               ecx,dword ptr [esp+C]
50: {
51:     if(b)
L9:
test              ecx,ecx
je                L18
52: return gcd(b,a%b);
mov               eax,ebx
cdq               
idiv              ecx
mov               ecx,edx ;---\
mov               ebx,ecx ;---+----------- WRONG! these instructions must be reversed
jmp               L9
53:     else
54: return a;
L18:
mov               eax,ebx
pop               ebx
ret               
lea               edi,[edi+0]
55: }
Code: [Select]
;;;;;;; 64 bits version
49: int gcd(int a, int b)

gcd:
mov               r8d,ecx
mov               ecx,edx
50: {
51:     if(b)
L5:
test              ecx,ecx
je                L16
52: return gcd(b,a%b);
mov               eax,r8d
cdq               
idiv              ecx
mov               ecx,edx ;---\
mov               r8d,ecx ;---+----------- WRONG! these instructions must be reversed
jmp               L5
53:     else
54: return a;
L16:
mov               eax,r8d
ret               
55: }

EDIT: I'm very tired today, my brain wan't cooperate! I posted two wrong answers in a row!!!  >:(
The problem is the order of the move instructions that reloads the parameters ...  :P
Maybe it's better to check if destination register is a result holding register to define the correct order of data assignement.
« Last Edit: August 04, 2014, 11:52:03 AM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

tfo

  • Guest
Re: Compiler optimization bug
« Reply #3 on: February 12, 2015, 12:46:07 AM »
Not fixed in 8.00 RC7.

tfo

  • Guest
Re: Compiler optimization bug
« Reply #4 on: March 10, 2015, 04:49:18 AM »
Fixed in 8.00 RC8.