I did some more digging, and it seems that the problem is not with a compiler per se, but with assembler. I've compiled the same C source file with -S key (only compile to assembly), and both Win and Linux compilers produced identical assembly code, but assemblers produced different code:
1. Linux assembler implemented addlik r1, -24 as addlik r1, 0xffe8 (this is a twos-complement of -24, which will be sign-extended to 64 bits), while Win assembler implemented it as a pair imml, 0x00ffff/addlik r1, 0xffe8, which is effective command addlik r1, 0x00ffffffe8, which is wrong, but consistent with Win assembler forcing upper 32 bits to zeros
2. Linux assembler implemented addlik r3,r0,8589934592 properly: imml 0x020000/addlik r3, r0, 0x0000 => addlik r3, r0, 0x200000000, which is correct, while Windows assembler implemented it as imml 0/addlik r3, r0, 0x0000 => effective addlik r3, r0, 0. What's interesting here is that it did realize that there is a long immediate involved (hence imml command), but it still zeroed out the upper part of it.
3. Third interesting point is instruction addlik r4,r0,-6172933522750876246, which requires two imml instructions (as each one can only store 24bit value), Linux assembler got this right - it emitted sequence imml 0xaa5555, imml 0xaaaa55, addlik r4, r0, 0x55aa, which is effective addlik r4, r0, 0xaa5555aaaa5555aa, while Windows version emitted only two commands: imml 0xffaa55, addlik r4, r0, 0x55aa, which is effectively means addlik r4, r0, 0xffffffffaa5555aa, as the immediate is sign-extended to 64 bits, which of course produces incorrect result.