Penso che l'ottimizzazione del compilatore normalmente riduca (sotto) espressioni che dipendono solo dai valori costanti.
Se un'espressione contiene variabili il cui valore è associato in fase di esecuzione, è possibile controllare solo alcune proprietà di base, ad es. quando si confronta un numero intero senza segno con 0, come questo:
unsigned int c;
...
if (c < 0)
{
...
}
D'altra parte, non penso che abbia senso (o che sia anche possibile) che un compilatore cerchi di indagare su proprietà più complesse di un'espressione valide per tutti i possibili input e ottimizzarle in base a ciò. Cosa fare per esempio con:
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";
}
Oltre ai possibili errori di calcolo dovuti a arrotondamenti o overflow, il programma non eseguirà mai il corpo del blocco if (si veda questo articolo di wikipedia per qualche background), ma come dovrebbe un compilatore essere in grado di determinarlo?
I teoremi di dimostrazione (per non dire scoperti) sull'espressione matematica sono troppo complessi (o anche non calcolabili in certi casi) quindi non possono essere usati come tecnica di ottimizzazione del compilatore.