lundi 27 juin 2016

GCC cosine optimization and sigbus


I have a program that writes in some FPGA memory. When the program is compiled with optimizations (either O1, O2 or O3) it crashes with a bus error. However there is no crash when the program is compiled without optimizations.

Here is a minimal example which crashes:

void set_reg(const uint32_t *data)
{
    uint32_t val = data[0];
    dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // crash
}

When I add volatile there is no more crash:

void set_reg(const uint32_t *data)
{
    volatile uint32_t val = data[0];
    dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // no crash
}

If I remove the call to cos there is no problem.

This seems related to GCC: program doesn't work with compilation option -O3. When I add the flag -ffloat-store the program don't crash.

However, on the actual code which is more complicated, adding the flag -ffloat-store doesn't solve the problem.

I don't understand the kind of optimization GCC does and how this leads to a SIGBUS. If anyone could explain that, it would be useful for debugging.

Thank you.


NB:

1) GCC version is arm-linux-gnueabihf-g++ (Ubuntu/Linaro 5.3.1-14ubuntu2) 5.3.1 20160413

2) The function write32 is defined as

void write32(MemMapID id, uint32_t offset, uint32_t value) 
{
    ASSERT_WRITABLE
    *(volatile uintptr_t *) (GetBaseAddr(id) + offset) = value;
}

Aucun commentaire:

Enregistrer un commentaire