vnmakarov / mir

A lightweight JIT compiler based on MIR (Medium Internal Representation) and C11 JIT compiler and interpreter based on MIR
MIT License
2.29k stars 145 forks source link

Different results when using jit and interpreter on optimization level 2 and higher #279

Closed Itay2805 closed 2 years ago

Itay2805 commented 2 years ago

I have found that the following code returns different results between interpreted and non-interpreted code, and specifically on jit with optimization level 2 and higher.

$ ./c2m test.mir -d -eg
  execution       -- 0 msec
exit code: 1
$ ./c2m test.mir -d -ei
  execution       -- 0 msec
exit code: 0
$ ./c2m test.mir -d -O0 -ei
  execution       -- 0 msec
exit code: 0

The offending code:

mod: module

malloc_proto: proto p, i64:size

import malloc

box_nullable_proto: proto p, p, blk0:8(arg0)

box_nullable:   func    p, p, blk0:8(arg0)
    local   i64:exception, i64:si0, i64:sv0, i64:ti0, i64:ti1
# 1 arg, 5 locals
    alloca  sv0, 8
L15:
    mov si0, sv0
    mov i64:(si0), i64:(arg0)
L16:
    mov ti0, si0
    mov si0, 0
    bf  L17, i8:(ti0)
    call    malloc_proto, malloc, si0, 24
    add ti1, si0, 16
    add ti0, ti0, 4
    mov i32:(ti1), i32:(ti0)
L17:
L18:
    mov ti0, si0
    ret 0, ti0
    endfunc

init_nullable_proto: proto p, p:this, i32:arg0

init_nullable:  func    p, p:this, i32:arg0
    local   i64:exception, i64:si0, i64:si1, i64:ti0, i64:ti1
# 2 args, 5 locals
L78:
    mov si0, this
L79:
    mov si1, 1
L80:
    mov ti0, si1
    mov ti1, si0
    mov i8:(ti1), ti0
L81:
    mov si0, this
L82:
    mov si1, arg0
L83:
    mov ti0, si1
    mov ti1, si0
    mov i32:4(ti1), ti0
L84:
    ret 0
    endfunc

main:   func    i32
    local   i64:exception, i64:si0, i64:ti0, i64:sv0
# 0 args, 4 locals
    alloca  sv0, 8
L5:
    mov si0, 123
L6:
    mov ti0, si0
    mov si0, sv0
    mov i64:(si0), 0
    call    init_nullable_proto, init_nullable, exception, si0, ti0
    bf  L7, exception
    ret exception
L7:
L8:
    mov ti0, si0
    call    box_nullable_proto, box_nullable, exception, si0, blk0:8(ti0)
    bf  L9, exception
    ret exception
L9:
L10:
    mov ti0, si0
    bf  L11, ti0
L12:
    mov si0, 0
L13:
    mov ti0, si0
    ret ti0
L11:
    mov si0, 1
L14:
    mov ti0, si0
    ret ti0
    endfunc

endmodule
vnmakarov commented 2 years ago

Thank you for reporting this and sorry for delay with other issues (I was on vacation).

Fixing this bug probably will take some time but I hope to fix this on next week.

I'll provide updates on this issue status.

Itay2805 commented 2 years ago

No worries! Hope you had a nice vacation :)

vnmakarov commented 2 years ago

I've pushed a fix fd737c15a13bca5ad58d502eddaa7239188c30db

The problem was in sparse conditional constant propagation (in incorrect processing call insns as insns having multiple outputs).

Itay2805 commented 2 years ago

Great work!