Open Goubermouche opened 9 months ago
Hi, I believe I've discovered a bug in the Linux target, specifically, there seems to be an issue with how function calls with more than 5 parameters behave. I've attached a minimal reproducible example below:
#include "tb/include/tb.h" #define CUIK_USE_TB int main() { TB_FeatureSet features = { 0 }; TB_Module* module = tb_module_create(TB_ARCH_X86_64, TB_SYSTEM_LINUX, &features, false); TB_ModuleSectionHandle text = tb_module_get_text(module); TB_PrototypeParam printf_ret = { TB_TYPE_I32 }; TB_PrototypeParam printf_param = { TB_TYPE_PTR }; // printf TB_External* printf_external = tb_extern_create(module, 7, "printf", TB_EXTERNAL_SO_LOCAL); TB_FunctionPrototype* printf_proto = tb_prototype_create(module, TB_STDCALL, 1, &printf_param, 1, &printf_ret, true); // main TB_PrototypeParam main_ret = { TB_TYPE_I32 }; // main TB_Function* main_f = tb_function_create(module, 5, "main", TB_LINKAGE_PUBLIC); TB_FunctionPrototype* main_prototype = tb_prototype_create(module, TB_STDCALL, 0, NULL, 1, &main_ret, false); tb_function_set_prototype(main_f, text, main_prototype, NULL); TB_Node* params[8] = { tb_inst_string(main_f, 22, "%d %d %d %d %d %d %d\n"), tb_inst_sint(main_f, TB_TYPE_I32, 1), tb_inst_sint(main_f, TB_TYPE_I32, 2), tb_inst_sint(main_f, TB_TYPE_I32, 3), tb_inst_sint(main_f, TB_TYPE_I32, 4), tb_inst_sint(main_f, TB_TYPE_I32, 5), tb_inst_sint(main_f, TB_TYPE_I32, 6), tb_inst_sint(main_f, TB_TYPE_I32, 7) }; tb_inst_call(main_f, printf_proto, tb_inst_get_symbol_address(main_f, (TB_Symbol*)printf_external), 8, params); TB_Node* ret_value = tb_inst_sint(main_f, TB_TYPE_I32, 0); tb_inst_ret(main_f, 1, &ret_value); TB_Passes* p_main = tb_pass_enter(main_f, tb_function_get_arena(main_f)); tb_pass_exit(p_main); TB_ExportBuffer buffer = tb_module_object_export(module, TB_DEBUGFMT_NONE); // copy into file if (!tb_export_buffer_to_file(buffer, "./a.o")) { printf("err\n"); } return 0; }
When we link the generated object file for TB_SYSTEM_LINUX using clang like so:
TB_SYSTEM_LINUX
$ clang a.o -o test
The program partially prints gibberish:
1 2 3 4 5 1776 1872767257
If we were to compile the same IR with TB_SYSTEM_WINDOWS, and with the same command, we'd get the following, correct result:
TB_SYSTEM_WINDOWS
1 2 3 4 5 6 7
Hi, I believe I've discovered a bug in the Linux target, specifically, there seems to be an issue with how function calls with more than 5 parameters behave. I've attached a minimal reproducible example below:
When we link the generated object file for
TB_SYSTEM_LINUX
using clang like so:The program partially prints gibberish:
If we were to compile the same IR with
TB_SYSTEM_WINDOWS
, and with the same command, we'd get the following, correct result: