Please refer to my code below. When optimization in IAR MSP430 compiler is set high, I am having the following issue. Code works fine when optimization is low.
Issue: If the condition statement at (B) returns false, statement (A) is executed instead of statement (C).
int16_t cpu_flash_read_setting (void * setting, const uint8_t offset, const uint8_t num_of_bytes)
{
int16_t returnable_status = PASS;
uint16_t flash_copy_one_address = FLASH_INFO_SEG_C_ADDR + offset;
uint16_t flash_copy_two_address = FLASH_INFO_SEG_D_ADDR + offset;
if (0U == (num_of_bytes % sizeof(uint16_t)))
{
uint16_t *setting_copy_one = (uint16_t *) flash_copy_one_address;
uint16_t *setting_copy_two = (uint16_t *) flash_copy_two_address;
if (*setting_copy_one == *setting_copy_two)
{
setting = setting_copy_one;
}
else
{
(A) returnable_status = FAIL;
}
}
else if (0U == (num_of_bytes % sizeof(uint8_t)))
{
uint8_t *setting_copy_one = (uint8_t *) flash_copy_one_address;
uint8_t *setting_copy_two = (uint8_t *) flash_copy_two_address;
(B) if (*setting_copy_one == *setting_copy_two)
{
setting = setting_copy_one;
}
else
{
(C) returnable_status = FAIL;
}
}
else
{
/* No Action */
}
return returnable_status;
}
That looks entirely reasonable to me. When you have optimisation turned up high, the compiler can and usually will re-order statements wildly. Your two main clauses are identical apart from their typing – so it’s entirely plausible for the compiler to merge the execution paths and have them differ only where it actually matters.
This is only a problem if the actual observable effect differs from what was intended.
In any event, optimised code is always difficult to follow with a debugger, precisely because of the re-ordering effects.
By the way, if your code is talking to actual hardware you may want to declare the
flash_copy_*_addressvariables asvolatile. This is a hint to the compiler that the memory they point to doesn’t necessarily behave in the normal way, and forces it be more conservative with its optimisations.