I did some similar experiments myself a long time ago. Something mildly surprising for me at that time was that this got optimized to a single roll instruction: uint32_t roll(uint32_t const x) { return (x > 17); } I haven't managed to make GCC generate a non-constant roll (i.e. (x > (32-c)) ), probably because it couldn't infer that c is in the [0,31] range.
Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
11–20 of 34 posts
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#12This reminds me of something my assembly instructor said in class once (paraphrased): "Once, I was interested in finding out how a C compiler would handle the div instruction. So, I opened up my editor, and wrote this C program: void main () { printf("%f", 14.0 / 3.0); } I compiled it, and took a look at the generated assembly. How many div instructions do you think it used? [Various guesses, mostly "one."] The corre…
I don't spend a lot of time looking at complier outputs, but the optimization is quite obvious in the first case. I don't have a clue how it would optimize it out in the second case though...
[1] Normally you have to declare a function as 'static' to tell the compiler that the function isn't being exported form the compilation unit, since the compiler isn't supposed to be able to tell the difference between function declarations in the .c file itself and function declarations that were included from .h files. But in this case the function is just defined and never declared, so I presume that's the same as a static declaration.
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#13Cost: one sleepless night in college."What do you mean, optimization doesn't just make it faster?!?"
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#14This reminds me of something my assembly instructor said in class once (paraphrased): "Once, I was interested in finding out how a C compiler would handle the div instruction. So, I opened up my editor, and wrote this C program: void main () { printf("%f", 14.0 / 3.0); } I compiled it, and took a look at the generated assembly. How many div instructions do you think it used? [Various guesses, mostly "one."] The corre…
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#15I am surprised at number 3, I would have thought that it would be optimised to x Edit: No. 5 explains why.
Not really; there's no rounding problem with x random aside: gcc usually uses the LEA instruction for this sort of thing, which lets you compute any combination of {1,2,4,8} * x + y + n in one cycle where x and y are registers and n is a constant number. So even with the LEA instruction you can use either lea eax, [eax*2] or lea eax, [eax+eax] to compute this. And so on. I think add eax, eax is most likely what it do…
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#16Earlier quoted context omitted.
I don't spend a lot of time looking at complier outputs, but the optimization is quite obvious in the first case. I don't have a clue how it would optimize it out in the second case though...
In the second case the divide function isn't being exported from the compilation unit and the compiler can tell[1], so the compiler is free to do whatever it wants with the calling convention and in this case it will choose to inline. And once it's inlined finding the correct answer at compile time is still obvious. [1] Normally you have to declare a function as 'static' to tell the compiler that the function isn't b…
You can see this by inspecting the disassembly yourself, you'll see that printf never actually calls divide, and yet the divide function is still defined within the executable output.
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#17Earlier quoted context omitted.
Not really; there's no rounding problem with x random aside: gcc usually uses the LEA instruction for this sort of thing, which lets you compute any combination of {1,2,4,8} * x + y + n in one cycle where x and y are registers and n is a constant number. So even with the LEA instruction you can use either lea eax, [eax*2] or lea eax, [eax+eax] to compute this. And so on. I think add eax, eax is most likely what it do…
x86 has encodings for shifts by 1 that are two bytes, so there's no code size advantage.
I don't know that this is necessarily the reason here, but it's one possible explanation.
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#18I did some similar experiments myself a long time ago. Something mildly surprising for me at that time was that this got optimized to a single roll instruction: uint32_t roll(uint32_t const x) { return (x > 17); } I haven't managed to make GCC generate a non-constant roll (i.e. (x > (32-c)) ), probably because it couldn't infer that c is in the [0,31] range.
What version of GCC are you using? The non-constant case compiles to "roll" as far back as GCC 4.4.
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#19I did some similar experiments myself a long time ago. Something mildly surprising for me at that time was that this got optimized to a single roll instruction: uint32_t roll(uint32_t const x) { return (x > 17); } I haven't managed to make GCC generate a non-constant roll (i.e. (x > (32-c)) ), probably because it couldn't infer that c is in the [0,31] range.
If c were outside that range, the result would be undefined, and the compiler would not need to consider that possibility.
Re: Will It Optimize? See how well you can anticipate gcc's optimizer (2010)
#20This reminds me of something my assembly instructor said in class once (paraphrased): "Once, I was interested in finding out how a C compiler would handle the div instruction. So, I opened up my editor, and wrote this C program: void main () { printf("%f", 14.0 / 3.0); } I compiled it, and took a look at the generated assembly. How many div instructions do you think it used? [Various guesses, mostly "one."] The corre…