shecc icon indicating copy to clipboard operation
shecc copied to clipboard

Improve large structure instances handling

Open DrXiao opened this issue 2 months ago • 0 comments

Description

Currently, shecc cannot correctly handle large structure instances, causing operations such as large structure assignment and passing a large structure instance as a function argument to behave incorrect.

Current Bug

typedef struct {
    int a, b, c, d, e;
} large_struct_t;

void test(large_struct_t s)
{
    printf("test(s) = %d %d %d %d %d\n", s.a, s.b, s.c, s.d, s.e);
}

int main(void)
{
    large_struct_t s;
    s.a = 10;
    s.b = 20;
    s.c = 30;
    s.d = 40;
    s.e = 50;
    printf("s = %d %d %d %d %d\n", s.a, s.b, s.c, s.d, s.e);

    /* Bug 1: assignment is incorrect. */
    large_struct_t s2 = s;
    printf("s2 = %d %d %d %d %d\n", s2.a, s2.b, s2.c, s2.d, s2.e);

    /* Bug 2: pass a large instance as an argument is also incorrect. */
    test(s);
    return 0;
}
$ qemu-arm out/shecc-stage2.elf -o test test.c
$ qemu-arm test
s = 10 20 30 40 50
s2 = 10 0 0 0 0
test(s) = 10 1082129836 1082129828 1082129596 4

Root Cause

One of potential root causes is that the current register allocator lacks proper considerations about "physical storage". Consider the following structure definition in shecc's source code:

typedef struct {
    var_t *var;
    int polluted;
} regfile_t;

shecc uses instances of regfile_t to perform register allocation. Although a register may conceptually hold a variable (var_t), each register on Arm32 and RISC-V can store only a 4 byte object and thus cannot hold large objects.

However, during register allocation, shecc directly assigns each variable to a register even if the variable is a large structure whose size exceeds 4 bytes. Since no additional handling is performed, the code generator ultimately treats every register as if it always stores small objects when generating instructions, which leads to the aforementioned bugs.

DrXiao avatar Nov 22 '25 14:11 DrXiao