I'm aware that compilers (for example, clang and gcc), at least with all optimizations flags enabled, do semantic analysis of your loops to see if you are actually implementing some mathematical serie (e.g., sum of an arithmetic progression 1 + 2 + ... + n), and the compiler completely removes the loop and replaces it with its corresponding formula (e.g., n * (n - 1) / 2).
Some months ago I found a clang or llvm documentation page about the different options and techniques use to find and apply these kind of optimization oportunities, but I'm not able to find it again.
So, the question is: what is the name of these kind of loop analysis optimization techniques and how are they actually applied?