Re: Question about MS C code generation (Paolo Bonzini)
3 Dec 2003 20:32:23 -0500

          From comp.compilers

Related articles
Question about MS C code generation (2003-11-21)
Re: Question about MS C code generation (Joachim Durchholz) (2003-12-03)
Re: Question about MS C code generation (2003-12-03)
Re: Question about MS C code generation (2003-12-03)
Re: Question about MS C code generation (2003-12-03)
| List of all articles for this month |

From: (Paolo Bonzini)
Newsgroups: comp.compilers
Date: 3 Dec 2003 20:32:23 -0500
References: 03-11-090
Keywords: code, optimize
Posted-Date: 03 Dec 2003 20:32:22 EST

> if(a<0) b=-5;
> else if(a>=0) b=5;
> else b=0;

I guess that you meant a>0 in the second line.

> [which the compiler rewrites to]
> if(a>=0) {
> if(a<=0) b=0;
> else b=5;
> } else b=-5;

The compiler is only inverting the conditions (either according to
what it thinks the branch probabilities are, or just because it likes
it better this way).

Now, let's look at the second snippet. The compiler is trying to
remove a jump, so it does this:

> xor eax, eax
> cmp [ebp+nA], 0
> setle al

AL = (a <= 0) ? 1 : 0;

> dec eax

AL = (a <= 0) ? 0 : -1;

> and eax, 5

AL = (a <= 0) ? 0 : 5;

that is, AL = (a > 0) ? 5 : 0. As I said, this is a transformation
with which the compiler tries to avoid unnecessary jumps; there are a
number of these hardcoded in the optimizer (in the case of gcc, they
call it "if conversion").

On to the next question:

> mov [ebp+nTmp], ecx
> mov edx, [ebp+nTmp]

Are you using the top optimization level? It does not seem very smart

> 4) if asked, how would you write this program in assembly ?

      xor ecx, ecx ;We need the top 24 bits cleared
      xor edx, edx
      cmp [var], 0
      setg cl ;ECX=1 if EAX>0
      setl dl ;EDX=1 if EAX<0
      sub ecx, edx ;ECX=sign of EAX
      lea [ecx*4+ecx],ecx ;ECX=sign of EAX * -5


      cmp [var], 0
      setg cl ;CL=1 if EAX>0
      setl dl ;DL=1 if EAX<0
      sub cl, dl ;CL=sign of EAX
      movsx ecx, cl ;ECX=sign of EAX
      lea [ecx*4+ecx],ecx ;ECX=sign of EAX * -5

But I do not expect a compiler to recognize this. It corresponds to
another way to express your expression: 5 * ((a > 0) - (a < 0))

Also note that if you need an 8-bit result you can drop the first two
instructions (the XORs), or the MOVSX in the second example.

Finally, if you are testing a register, I'd suggest OR EAX, EAX
instead of a compare with zero (a byte smaller). And if you are on a
PII or later, what about

      xor ecx, ecx
      cmp [var], 0
      cmovl ecx, -5
      cmovg cl, 5

This *is* something I'd expect out of a smart compiler, if told to
generate CMOV instructions.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.