It is easy to see that:
(i % 3 == 0) && (i % 5 == 0)
Can be simplified to:
(i % 15 == 0)
Yet looking into the output of GCC, it seems this is not done even at high optimisation levels.
Do any compilers do these sorts of optimisations, or is there a good reason why those two tests are not semantically equivalent?
Edit: In response to those who say this is a fringe case, the following is a similar case:
(i < 3) && (i < 5)
Any number less than 3, must always be less than 5. Second test is redundant.
I would also like to add the following in response to the answer that the compiler cannot know if the environment is affected… Look at this code:
void foo(void)
{
int i;
for (i = 0; i <= 10; i++)
{
if (i > 20)
{
puts("Hi");
}
}
}
Whole function is reduced to “repz ret” by GCC with -O2. That is far more complex than anything I am talking about.
Ignore all the silly answers claiming this is terribly difficult/impossible for a compiler to do. I see no reason why it would be difficult, but presumably either nobody thought of doing it or thought it would be sufficiently important to optimize. If you want a better answer than this you’ll need to report it on the GCC bug tracker as a request for enhancement and see what the developers say.