-
-
Notifications
You must be signed in to change notification settings - Fork 46
Open
Description
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:
$ clang a.o -o testThe program partially prints gibberish:
1 2 3 4 5 1776 1872767257If we were to compile the same IR with TB_SYSTEM_WINDOWS, and with the same command, we'd get the following, correct result:
1 2 3 4 5 6 7Metadata
Metadata
Assignees
Labels
No labels