Tony
Tony

Reputation: 6148

What is the optimization level of `-S` switch to GCC

In this question, I meet the situation that gcc myfile.c -S produce the assembly code that is better than gcc myfile.c -O0 but worse than gcc myfile.c -O1.

At -O0, both loops are generated. At -O1, both loops are optimized out. (Thanks @Raymond Chen for reminder. cited from his comments) (using the -S just optimize one loop out)

I search the Internet and only find this:

-S (cited from Overall options)

Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified.

By default, the assembler file name for a source file is made by replacing the suffix ‘.c’, ‘.i’, etc., with ‘.s’.

Input files that don't require compilation are ignored.

So my question is:

Edit: you can use this site to help you reproduce the problem. Code is in the question I mentioned. ( If you just use -S compiler option(or no compiler option), you can get one loop elision. )

step 1:

Open this site and copy the following code in Code Eidtor.

 #include <stdio.h>
 int main (int argc, char *argv[]) {

   unsigned int j = 10;

   for (; j > -1; --j) {    
      printf("%u", j);
   }
 }

step 2:

Choose g++ 4.8 as compiler. Compiler option is empty.(or -S)

step 3:

You get the first situation. Now, change the j > -1 to j >= -1 and you can see the second.

Upvotes: 0

Views: 422

Answers (2)

nos
nos

Reputation: 229058

With your last edit, it's now somewhat clear what you're actually doing, so:

For the 1. case, j > -1

This can never happen. j is an unsigned int, and -1 converted to an unsigned value will correspond to a value with all bits being set. That's the same as UINT_MAX, and j can never be greater than that. So gcc eliminates the loop, since its condition will always be false

For the 2. case, j >= -1:

This can happen. j can surely become (unsigned int)-1, or UINT_MAX as mentioned above. The loop is not eliminated.

what is exactly the optimization level of -S option when it compile file? (-O0.5?)

The optimization level is controlled with the -O flag. The -S does not impact optimization. The default optimization if no -O flag is given is -O0 (no optimization)

Upvotes: 1

Aaron Digulla
Aaron Digulla

Reputation: 328556

-S doesn't optimize. -O0, on the other hand, disables all and any optimizations, even the default ones.

So the effect that you see is that you're "enabling" the default optimizations if you use just -S.

Use -S with various -O options to see the effect on the assembler code.

EDIT I've been using GCC since about 2.6 (in 1994). I'm pretty sure I remember that in some versions, the compiler would do default optimizations that you could disable with -O0 to debug the compiler (i.e. gcc ... crashes, gcc -O0 ... doesn't crash -> congrats, you found a bug).

But that doesn't seem to be the case here. I get the same assembler output for -S, -O0 and not giving either. So it seems that the simple optimizations (like if(0){} to comment out a code block) are always applied, no matter which optimization level is selected.

Therefore, I'd say is that original statement above:

At -O0, both loops are generated. At -O1, both loops are optimized out. (Thanks @Raymond Chen for reminder. cited from his comments) (using the -S just optimize one loop out)

is not correct to begin with (at least for GCC 4.8.2). The only other alternative is that the GCC version used by the OP (4.8) has a bug when it comes to enabling/disabling optimizer options.

Upvotes: 1

Related Questions