I think compiler optimization normally reduces (sub)expressions that depend on constant values only.
If an expression contains variables whose value is bound at run-time, only some basic properties can be checked, e.g. when comparing an unsigned integer with 0, like this:
unsigned int c;
if (c < 0)
On the other hand, I do not think that it makes sense (or that it is even possible) for a compiler to try and investigate more complex properties of an expression that are valid for all possible inputs and optimize based on that. What to do for example with:
unsigned int a, b, c, n;
std::cin >> a;
std::cin >> b;
std::cin >> c;
std::cin >> n;
if (n > 2 && pow(a, n) + pow(b, n) == pow(c, n))
std::cout << "OK";
Apart from possible computation errors due to rounding or overflow the program will never execute the body of the if block(see this wikipedia article for some background), but how should a compiler be able to determine this?
Proving (let alone discovering) theorems about mathematical expression is too complex (or even not computable in certain cases) so it cannot be used as a compiler optimization technique.