Pelles C forum

Pelles C => Bug reports => Topic started by: ander_cc on April 14, 2026, 03:38:30 PM

Title: Maybe a optimization bug.
Post by: ander_cc on April 14, 2026, 03:38:30 PM
Today, I showed a sample code about while statement to my students. But got a error result. :-[
I think it might be a bug related to optimization. Because when I close optimization, I can get the right value.

Pelles C v14, Windows 11 pro Chinese (Samplify) 25H2
1.png
Title: Re: Maybe a optimization bug.
Post by: John Z on April 14, 2026, 04:43:36 PM
Hi ander_cc,

A good lesson there similar to a lawyers credo "In Court don't ask a question if you don't already know the answer"  the corollary to teaching, esp programing, is "In classroom don't use an example you haven't tested"  :)  (half kidding you, no offense meant)

But seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these.  I have many programs using optimizations successfully.

Perhaps Pelle can find the cause of this short program, meanwhile

Your program can use optimizations by using this 'fix':

volatile int i=1;

which, as I understand it inhibits the optimizer from making assumptions about i.

John Z

As an aside I would recommend not using any optimizations for teaching.  Optimizing should be performed by the students learning programing.

Cheers,
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 14, 2026, 06:06:04 PM
Compiling the code with the maximize speed option :

#include <stdio.h>

int main(void)
{
    int i=1, sum=0;
    while (i<=100)
    {
        //printf("i=%d\n",i);
        sum=sum+i;
        i++;
    }
    printf("i=%d\n",i);
    printf("sum=%d\n",sum);
    return 0;
}

Disassembling the object module :

_text  SEGMENT PARA 'CODE'                            ; section number 1

main    PROC
        sub    rsp, 40                                ; 0000 _ 48: 83. EC, 28
        lea    rcx, [@152]                            ; 0004 _ 48: 8D. 0D, 00000000(rel)
        call    printf                                  ; 000B _ E8, 00000000(rel)
        lea    rcx, [@154]                            ; 0010 _ 48: 8D. 0D, 00000000(rel)
        mov    edx, 5050                              ; 0017 _ BA, 000013BA
        call    printf                                  ; 001C _ E8, 00000000(rel)
        xor    eax, eax                                ; 0021 _ 31. C0
        add    rsp, 40                                ; 0023 _ 48: 83. C4, 28
        ret                                            ; 0027 _ C3
main    ENDP

_text  ENDS

.xdata  SEGMENT ALIGN(8) 'CONST'                        ; section number 3

..?xdatasym1 label byte
        db 01H, 04H, 01H, 00H, 04H, 42H, 00H, 00H      ; 0000 _ .....B..

.xdata  ENDS

.rdata  SEGMENT PARA 'CONST'                            ; section number 4

@154    label byte
        db 73H, 75H, 6DH, 3DH, 25H, 64H, 0AH, 00H      ; 0000 _ sum=%d..

@152    label byte
        db 69H, 3DH, 25H, 64H, 0AH, 00H                ; 0008 _ i=%d..

.rdata  ENDS

The first printf call should take a second parameter, edx pointint the value of i. Since this statement is missing, printf will print the random value stored by the register edx.
Title: Re: Maybe a optimization bug.
Post by: TimoVJL on April 14, 2026, 07:41:26 PM
For small tests quick look with podump.exe

Disasm obj Add-In (https://forum.pellesc.de/index.php?msg=26516)
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 14, 2026, 08:37:49 PM
Hi Timo,

Here is the output of Podump :

\PellesC\bin\podump.exe /DISASM output\sum.obj
sub               rsp,28
lea               rcx,[@152]
call              printf
lea               rcx,[@154]
mov               edx,13BA
call              printf
xor               eax,eax
add               rsp,28
ret
Title: Re: Maybe a optimization bug.
Post by: ander_cc on April 15, 2026, 05:09:23 AM
Quote from: John Z on April 14, 2026, 04:43:36 PMHi ander_cc,

A good lesson there similar to a lawyers credo "In Court don't ask a question if you don't already know the answer"  the corollary to teaching, esp programing, is "In classroom don't use an example you haven't tested"  :)  (half kidding you, no offense meant)

But seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these.  I have many programs using optimizations successfully.

Perhaps Pelle can find the cause of this short program, meanwhile

Your program can use optimizations by using this 'fix':

volatile int i=1;

which, as I understand it inhibits the optimizer from making assumptions about i.

John Z

As an aside I would recommend not using any optimizations for teaching.  Optimizing should be performed by the students learning programing.

Cheers,
Yes, It really embarrassed me at that time. I realized I had forgotten to turn off the optimization. Then I explained the reason to my students, and turned off optimization to test the code again, and used gcc -o2 to test the code again.
Title: Re: Maybe a optimization bug.
Post by: TimoVJL on April 15, 2026, 07:55:56 AM
from Clang
main:
00000000  4883EC28                sub rsp, 28h
00000004  488D0D00000000          lea rcx, [??_C@_05BKKKKIID@i?$DN?$CFd?6?$AA@]
0000000B  BA65000000              mov edx, 65h
00000010  E800000000              call printf
00000015  488D0D00000000          lea rcx, [??_C@_07MJFEPNKA@sum?$DN?$CFd?6?$AA@]
0000001C  BABA130000              mov edx, 13BAh
00000021  E800000000              call printf
00000026  31C0                    xor eax, eax
00000028  4883C428                add rsp, 28h
0000002C  C3                      ret
As Vortex mentioned, this was missingmov edx, 65h
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 15, 2026, 10:35:59 AM
By the way, uncommenting the line below will output the correct result :

printf("i=%d\n",i);
#include <stdio.h>

int main(void)
{
    int i=1, sum=0;
    while (i<=100)
    {
        printf("i=%d\n",i);
        sum=sum+i;
        i++;
    }
    printf("i=%d\n",i);
    printf("sum=%d\n",sum);
    return 0;
}
Title: Re: Maybe a optimization bug.
Post by: TimoVJL on April 15, 2026, 12:35:08 PM
For all bug hunters, use pope.exe to check obj-file, as it have internal disassembler.
Title: Re: Maybe a optimization bug.
Post by: John Z on April 15, 2026, 01:57:27 PM
Quote from: Vortex on April 15, 2026, 10:35:59 AMBy the way, uncommenting the line below will output the correct result :

Very typical in my experience for the optimization failures.  Sometimes even just a 1 byte change can make it work, or make it fail.

John Z
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 15, 2026, 10:00:46 PM
The trick i=i-(-1); seems to solve the issue :

#include <stdio.h>

int main(void)
{
int i=1, sum=0;
while (i<=100)
{
sum=sum+i;
//i++;
i=i-(-1);
}
printf("i=%d\n",i);
printf("sum=%d\n",sum);
return 0;
}
Title: Re: Maybe a optimization bug.
Post by: TimoVJL on April 16, 2026, 06:04:07 PM
It might be a cdecl problem, so 32-bit programs can use stdcall to avoid it.
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 16, 2026, 09:13:41 PM
Disassembling the 32-bit MS COFF object module, building the project as 32-bit console application :

_text   SEGMENT PARA PUBLIC 'CODE'

_main   PROC NEAR
        push    eax
        push    offset @152
        call    _printf                               
        add     esp, 8     
        push    5050                                   
        push    offset @154                           
        call    _printf                               
        add     esp, 8                                 
        xor     eax, eax                               
        ret                                           
_main   ENDP

.rdata  SEGMENT DWORD PUBLIC 'CONST'               

@154    label byte
        db 73H, 75H, 6DH, 3DH, 25H, 64H, 0AH, 00H       ; 0000 _ sum=%d..

@152    label byte
        db 69H, 3DH, 25H, 64H, 0AH, 00H                 ; 0008 _ i=%d..

.rdata  ENDS
Title: Re: Maybe a optimization bug.
Post by: Pelle on April 18, 2026, 05:48:32 PM
A sanity check is missing in the loop idiom optimizer: triangular numbers. This affects all targets. We'll see when I can fix this...

/* The triangular numbers are given by the following formula:
 * Tn = 1 + 2 + 3 + .. + n = (n * (n + 1)) / 2
 */
Title: Re: Maybe a optimization bug.
Post by: Pelle on April 18, 2026, 05:52:29 PM
Quote from: John Z on April 14, 2026, 04:43:36 PMBut seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these.  I have many programs using optimizations successfully.
I my experience, enabling the optimizer on poorly written C code is more of a problem than the optimizer itself.
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 19, 2026, 09:59:44 PM
Hi Pelle,

This code below outputs the correct result. Tested with Pelles C v14 :

#include <stdio.h>

int main(void)
{
    int i;
    int s=0;
    for (i=1;i<11;i++)
    {
        s=s+i;
    }
    printf("Sum = %d\n",s);
    return 0;
}

Sum = 55
Optimizations : Maximize speed
Title: Re: Maybe a optimization bug.
Post by: John Z on April 19, 2026, 10:57:46 PM

Are you sure because adding the print of i to check shows maybe not-
If i becomes corrupt but it is not looked at - is it really corrupt  ;D
Schrödinger's cat according to quantum theory, i is simultaneously good and bad until viewed
 ;)

#include <stdio.h>

int main(void)
{
    int i;
    int s=0;
    for (i=1;i<11;i++)
    {
        s=s+i;
    }
    printf("i = %d\n",i);
    printf("Sum = %d\n",s);
    return 0;
}

This also appears to be OK as long as not looking at the value of i -
#include <stdio.h>

int main(void)
{
    int i = 1;
    int s = 0;
   
    do {
        s = s + i;
        i++;
    } while (i <= 10);
    printf("i = %d\n", i);
    printf("Sum = %d\n", s);
    return 0;
}

using volatile int i has 'fixed' it every time...

John Z
Title: Re: Maybe a optimization bug.
Post by: John Z on April 19, 2026, 11:13:12 PM
Quote from: Pelle on April 18, 2026, 05:52:29 PMI my experience, enabling the optimizer on poorly written C code is more of a problem than the optimizer itself.

I agree with this also. In general I am seeing less and less issues as I program more...

John Z
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 20, 2026, 12:55:52 PM
I was too fast, same issue :

_text   SEGMENT PARA 'CODE'

main    PROC
        sub     rsp, 40
        lea     rcx, [@154]
        call    printf    
        lea     rcx, [@156]
        mov     edx, 55   
        call    printf    
        xor     eax, eax  
        add     rsp, 40   
        ret               
main    ENDP

_text   ENDS

.rdata  SEGMENT PARA 'CONST'                          

@156    label byte
        db 53H, 75H, 6DH, 20H, 3DH, 20H, 25H, 64H       ; 0000 _ Sum = %d
        db 0AH, 00H                                  

@154    label byte
        db 69H, 20H, 3DH, 20H, 25H, 64H, 0AH, 00H       ; 000A _ i = %d..

.rdata  ENDS

Again, this line is fixing the issue :

    for (i=1;i<11;i=i-(-1))
Title: Re: Maybe a optimization bug.
Post by: John Z on April 20, 2026, 01:59:47 PM
Many variations can complicate the use of i enough that the optimizer does not affect i.

Both of these variations within the loop also 'work' to inhibit the optimization -
s = s + (i*i)/i;
and
s = s + ((i << 1) >> 1);

We can probably find more too, but I'm fairly sure this is not helping -

#include <stdio.h>

int main(void)
{
    int i = 1;
    int s = 0;

    do {
        //s = s + (i*i)/i;         // works
          s = s + ((i << 1) >> 1); // works
        i++;   
    } while (i <= 10);
    printf("i = %d\n", i);
    printf("Sum = %d\n", s);
    return 0;
}

Another 'working' version
#include <stdio.h>

int main(void)
{
    int i = 0;
    int s = 0;

    do {
++i;
s = s + i;
       } while (i <= 9);
    printf("i = %d\n", i);
    printf("Sum = %d\n", s);
    return 0;
}

John Z
Title: Re: Maybe a optimization bug.
Post by: TimoVJL on April 20, 2026, 10:09:30 PM
Hi John Z, have a fun with Clang with limits with optimizations.
Optimizations for static code isn't so important and you know reasons for that.
Title: Re: Maybe a optimization bug.
Post by: Vortex on April 20, 2026, 10:53:43 PM
The code below compiled as 32-bit application works fine :

#include <stdio.h>

int main(void)
{
    int i;
    int s=0;
    for (i=1;i<11;)
    {
s=s+i;
__asm inc i;
    }
    printf("i=%d , sum = %d\n",i,s);
    return 0;
}

i=11 , sum = 55