Good question. I go with -O3 because it does even more optimizations, but to be quite candid I really don't know what impact -fpredictive-commoning, -ftree-vectorize, and others have on my resulting machine code, if any.
I did a quick experiment, compiling one C file with -O2 -finline-functions and another with -O3, using the -S flag so I could see the assembler output.
The only difference I saw was this:
.comm free_list,8,8
Versus this: .comm free_list,8,16
Who knows. I guess I'm really using -O3 because "3 is more than 2" -- in other words, "Ours goes to 11!" :)