As my colleague Bin Cheng pointed out, this is because the code rely on undefined behavior. Indeed, b_struct is defined as:
struct b_struct
{
uint8_t A[7][6];
};
So a given row of A has only 6 elements. Therefore the first check ((b.A[id][li] & 0x80) == 0) is undefined for li >= 6 and GCC assumes this code is never executed for such values of li. This is why the second condition is removed.
You can tell GCC not to optimize so aggressively by using -faggressive-loop-optimizations.
As my colleague Bin Cheng pointed out, this is because the code rely on undefined behavior. Indeed, b_struct is defined as:
struct b_struct
{
uint8_t A[7][6];
};
So a given row of A has only 6 elements. Therefore the first check ((b.A[id][li] & 0x80) == 0) is undefined for li >= 6 and GCC assumes this code is never executed for such values of li. This is why the second condition is removed.
You can tell GCC not to optimize so aggressively by using -faggressive- loop-optimizati ons.
Best regards.