Loops and flow control statements in shaders aren't great. Avoid when possible. At best, they will be slow, and at works, they won't work at all (loops).
GPU cores are optimized for mathematical calculations, not logical flow control of programs (loop exit conditions, if statements etc). When you use such constructs in shaders, it really hurts performance and here is why:
Let's look at a trivial hypothetical situation. Imagine you write a fragment shader with a single if statement in the code. That if statement controls whether or not a calculation is performed. The calculation will be carried out 10% of the time.
What happens when you execute a shader pipeline, is that at the driver/hardware level, a "warp" is executed. Warps are a collection of shader kernels (an instance of a shader/gpgpu program) each of which will run on a single core. After these kernels have executed, the memory they operate opon (in this case, a target buffer texture), will have to be memory fenced and synchronized, and wait until all kernels have exited.
90% of the kernels will finish early, having not had to perform our extra calculation, but the remaining 10% will still be working, thus adding a little extra work some of the time will actually reduce performance all the time.
Then you have code branching. On a cpu, when code branching is executed, difference branches of code are run on different cores, with little to no penalty in performance (compilers sort this out for you), but on gpus this sort of branch prediction is not available, and in most cases will result in performance loss. Loops suffer from this problem, because their exit conditions result in code branching upon compilation.
Unroll your loop code, and stick to shaders with a finite predictable scope.