This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Issue with compiler optimization

A customer reported an issue with C-compiler optimization with compiler version 5.1.10.

The attached project works fine with –o0 and –o1. With –o2, the PC does not reach main(). I found it stuck at the call to esmGroup3Notification() in startup function c_int00() in file HL_sys_startup.c. From the attached screenshot, CPU loads the ESM status register value to R12 from address pointed by R4. R4 should have the address of the ESM status register. Instead, it has a value of zero.

In the beginning of c_int_00(), R4 is initialized to 0xfffff520 which is the address of the ESM status register. R4 is changed to zero in the call to assembly function _coreInitRegisters_(). It seems that the compiler does not generate the correct code in this case. I am not sure if there is away for compiler to know what assembly code does. We advised the customer not to use –o2 for the time being. Would you please take a look at this and provide feedback? I think that the –o2 option should not be used when there are assembly code in the project. Would you please comment?

Thanks and regards, MotorController.zip

Zhaohong

  • If an assembly function abc is to be called from a C function, it must obey the C calling convention. For ARM, R4 is a callee-saved register. Function abc must preserve the value of R4. That is, upon exit from function abc, the value of R4 must be the same as at the entry of R4. If function abc does not preserve R4, it may not be called from a C function.
  • In general, I agree to your comments. However, would this behavior be consistent across optimization levels? Is it possible to exclude some files from optimization?

    Thanks and regards,

    Zhaohong
  • The root cause of your problem is that your are initializing your C environment with a function written in C (_c_int00).  That this works at all, even under no optimization, is a matter of luck.  I suspect you are working within an infrastructure constructed by some other team.  That team needs to rewrite the _c_int00 routine in assembly.

    Thanks and regards,

    -George

  • Calling a function that does not adhere to the C calling convention is undefined behavior. There are no guarantees for undefined behavior; the observed behavior may change for any reason in unpredictable ways, including a change in optimization level or whether it's Tuesday.