Pelles C forum

Pelles C => Bug reports => Topic started by: omolin on October 14, 2026, 12:59:48 PM

Title: Merging 4 byte loads into 32 bit load optimization bug
Post by: omolin on October 14, 2026, 12:59:48 PM
Hi I ran into this problem when optimization was enabled. Without it the code runs fine.
As I'm not x86 assembly fluent that report part is AI generated, but I hope it should be clear what the issue is:

Pelles C 14.50.0 (pocc 14.50.0, polink 14.50.1), Windows 11 x64. Also seen on 13.00.9.
Target /Tx64-coff. Fails at /Ot, /Ox, /Os, /O1 and /O2; correct without /O.

Repro (repro.c):

#include <stdio.h>
#include <stdint.h>
#include <string.h>

static uint32_t get_le32(const uint8_t *f, size_t n)
{
    return (uint32_t)f[n - 4] | ((uint32_t)f[n - 3] << 8) |
           ((uint32_t)f[n - 2] << 16) | ((uint32_t)f[n - 1] << 24);
}

int main(void)
{
    uint8_t buf[64];
    size_t n;
    int bad = 0;
    for (n = 0; n < sizeof buf; n++)
        buf[n] = (uint8_t)(n * 7u + 1u);
    for (n = 4; n <= sizeof buf; n++) {
        uint32_t got = get_le32(buf, n), want;
        memcpy(&want, buf + n - 4, 4);
        if (got != want) { printf("n=%u: got %08X want %08X\n", (unsigned)n, got, want); bad++; }
    }
    printf("%s\n", bad ? "FAIL" : "OK");
    return bad != 0;
}

Build:
  pocc /Tx64-coff /std:C11 /Ze /MT /Ot repro.c
  polink /SUBSYSTEM:CONSOLE /MACHINE:X64 repro.obj

Result:
  without /O : prints OK
  /Ot /Ox /Os /O1 /O2 : "CRT: unhandled exception (main) -- terminating"

Generated code for get_le32 at /Ot (pocc /Tx64-asm):
  add rcx,rdx
  mov rax,4294967292        ; 0x00000000FFFFFFFC
  mov eax,dword [rcx+rax]   ; reads f + n + 4 GB - 4 -> access violation
  ret

Merging the four byte loads into one dword load is fine. The bug is the displacement:
-4 is materialized as the 32-bit value 0xFFFFFFFC zero-extended to 64 bits, instead of
sign-extended (mov rax,-4, or simply dword [rcx+rdx-4]). It looks like the
"n - 4" offset is computed in 32-bit unsigned arithmetic and then widened when the
index is size_t.
Title: Re: Merging 4 byte loads into 32 bit load optimization bug
Post by: TimoVJL on October 14, 2026, 02:08:40 PM
Bug have been since version 11  :(