Consider the following piece of code:

void innermost_loop(int i, double d1, double d2, double delta, int n, double cells[n]) { int j; const double d1d = d1 * delta; const double d2d = d2 * delta; for (j = 0; j <= i; j++) cells[j] = d1d * cells[j + 1] + d2d * cells[j]; }

When compiling at `-Ofast` level, after the "Reassociate expressions"

pass, this code is transformed into an equivalent of:

int j; for (j = 0; j <= i; j++) cells[j] = (d1 * cells[j + 1] + d2 * cells[j]) * delta;

Effectively, the computation of those loop invariants isn't done

before the loop anymore, we have one extra multiplication on each

loop iteration instead. Sadly, this results in a significant

performance hit.

This patch makes the OptimizeAdd() function of the "Reassociate

expressions" pass aware of modifying operations in a loop and

bails out when some of the operands are pulled from the outside

of the loop.