windelbouwman / ppci

A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python
https://ppci.readthedocs.io/en/latest/
BSD 2-Clause "Simplified" License
337 stars 36 forks source link

ppci-cc: wrong IR code for int32_t comparison with 0xffffffff #89

Closed tstreiff closed 4 years ago

tstreiff commented 4 years ago
    int32_t x;
    if (x != 3)
            return 1;
    if (x != 0xffffffff)
            return 1;

For the 1st comparison, a i32 comparison is generated which is correct:

i32 tmp_load_1 = load alloca_addr;
i32 num_2 = 3;
cjmp tmp_load_1 != num_2 ? main_block3 : main_block2;

For the 2nd one, a i32 to i64 cast is generated on x before the comparison is made with 0xffffffff, which is wrong:

i32 tmp_load_4 = load alloca_addr;
i64 typecast_5 = cast tmp_load_4;
i64 num_6 = 4294967295;
cjmp typecast_5 != num_6 ? main_block6 : main_block5;

0xffffffff is a valid constant for an i32, there is no need for the i64 cast.

tstreiff commented 4 years ago

I suspect that this comes from semantics/on_number(). This function tries to determine the smaller integer type able to hold the value of a constant. For this it uses the maximum value possible for each integer type (computed in context/limit_max()) The comparison should be "<=" instead of "<" because the maximum value is part of the value supported by a type. In our case, for 0xffffffff, on_number() returns "long" (64bit) whereas it should return "unsigned int" (32bit). This leads to the erroneous extension from 32bit to 64bit.

tstreiff commented 4 years ago

Tests passed !