Fix if (x < 8) being broken:

During the backporting effort this passed unnoticed. This part of TCC
converts this:

   if x < 8:

To something like:

    if x < 8:
       x <-- 1
    else:
       x <-- 0
    if x set?

This is done for several reasons: the case of a large constant, to stay
compatible with architectures that use flags for comparison and so on.

In RISC-V we had:

    if ( x < 8 )

Converted to:

  28:	 slti	a0,a0,8             // set a0 to 1 if a0 < 8
  2c:	 bltz	a0,34 <main+0x34>   // branch if a0 less than zero
  30:	 j	3c <main+0x3c>      // jump over the `true` case
  34:    ...                        // the `true` case of the if
  ...
  3c

This assembly is wrong, because a0 is never less than zero. This
happened because the applied comparison is the one that was in the `if`
clause *before* the conversion happened: a < 8 => less than.

It wasn't comparing against 8 anymore though because the code that
assigned the operands was working correctly, comparing against 0: which
is the value you have to compare the flags against in order to know if
they are set or not.

The problem in the code was that after making the conversion, the
pending comparison operator was not updated to the case of comparing
against the flag. That happened because the code was re-setting
`vtop->c.i` to op (which already was there) instead of changing it for
the future operation: check if the flag is not equal to zero => TOK_NE
(NE means not-equal).

After this commit this is the result of the compilation:

  28:	slti	a0,a0,8             // set a0 to 1 if a0 < 8
  2c:	bnez	a0,34 <main+0x34>   // branch if not equal to zero
  30:	j	3c <main+0x3c>      // same as before ...
  ...

So now it is correctly checking against the flag.
This commit is contained in:
Ekaitz 2023-10-06 01:33:52 +02:00
parent f636cf3d48
commit 5a0ef8d062
1 changed files with 1 additions and 1 deletions

View File

@ -1147,7 +1147,7 @@ static void gen_opil(int op, int ll)
--vtop;
if (op >= TOK_ULT && op <= TOK_GT) {
vtop->r = VT_CMP;
vtop->c.i = op;
vtop->c.i = TOK_NE;
vtop->cmp_r = ireg(d) | 0 << 8;
} else
vtop[0].r = d;