Recent

Author Topic: Comparisons with zero  (Read 1751 times)

lagprogramming

  • Full Member
  • ***
  • Posts: 159
Comparisons with zero
« on: November 21, 2015, 11:19:03 am »
variable_in_register=0 and variable_in_register<>0 comparisons are optimized to use "test" instead of "cmp" based on the zero flag. This means we have something like:
Code: Pascal  [Select]
  1. if variable_in_register<>0 then variable_in_register:=0;
  2. testq   %rax,%rax
  3. je      .Lj6
  4. movq    $0,%rax


When comparing for sign, fpc produces the following code:
Code: Pascal  [Select]
  1. if variable_in_register<0 then variable_in_register:=0;
  2. cmpq    $0,%rax
  3. jnl     .Lj6
  4. movq    $0,%rax
When dealing with "<0" and ">=0", I'd like "test" to be used instead of "cmp", too.

I've looked at compiler/i386/popt386.pas and I've seen:
Code: Pascal  [Select]
  1.               A_CMP:
  2.                 begin
  3.                   if (taicpu(p).oper[0]^.typ = top_const) and
  4.                      (taicpu(p).oper[0]^.val = 0) and
  5.                      (taicpu(p).oper[1]^.typ = top_reg) then
  6.                    {change "cmp $0, %reg" to "test %reg, %reg"}
  7.                     begin
  8.                       taicpu(p).opcode := A_TEST;
  9.                       taicpu(p).loadreg(0,taicpu(p).oper[1]^.reg);
  10.                       continue;
  11.                     end;
  12.                 end;
  13.  
So, I've said to myself that the "cmp" should have already been changed with "test". Paying further attention I've noticed that "jnl" would not work with "test" because "jnl" involves the overflow flag.
Now, I'm thinking that maybe if "jnl" would be replaced with "jns" at variable_in_register<0 then the peephole optimizer might do the job.
If I'm on the right track, where do I have to look further?

   P.S. It should be obvious to you that I'm not experienced with compiler internals and I couldn't find documentation regarding how the compiler optimizes the code.