[llvm-dev] Difference between clang -Oz and opt -Oz

Fāng-ruì Sòng via llvm-dev llvm-dev at lists.llvm.org
Tue Dec 29 13:58:14 PST 2020


On Tue, Dec 29, 2020 at 12:02 PM Fernando Magno Quintao Pereira via
llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
> Dear LLVMers,
>
> Why does opt -Oz and clang -Oz produce different codes? And could
> someone point me to some documentation/discussion that explains the
> differences between them?
>
> Regards,
>
> Fernando
>
> ------------------
>
> Example
> =======
>
> This program below ends up with 74 instructions with opt -Oz, and 22
> instructions with clang -Oz (LLVM 10.0). Opt unrolls the loop 2x,
> whereas clang doesn't:
>
> void prefix_sum(int *src, int *dst, int N) {
>   if (0 < N) {
>     int i = 0;
>     do {
>       int tmp = 0;
>       int j = 0;
>       if (j < i) {
>         do  {
>           tmp += src[j];
>           j++;
>         } while (j < i);
>         dst[i] = tmp;
>       }
>       i++;
>     } while (i < N);
>   }
> }
>
> I can see some optimizations with clang, that might not run with opt when I do:
>
> echo 'int;' | clang -xc -Oz - -o /dev/null -\#\#\#
>
> Would that be the reason for the difference?

clang -fno-legacy-pass-manager -S -emit-llvm -Oz
populates the pipeline with PassBuilder::buildPerModuleDefaultPipeline

If you use
clang -fno-legacy-pass-manager -S -emit-llvm -Oz -Xclang -disable-llvm-passes
opt -S -passes='default<Oz>'
the behavior will be quite similar, though the variable naming will be
different.

---

If you invoke
clang -fno-legacy-pass-manager -S -emit-llvm -O0 -Xclang -disable-llvm-passes
followed by
opt -S -passes='default<Oz>' calls

clang -O0 adds optnone and (for most functions) noinline function attributes.
  (llvm::PassInstrumentation::runBeforePass<llvm::Function, ...> skips
passes if the function has the optnone attribute.)
clang -Oz adds optsize and minsize function attributes.

noinline/optsize/minsize can affect optimization passes' heuristics.


You can drop optnone with
clang -fno-legacy-pass-manager -S -emit-llvm -O0 -Xclang
-disable-O0-optnone -Xclang -disable-llvm-passes
however, noinline is still there. You can use -O1
clang -fno-legacy-pass-manager -S -emit-llvm -O1 -Xclang -disable-llvm-passes
however, there is still a llvm.loop.unroll.disable metadata difference.
clang -fno-legacy-pass-manager -S -emit-llvm -O2 -Xclang -disable-llvm-passes


More information about the llvm-dev mailing list