Operator associativity and 4x4 matrices - performance question During vertex processing with 4x4 matrices, we might stack multiple transformations like projection, model-world, world-camera, etc. by doing something like this:

$$v_{final} = T_N \cdot ... \cdot T_1 \cdot T_0 \cdot v$$

Now from the GLSL specs (section 5.1), I get that the operator associativity is "left to right". So this:

$$v_{final} = T_2 \cdot T_1 \cdot T_0 \cdot v$$

is equivalent to:

$$v_{final} = ((T_2 \cdot T_1) \cdot T_0) \cdot v$$

However, as matrix multiplication is associative, the result does not change if we write:

$$v_{final} = T_2 \cdot (T_1 \cdot (T_0 \cdot v))$$

While both versions yield the same result, the second version should (at least in theory) be much cheaper to compute since it incorporates 3 matrix-vector multiplications while the first version does 2 matrix-matrix multiplications and a final matrix-vector multiplication.

So my question is, does enforcing the order by adding extra parenthesis really boost performance or is the GLSL compiler usually smart enough to figure out, that the order of operations does not matter for the result and he can reorder the executions for performance even though the specs say "left to right" associativity?

Additional Note: 
I specially mentioned 4x4 matrices, because if you use 3x3 matrices or quaternions, you have to use parenthesis anyways because of the addition of the translations.
As Olivier mentioned, it's not safe in general to apply algebraic optimizations to floating-point math, as floating point doesn't actually obey associativity rules due to roundoff error. $(a + b) - b$ will not be equal to $a$, if the intermediate result $(a + b)$ had to be rounded; nor will $a \cdot (b + c)$ be equal to $a \cdot b + a \cdot c$ in general, for the same reason.

That being said, shader compilers are typically very relaxed about floating-point math optimizations. They behave like using -ffast-math on a C++ compiler, where they make various simplifying assumptions—including that algebraic operations are associative—in order to optimize more aggressively. So it's not out of the question that a GLSL compiler could actually make the optimization you describe.

That said, GLSL compilers vary wildly in quality; there is no canonical GLSL compiler, every GPU vendor implements their own (for OpenGL at least—in the case of Vulkan there are a couple standardized options), and who knows what level of optimizations they might or might not apply under various circumstances. If you wish the code to be optimized in a particular way, better to write it explicitly that way.

One other point,


  the second version should (at least in theory) be much cheaper to compute 


It's only cheaper if you're transforming just a single vertex. If you want to transform thousands of vertices by the same matrix, it will be cheaper to multiply all the matrices together up front; then each vertex only needs to be transformed by a single 4×4 matrix instead of several.