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

Inconsistent MIR_BFS results in interp and gen #407

Closed rogerchang23424 closed 3 months ago

rogerchang23424 commented 3 months ago

MIR API sample code:

#include "mir/mir-gen.h"
#include "mir/mir.h"

#include <iostream>

typedef int64_t (*myfunc)();

myfunc make_function_beq_zero(MIR_context_t ctx, bool interp) {
  MIR_module_t m = MIR_new_module (ctx, "m");
  MIR_type_t ret_type = MIR_T_I64;
  MIR_item_t func = MIR_new_func (ctx, "beq_zero_test2", 1, &ret_type, 0);
  MIR_reg_t num = MIR_new_func_reg (ctx, func->u.func, MIR_T_I64, "num");

  MIR_label_t true_label = MIR_new_label (ctx), cont = MIR_new_label (ctx);

  MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_MOV, MIR_new_reg_op (ctx, num), MIR_new_int_op (ctx, 0x1'0000'0000)));

  MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_BFS, MIR_new_label_op (ctx, true_label),
                                            MIR_new_reg_op (ctx, num)));
  MIR_append_insn (ctx, func, MIR_new_ret_insn (ctx, 1, MIR_new_int_op (ctx, 1)));
  MIR_append_insn (ctx, func, true_label);
  MIR_append_insn (ctx, func, MIR_new_ret_insn (ctx, 1, MIR_new_int_op (ctx, 2)));
  MIR_finish_func (ctx);
  MIR_finish_module (ctx);

  MIR_load_module(ctx, m);

  myfunc code;

  if (interp) {
    MIR_link(ctx, MIR_set_interp_interface, nullptr);
    code = reinterpret_cast<myfunc>(func->addr);
  } else {
    MIR_gen_init(ctx);
    MIR_gen_set_optimize_level(ctx, 3);
    MIR_link(ctx, MIR_set_gen_interface, nullptr);
    code = reinterpret_cast<myfunc>(MIR_gen(ctx, func));
    MIR_gen_finish(ctx);
  }

  return code;
}

int main() {
  MIR_context_t ctx = MIR_init();
  myfunc func1 = make_function_beq_zero(ctx, true);
  std::cout << func1() << std::endl;
  func1 = nullptr;
  MIR_finish(ctx);

  MIR_context_t ctx2 = MIR_init();
  myfunc func2 = make_function_beq_zero(ctx2, false);
  std::cout << func2() << std::endl;
  func2 = nullptr;
  MIR_finish(ctx2);
}

Terminal output

2
1

Host: x86-64

vnmakarov commented 3 months ago

Thank you very much for reporting this. The bug was in constant folding of MIR generator. MIR_BTS code was also involved.

I fixed it with https://github.com/vnmakarov/mir/commit/2719bf5d8290eb258938fee5a9b14134ca1e2eb2.

rogerchang23424 commented 3 months ago

Thanks @vnmakarov for fixing the issue.