diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 1fa106ee4..4da2c6c3d 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -51,17 +51,15 @@ static void diagnostics_handler(LLVMDiagnosticInfoRef ref, void *context) bool module_should_weaken(Module *module) { - return str_eq("std", module->top_module->name->module); + Module *top = module->top_module; + return top && top->name->module == kw_std; } static void gencontext_init(GenContext *context, Module *module, LLVMContextRef shared_context) { assert(LLVMIsMultithreaded()); memset(context, 0, sizeof(GenContext)); - if (compiler.build.type == TARGET_TYPE_DYNAMIC_LIB || compiler.build.type == TARGET_TYPE_STATIC_LIB) - { - context->weaken = module_should_weaken(module); - } + context->weaken = module_should_weaken(module); if (shared_context) { @@ -131,8 +129,7 @@ LLVMValueRef llvm_get_selector(GenContext *c, const char *name) LLVMValueRef selector = llvm_add_global_raw(c, sel_name, char_array_type, 0); LLVMSetGlobalConstant(selector, 1); LLVMSetInitializer(selector, llvm_get_zstring(c, name, name_len)); - LLVMSetLinkage(selector, LLVMLinkOnceODRLinkage); - llvm_set_comdat(c, selector); + llvm_set_selector_linkage(c, selector); return selector; } @@ -469,16 +466,76 @@ void llvm_set_global_tls(Decl *decl) LLVMSetThreadLocalMode(optional_ref, thread_local_mode); } } + +static void llvm_set_weak(GenContext *c, LLVMValueRef global) +{ + LLVMSetLinkage(global, LLVMWeakAnyLinkage); + LLVMSetVisibility(global, LLVMDefaultVisibility); + llvm_set_comdat(c, global); +} + +static void llvm_set_external_reference(GenContext *c, LLVMValueRef ref, bool is_weak) +{ + LLVMSetLinkage(ref, is_weak ? LLVMExternalWeakLinkage : LLVMExternalLinkage); + LLVMSetVisibility(ref, LLVMDefaultVisibility); +} + +void llvm_set_decl_linkage(GenContext *c, Decl *decl) +{ + bool is_var = decl->decl_kind == DECL_VAR; + bool is_weak = decl->is_weak; + bool should_weaken = is_weak || (!decl->is_extern && module_should_weaken(decl->unit->module)); + LLVMValueRef ref = decl->backend_ref; + LLVMValueRef opt_ref = is_var ? decl->var.optional_ref : NULL; + bool is_static = is_var && decl->var.is_static; + // Static variables in a different modules should be copied to the current module. + bool same_module = is_static || decl->unit->module == c->code_module; + if (decl->is_extern || !same_module) + { + llvm_set_external_reference(c, ref, should_weaken); + if (opt_ref) llvm_set_external_reference(c, opt_ref, should_weaken); + return; + } + if (decl_is_externally_visible(decl) && !is_static) + { + if (decl->is_export && compiler.platform.os == OS_TYPE_WIN32 && !compiler.build.win.def && decl->name != kw_main && decl->name != kw_mainstub) + { + LLVMSetDLLStorageClass(ref, LLVMDLLExportStorageClass); + } + if (is_weak) + { + llvm_set_weak(c, ref); + if (opt_ref) llvm_set_weak(c, opt_ref); + return; + } + if (should_weaken) + { + llvm_set_linkonce(c, ref); + if (opt_ref) llvm_set_linkonce(c, opt_ref); + return; + } + LLVMSetVisibility(ref, LLVMDefaultVisibility); + if (opt_ref) LLVMSetVisibility(opt_ref, LLVMDefaultVisibility); + return; + } + + LLVMSetLinkage(ref, decl->is_weak ? LLVMLinkerPrivateWeakLinkage : LLVMInternalLinkage); + if (opt_ref) LLVMSetLinkage(opt_ref, LLVMInternalLinkage); +} + void llvm_set_internal_linkage(LLVMValueRef alloc) { LLVMSetLinkage(alloc, LLVMInternalLinkage); LLVMSetVisibility(alloc, LLVMDefaultVisibility); } -void llvm_set_private_linkage(LLVMValueRef alloc) + +void llvm_set_private_declaration(LLVMValueRef alloc) { LLVMSetLinkage(alloc, LLVMPrivateLinkage); LLVMSetVisibility(alloc, LLVMDefaultVisibility); + LLVMSetUnnamedAddress(alloc, LLVMGlobalUnnamedAddr); } + void llvm_emit_global_variable_init(GenContext *c, Decl *decl) { assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST || decl->var.is_static); @@ -587,27 +644,6 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl) LLVMSetGlobalConstant(global_ref, decl->var.kind == VARDECL_CONST); - if (decl->is_extern) - { - LLVMSetLinkage(global_ref, LLVMExternalLinkage); - if (optional_ref) LLVMSetLinkage(optional_ref, LLVMExternalLinkage); - } - else if (decl_is_externally_visible(decl) && !decl->var.is_static) - { - LLVMSetVisibility(global_ref, LLVMDefaultVisibility); - if (c->weaken) llvm_set_linkonce(c, global_ref); - if (optional_ref) - { - if (c->weaken) llvm_set_linkonce(c, optional_ref); - LLVMSetVisibility(optional_ref, LLVMDefaultVisibility); - } - } - else - { - LLVMSetLinkage(global_ref, LLVMInternalLinkage); - if (optional_ref) LLVMSetLinkage(optional_ref, LLVMInternalLinkage); - } - decl->backend_ref = global_ref; if (old) { @@ -615,6 +651,8 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl) LLVMDeleteGlobal(old); } + llvm_set_decl_linkage(c, decl); + } static void gencontext_verify_ir(GenContext *context) { @@ -882,21 +920,22 @@ void llvm_set_comdat(GenContext *c, LLVMValueRef global) LLVMSetComdat(global, comdat); } -void llvm_set_linkonce(GenContext *c, LLVMValueRef global) +void llvm_set_selector_linkage(GenContext *c, LLVMValueRef selector) { - LLVMSetLinkage(global, LLVMLinkOnceAnyLinkage); - LLVMSetVisibility(global, LLVMDefaultVisibility); - llvm_set_comdat(c, global); + LLVMSetVisibility(selector, LLVMDefaultVisibility); + LLVMSetLinkage(selector, LLVMLinkOnceODRLinkage); + llvm_set_comdat(c, selector); } -void llvm_set_weak(GenContext *c, LLVMValueRef global) +void llvm_set_linkonce(GenContext *c, LLVMValueRef global) { - LLVMSetLinkage(global, LLVMWeakAnyLinkage); + LLVMSetLinkage(global, LLVMLinkOnceAnyLinkage); LLVMSetVisibility(global, LLVMDefaultVisibility); llvm_set_comdat(c, global); } + void llvm_value_set_int(GenContext *c, BEValue *value, Type *type, uint64_t i) { llvm_value_set(value, llvm_const_int(c, type, i), type); @@ -1070,10 +1109,6 @@ void llvm_add_global_decl(GenContext *c, Decl *decl) scratch_buffer_set_extern_decl_name(decl, true); decl->backend_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), type, decl->alignment); } - if (!same_module) - { - LLVMSetLinkage(decl->backend_ref, LLVMExternalLinkage); - } if (decl->var.kind == VARDECL_CONST) { LLVMSetGlobalConstant(decl->backend_ref, true); @@ -1085,6 +1120,7 @@ void llvm_add_global_decl(GenContext *c, Decl *decl) scratch_buffer_append(".f"); decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0); } + llvm_set_decl_linkage(c, decl); llvm_set_global_tls(decl); } @@ -1254,10 +1290,6 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) } assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST); llvm_add_global_decl(c, decl); - if (decl->is_export && compiler.platform.os == OS_TYPE_WIN32 && !compiler.build.win.def) - { - LLVMSetDLLStorageClass(decl->backend_ref, LLVMDLLExportStorageClass); - } return decl->backend_ref; case DECL_FUNC: if (decl->func_decl.attr_interface_method) @@ -1275,15 +1307,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) backend_ref = decl->backend_ref = LLVMAddFunction(c->module, scratch_buffer_to_string(), type); } llvm_append_function_attributes(c, decl); - if (decl->is_export && compiler.platform.os == OS_TYPE_WIN32 && !compiler.build.win.def && decl->name != kw_main && decl->name != kw_mainstub) - { - LLVMSetDLLStorageClass(backend_ref, LLVMDLLExportStorageClass); - } - if (decl_is_local(decl)) - { - assert(decl->unit->module == c->code_module); - llvm_set_internal_linkage(backend_ref); - } + llvm_set_decl_linkage(c, decl); return backend_ref; case DECL_DEFINE: return llvm_get_ref(c, decl->define_decl.alias); diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 1d985e26f..5f9f67992 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -1730,8 +1730,7 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, AlignSize alignment = type_alloca_alignment(initializer->type); LLVMTypeRef type = LLVMTypeOf(value); LLVMValueRef global_copy = llvm_add_global_raw(c, ".__const", type, alignment); - llvm_set_private_linkage(global_copy); - LLVMSetUnnamedAddress(global_copy, LLVMGlobalUnnamedAddr); + llvm_set_private_declaration(global_copy); // Set the value and make it constant LLVMSetInitializer(global_copy, value); @@ -5056,8 +5055,7 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr) LLVMTypeRef val_type = llvm_get_type(c, init->type); LLVMValueRef global_copy = llvm_add_global_raw(c, ".__const_slice", val_type, alignment); LLVMSetInitializer(global_copy, value); - llvm_set_private_linkage(global_copy); - LLVMSetUnnamedAddress(global_copy, LLVMGlobalUnnamedAddr); + llvm_set_private_declaration(global_copy); assert(type_is_arraylike(init->type)); LLVMValueRef val = llvm_emit_aggregate_two(c, type, global_copy, llvm_const_int(c, type_usz, init->type->array.len)); @@ -5131,8 +5129,7 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr) if (!is_bytes) size++; if (is_array && type->array.len > size) size = type->array.len; LLVMValueRef global_name = llvm_add_global_raw(c, is_bytes ? ".bytes" : ".str", LLVMArrayType(llvm_get_type(c, type_char), size), 1); - llvm_set_private_linkage(global_name); - LLVMSetUnnamedAddress(global_name, LLVMGlobalUnnamedAddr); + llvm_set_private_declaration(global_name); LLVMSetGlobalConstant(global_name, 1); LLVMValueRef data = is_bytes ? llvm_get_bytes(c, expr->const_expr.bytes.ptr, expr->const_expr.bytes.len) diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index bd6311d47..d60dfc968 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -644,29 +644,6 @@ void llvm_emit_function_decl(GenContext *c, Decl *decl) { llvm_emit_debug_function(c, decl); } - - if (decl->is_extern) - { - if (decl->is_weak) - { - LLVMSetLinkage(function, LLVMExternalWeakLinkage); - llvm_set_comdat(c, function); - } - else - { - LLVMSetLinkage(function, LLVMExternalLinkage); - } - LLVMSetVisibility(function, LLVMDefaultVisibility); - return; - } - if (decl_is_local(decl)) - { - LLVMSetLinkage(function, decl->is_weak ? LLVMLinkerPrivateWeakLinkage : LLVMInternalLinkage); - LLVMSetVisibility(function, LLVMDefaultVisibility); - return; - } - if (c->weaken) llvm_set_linkonce(c, function); - if (decl->is_weak) llvm_set_weak(c, function); } diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index 9d38bb6dc..1b7492d8f 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -364,10 +364,12 @@ void llvm_attribute_add_type(GenContext *c, LLVMValueRef value_to_add_attribute_ void llvm_attribute_add_int(GenContext *c, LLVMValueRef value_to_add_attribute_to, unsigned attribute, uint64_t val, int index); // -- Linking -- +void llvm_set_selector_linkage(GenContext *c, LLVMValueRef selector); void llvm_set_linkonce(GenContext *c, LLVMValueRef global); void llvm_set_comdat(GenContext *c, LLVMValueRef global); -void llvm_set_weak(GenContext *c, LLVMValueRef global); -void llvm_set_private_linkage(LLVMValueRef alloc); +void llvm_set_private_declaration(LLVMValueRef alloc); +void llvm_set_decl_linkage(GenContext *c, Decl *decl); + void llvm_set_internal_linkage(LLVMValueRef alloc); void llvm_set_global_tls(Decl *decl); diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 558cefe45..03ef89d55 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -54,7 +54,6 @@ void llvm_emit_local_static(GenContext *c, Decl *decl, BEValue *value) decl->var.optional_ref = llvm_add_global_raw(c, scratch_buffer_to_string(), anyfault, 0); } llvm_emit_global_variable_init(c, decl); - // Pop the builder c->builder = builder; llvm_value_set_decl(c, value, decl); @@ -850,7 +849,7 @@ static void llvm_emit_switch_jump_table(GenContext *c, LLVMValueRef jmptable = llvm_add_global_raw(c, "jumptable", llvm_array_type, alignment); switch_ast->switch_stmt.codegen.jump.jmptable = jmptable; - llvm_set_private_linkage(jmptable); + llvm_set_private_declaration(jmptable); LLVMSetGlobalConstant(jmptable, 1); BEValue array_value; diff --git a/src/compiler/llvm_codegen_value.c b/src/compiler/llvm_codegen_value.c index 2869e68c0..56b9d7de9 100644 --- a/src/compiler/llvm_codegen_value.c +++ b/src/compiler/llvm_codegen_value.c @@ -60,7 +60,7 @@ void llvm_value_addr(GenContext *c, BEValue *value) { LLVMValueRef val = llvm_load_value_store(c, value); LLVMValueRef ref = llvm_add_global_raw(c, ".taddr", LLVMTypeOf(val), 0); - llvm_set_private_linkage(ref); + llvm_set_private_declaration(ref); LLVMSetInitializer(ref, val); llvm_value_set_address_abi_aligned(value, ref, value->type); } diff --git a/test/test_suite/arrays/global_init.c3t b/test/test_suite/arrays/global_init.c3t index 27116c828..314a1b263 100644 --- a/test/test_suite/arrays/global_init.c3t +++ b/test/test_suite/arrays/global_init.c3t @@ -20,22 +20,21 @@ fn void main() { /* #expect: test.ll -@.taddr = private global i32 3, align 4 +@.taddr = private unnamed_addr global i32 3, align 4 @test.foo = local_unnamed_addr global ptr @.taddr, align 8 @test.a = global i32 0, align 4 @test.c = local_unnamed_addr global i32 0, align 4 @test.d = local_unnamed_addr global i32 0, align 4 @test.abc = local_unnamed_addr global [3 x i32] zeroinitializer, align 4 -@test.b = local_unnamed_addr global ptr getelementptr -@test.bf = local_unnamed_addr global ptr getelementptr +@test.b = local_unnamed_addr global ptr getelementptr (i8, ptr @test.a, i64 28), align 8 +@test.bf = local_unnamed_addr global ptr getelementptr (i8, ptr @test.abc, i64 16), align 8 @test.bf2 = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @test.abc, i64 8), align 8 -@test.bf3 = local_unnamed_addr global ptr getelementptr -@.taddr.9 = private global i32 42, align 4 -@.taddr.10 = private global i8 99, align 1 -@.taddr.11 = private global %"char[]" { ptr @.str, i64 3 }, align 8 +@test.bf3 = local_unnamed_addr global ptr getelementptr (i8, ptr @test.abc, i64 16), align 8 +@.taddr.9 = private unnamed_addr global i32 42, align 4 +@.taddr.10 = private unnamed_addr global i8 99, align 1 +@.taddr.11 = private unnamed_addr global %"char[]" { ptr @.str, i64 3 }, align 8 @main.x = internal unnamed_addr global [3 x %any] [%any { ptr @.taddr.9, i64 ptrtoint (ptr @"$ct.int" to i64) }, %any { ptr @.taddr.10, i64 ptrtoint (ptr @"$ct.char" to i64) }, %any { ptr @.taddr.11, i64 ptrtoint (ptr @"$ct.String" to i64) }], align 16 -; Function Attrs: define void @test.main() #0 { entry: %bf34 = alloca ptr, align 8 diff --git a/test/test_suite/compile_time/ct_memberof.c3t b/test/test_suite/compile_time/ct_memberof.c3t index a46498311..d60e6e732 100644 --- a/test/test_suite/compile_time/ct_memberof.c3t +++ b/test/test_suite/compile_time/ct_memberof.c3t @@ -266,39 +266,51 @@ noerr_block22: ; preds = %after_check20 assign_optional25: ; preds = %noerr_block22 store i64 %14, ptr %error_var23, align 8 br label %guard_block27 + after_check26: ; preds = %noerr_block22 br label %noerr_block28 + guard_block27: ; preds = %assign_optional25 br label %voiderr36 + noerr_block28: ; preds = %after_check26 %16 = call i64 @std.io.File.flush(ptr %10) %not_err30 = icmp eq i64 %16, 0 %17 = call i1 @llvm.expect.i1(i1 %not_err30, i1 true) br i1 %17, label %after_check32, label %assign_optional31 + assign_optional31: ; preds = %noerr_block28 store i64 %16, ptr %error_var29, align 8 br label %guard_block33 + after_check32: ; preds = %noerr_block28 br label %noerr_block34 + guard_block33: ; preds = %assign_optional31 br label %voiderr36 + noerr_block34: ; preds = %after_check32 %18 = load i64, ptr %len14, align 8 %add35 = add i64 %18, 1 br label %voiderr36 + voiderr36: ; preds = %noerr_block34, %guard_block33, %guard_block27, %guard_block21 %19 = call ptr @std.io.stdout() %20 = call i64 @std.io.File.write(ptr %retparam40, ptr %19, ptr @.str.11, i64 6) %not_err41 = icmp eq i64 %20, 0 %21 = call i1 @llvm.expect.i1(i1 %not_err41, i1 true) br i1 %21, label %after_check43, label %assign_optional42 + assign_optional42: ; preds = %voiderr36 store i64 %20, ptr %error_var38, align 8 br label %guard_block44 + after_check43: ; preds = %voiderr36 br label %noerr_block45 + guard_block44: ; preds = %assign_optional42 br label %voiderr59 + noerr_block45: ; preds = %after_check43 %22 = load i64, ptr %retparam40, align 8 store i64 %22, ptr %len37, align 8 @@ -306,42 +318,55 @@ noerr_block45: ; preds = %after_check43 %not_err47 = icmp eq i64 %23, 0 %24 = call i1 @llvm.expect.i1(i1 %not_err47, i1 true) br i1 %24, label %after_check49, label %assign_optional48 + assign_optional48: ; preds = %noerr_block45 store i64 %23, ptr %error_var46, align 8 br label %guard_block50 + after_check49: ; preds = %noerr_block45 br label %noerr_block51 + guard_block50: ; preds = %assign_optional48 br label %voiderr59 + noerr_block51: ; preds = %after_check49 %25 = call i64 @std.io.File.flush(ptr %19) %not_err53 = icmp eq i64 %25, 0 %26 = call i1 @llvm.expect.i1(i1 %not_err53, i1 true) br i1 %26, label %after_check55, label %assign_optional54 + assign_optional54: ; preds = %noerr_block51 store i64 %25, ptr %error_var52, align 8 br label %guard_block56 + after_check55: ; preds = %noerr_block51 br label %noerr_block57 + guard_block56: ; preds = %assign_optional54 br label %voiderr59 + noerr_block57: ; preds = %after_check55 %27 = load i64, ptr %len37, align 8 %add58 = add i64 %27, 1 br label %voiderr59 + voiderr59: ; preds = %noerr_block57, %guard_block56, %guard_block50, %guard_block44 %28 = call ptr @std.io.stdout() %29 = call i64 @std.io.File.write(ptr %retparam63, ptr %28, ptr @.str.12, i64 6) %not_err64 = icmp eq i64 %29, 0 %30 = call i1 @llvm.expect.i1(i1 %not_err64, i1 true) br i1 %30, label %after_check66, label %assign_optional65 + assign_optional65: ; preds = %voiderr59 store i64 %29, ptr %error_var61, align 8 br label %guard_block67 + after_check66: ; preds = %voiderr59 br label %noerr_block68 + guard_block67: ; preds = %assign_optional65 br label %voiderr82 + noerr_block68: ; preds = %after_check66 %31 = load i64, ptr %retparam63, align 8 store i64 %31, ptr %len60, align 8 @@ -349,42 +374,55 @@ noerr_block68: ; preds = %after_check66 %not_err70 = icmp eq i64 %32, 0 %33 = call i1 @llvm.expect.i1(i1 %not_err70, i1 true) br i1 %33, label %after_check72, label %assign_optional71 + assign_optional71: ; preds = %noerr_block68 store i64 %32, ptr %error_var69, align 8 br label %guard_block73 + after_check72: ; preds = %noerr_block68 br label %noerr_block74 + guard_block73: ; preds = %assign_optional71 br label %voiderr82 + noerr_block74: ; preds = %after_check72 %34 = call i64 @std.io.File.flush(ptr %28) %not_err76 = icmp eq i64 %34, 0 %35 = call i1 @llvm.expect.i1(i1 %not_err76, i1 true) br i1 %35, label %after_check78, label %assign_optional77 + assign_optional77: ; preds = %noerr_block74 store i64 %34, ptr %error_var75, align 8 br label %guard_block79 + after_check78: ; preds = %noerr_block74 br label %noerr_block80 + guard_block79: ; preds = %assign_optional77 br label %voiderr82 + noerr_block80: ; preds = %after_check78 %36 = load i64, ptr %len60, align 8 %add81 = add i64 %36, 1 br label %voiderr82 + voiderr82: ; preds = %noerr_block80, %guard_block79, %guard_block73, %guard_block67 %37 = call ptr @std.io.stdout() %38 = call i64 @std.io.File.write(ptr %retparam86, ptr %37, ptr @.str.13, i64 5) %not_err87 = icmp eq i64 %38, 0 %39 = call i1 @llvm.expect.i1(i1 %not_err87, i1 true) br i1 %39, label %after_check89, label %assign_optional88 + assign_optional88: ; preds = %voiderr82 store i64 %38, ptr %error_var84, align 8 br label %guard_block90 + after_check89: ; preds = %voiderr82 br label %noerr_block91 + guard_block90: ; preds = %assign_optional88 br label %voiderr105 + noerr_block91: ; preds = %after_check89 %40 = load i64, ptr %retparam86, align 8 store i64 %40, ptr %len83, align 8 @@ -392,42 +430,55 @@ noerr_block91: ; preds = %after_check89 %not_err93 = icmp eq i64 %41, 0 %42 = call i1 @llvm.expect.i1(i1 %not_err93, i1 true) br i1 %42, label %after_check95, label %assign_optional94 + assign_optional94: ; preds = %noerr_block91 store i64 %41, ptr %error_var92, align 8 br label %guard_block96 + after_check95: ; preds = %noerr_block91 br label %noerr_block97 + guard_block96: ; preds = %assign_optional94 br label %voiderr105 + noerr_block97: ; preds = %after_check95 %43 = call i64 @std.io.File.flush(ptr %37) %not_err99 = icmp eq i64 %43, 0 %44 = call i1 @llvm.expect.i1(i1 %not_err99, i1 true) br i1 %44, label %after_check101, label %assign_optional100 + assign_optional100: ; preds = %noerr_block97 store i64 %43, ptr %error_var98, align 8 br label %guard_block102 + after_check101: ; preds = %noerr_block97 br label %noerr_block103 + guard_block102: ; preds = %assign_optional100 br label %voiderr105 + noerr_block103: ; preds = %after_check101 %45 = load i64, ptr %len83, align 8 %add104 = add i64 %45, 1 br label %voiderr105 + voiderr105: ; preds = %noerr_block103, %guard_block102, %guard_block96, %guard_block90 %46 = call ptr @std.io.stdout() %47 = call i64 @std.io.File.write(ptr %retparam109, ptr %46, ptr @.str.14, i64 4) %not_err110 = icmp eq i64 %47, 0 %48 = call i1 @llvm.expect.i1(i1 %not_err110, i1 true) br i1 %48, label %after_check112, label %assign_optional111 + assign_optional111: ; preds = %voiderr105 store i64 %47, ptr %error_var107, align 8 br label %guard_block113 + after_check112: ; preds = %voiderr105 br label %noerr_block114 + guard_block113: ; preds = %assign_optional111 br label %voiderr128 + noerr_block114: ; preds = %after_check112 %49 = load i64, ptr %retparam109, align 8 store i64 %49, ptr %len106, align 8 @@ -435,42 +486,55 @@ noerr_block114: ; preds = %after_check112 %not_err116 = icmp eq i64 %50, 0 %51 = call i1 @llvm.expect.i1(i1 %not_err116, i1 true) br i1 %51, label %after_check118, label %assign_optional117 + assign_optional117: ; preds = %noerr_block114 store i64 %50, ptr %error_var115, align 8 br label %guard_block119 + after_check118: ; preds = %noerr_block114 br label %noerr_block120 + guard_block119: ; preds = %assign_optional117 br label %voiderr128 + noerr_block120: ; preds = %after_check118 %52 = call i64 @std.io.File.flush(ptr %46) %not_err122 = icmp eq i64 %52, 0 %53 = call i1 @llvm.expect.i1(i1 %not_err122, i1 true) br i1 %53, label %after_check124, label %assign_optional123 + assign_optional123: ; preds = %noerr_block120 store i64 %52, ptr %error_var121, align 8 br label %guard_block125 + after_check124: ; preds = %noerr_block120 br label %noerr_block126 + guard_block125: ; preds = %assign_optional123 br label %voiderr128 + noerr_block126: ; preds = %after_check124 %54 = load i64, ptr %len106, align 8 %add127 = add i64 %54, 1 br label %voiderr128 + voiderr128: ; preds = %noerr_block126, %guard_block125, %guard_block119, %guard_block113 %55 = call ptr @std.io.stdout() %56 = call i64 @std.io.File.write(ptr %retparam132, ptr %55, ptr @.str.15, i64 3) %not_err133 = icmp eq i64 %56, 0 %57 = call i1 @llvm.expect.i1(i1 %not_err133, i1 true) br i1 %57, label %after_check135, label %assign_optional134 + assign_optional134: ; preds = %voiderr128 store i64 %56, ptr %error_var130, align 8 br label %guard_block136 + after_check135: ; preds = %voiderr128 br label %noerr_block137 + guard_block136: ; preds = %assign_optional134 br label %voiderr151 + noerr_block137: ; preds = %after_check135 %58 = load i64, ptr %retparam132, align 8 store i64 %58, ptr %len129, align 8 @@ -478,29 +542,38 @@ noerr_block137: ; preds = %after_check135 %not_err139 = icmp eq i64 %59, 0 %60 = call i1 @llvm.expect.i1(i1 %not_err139, i1 true) br i1 %60, label %after_check141, label %assign_optional140 + assign_optional140: ; preds = %noerr_block137 store i64 %59, ptr %error_var138, align 8 br label %guard_block142 + after_check141: ; preds = %noerr_block137 br label %noerr_block143 + guard_block142: ; preds = %assign_optional140 br label %voiderr151 + noerr_block143: ; preds = %after_check141 %61 = call i64 @std.io.File.flush(ptr %55) %not_err145 = icmp eq i64 %61, 0 %62 = call i1 @llvm.expect.i1(i1 %not_err145, i1 true) br i1 %62, label %after_check147, label %assign_optional146 + assign_optional146: ; preds = %noerr_block143 store i64 %61, ptr %error_var144, align 8 br label %guard_block148 + after_check147: ; preds = %noerr_block143 br label %noerr_block149 + guard_block148: ; preds = %assign_optional146 br label %voiderr151 + noerr_block149: ; preds = %after_check147 %63 = load i64, ptr %len129, align 8 %add150 = add i64 %63, 1 br label %voiderr151 + voiderr151: ; preds = %noerr_block149, %guard_block148, %guard_block142, %guard_block136 store %"char[]" { ptr @.str.17, i64 3 }, ptr %taddr, align 8 %64 = insertvalue %any undef, ptr %taddr, 0 @@ -619,6 +692,7 @@ voiderr151: ; preds = %noerr_block149, %gu %122 = call i64 @std.io.printfn(ptr %retparam231, ptr @.str.47, i64 6, ptr %varargslots227, i64 2) ret void } + ; Function Attrs: nounwind uwtable define void @test.main() #0 { entry: @@ -761,6 +835,7 @@ entry: call void @test.test(i32 10) ret void } + ; Function Attrs: nounwind uwtable define i32 @main(i32 %0, ptr %1) #0 { entry: @@ -768,17 +843,12 @@ entry: ret i32 0 } -; Function Attrs: -declare ptr @std.io.stdout() #0 +declare extern_weak ptr @std.io.stdout() #0 -; Function Attrs: -declare i64 @std.io.File.write(ptr, ptr, ptr, i64) #0 +declare extern_weak i64 @std.io.File.write(ptr, ptr, ptr, i64) #0 -; Function Attrs: -declare i64 @std.io.File.write_byte(ptr, i8 zeroext) #0 +declare extern_weak i64 @std.io.File.write_byte(ptr, i8 zeroext) #0 -; Function Attrs: -declare i64 @std.io.File.flush(ptr) #0 +declare extern_weak i64 @std.io.File.flush(ptr) #0 -; Function Attrs: -declare i64 @std.io.printfn(ptr, ptr, i64, ptr, i64) #0 \ No newline at end of file +declare extern_weak i64 @std.io.printfn(ptr, ptr, i64, ptr, i64) #0 diff --git a/test/test_suite/concurrency/atomic_load_store_debug.c3t b/test/test_suite/concurrency/atomic_load_store_debug.c3t index 27ee58e89..fdec63c98 100644 --- a/test/test_suite/concurrency/atomic_load_store_debug.c3t +++ b/test/test_suite/concurrency/atomic_load_store_debug.c3t @@ -85,7 +85,7 @@ entry: ret i32 0, !dbg !50 } -declare i64 @std.io.printfn(ptr, ptr, i64, ptr, i64) #0 +declare extern_weak i64 @std.io.printfn(ptr, ptr, i64, ptr, i64) #0 declare i1 @llvm.expect.i1(i1, i1) diff --git a/test/test_suite/debug_symbols/defer_macro.c3t b/test/test_suite/debug_symbols/defer_macro.c3t index 8b8227a52..aef28657b 100644 --- a/test/test_suite/debug_symbols/defer_macro.c3t +++ b/test/test_suite/debug_symbols/defer_macro.c3t @@ -548,16 +548,11 @@ expr_block.exit28: ; preds = %loop.exit26 declare { i32, ptr } @attach.to_scope() #0 -declare ptr @std.core.mem.calloc(i64) #0 - -declare ptr @std.io.stdout() #0 - -declare i64 @std.io.fprintf(ptr, i64, ptr, ptr, i64, ptr byval(%"any[]") align 8) #0 - -declare i64 @std.io.File.write_byte(ptr, i8 zeroext) #0 - -declare i64 @std.io.File.flush(ptr) #0 - +declare extern_weak ptr @std.core.mem.calloc(i64) #0 +declare extern_weak ptr @std.io.stdout() #0 +declare extern_weak i64 @std.io.fprintf(ptr, i64, ptr, ptr, i64, ptr byval(%"any[]") align 8) #0 +declare extern_weak i64 @std.io.File.write_byte(ptr, i8 zeroext) #0 +declare extern_weak i64 @std.io.File.flush(ptr) #0 declare { ptr, i64 } @arena_scratch_begin(ptr, i64) #0 declare void @arena_scratch_end(ptr, i64) #0 diff --git a/test/test_suite/dynamic/inherit_linux.c3t b/test/test_suite/dynamic/inherit_linux.c3t index 99a2cb0e9..79d63b6be 100644 --- a/test/test_suite/dynamic/inherit_linux.c3t +++ b/test/test_suite/dynamic/inherit_linux.c3t @@ -41,16 +41,20 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } + $.dyn_search = comdat any + $"$ct.inherit.Test" = comdat any + $"$sel.tesT" = comdat any + $"$sel.hello" = comdat any + @"$ct.inherit.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", comdat, align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 - @.func = internal constant [5 x i8] c"main\00", align 1 -@std.core.builtin.panic = external global ptr, align 8 +@std.core.builtin.panic = extern_weak global ptr, align 8 @"$ct.dyn.inherit.Test.tesT" = global { ptr, ptr, ptr } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", ptr null }, align 8 @"$ct.dyn.inherit.Test.hello" = global { ptr, ptr, ptr } { ptr @inherit.Test.hello, ptr @"$sel.hello", ptr null }, align 8 @"$sel.hello" = linkonce_odr constant [6 x i8] c"hello\00", comdat, align 1 @@ -61,13 +65,11 @@ entry: ret void } -; Function Attrs: define void @inherit.Test.hello(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @inherit.main() #0 { entry: %z = alloca %any, align 8 @@ -88,6 +90,7 @@ entry: %type = load ptr, ptr %.cachedtype, align 8 %5 = icmp eq ptr %4, %type br i1 %5, label %cache_hit, label %cache_miss + cache_miss: ; preds = %entry %ptradd1 = getelementptr inbounds i8, ptr %4, i64 16 %6 = load ptr, ptr %ptradd1, align 8 @@ -95,17 +98,21 @@ cache_miss: ; preds = %entry store ptr %7, ptr %.inlinecache, align 8 store ptr %4, ptr %.cachedtype, align 8 br label %8 + cache_hit: ; preds = %entry %cache_hit_fn = load ptr, ptr %.inlinecache, align 8 br label %8 + 8: ; preds = %cache_hit, %cache_miss %fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ] %9 = icmp eq ptr %fn_phi, null br i1 %9, label %missing_function, label %match + missing_function: ; preds = %8 %10 = load ptr, ptr @std.core.builtin.panic, align 8 call void %10(ptr @.panic_msg, i64 41, ptr @.file unreachable + match: ; preds = %8 %11 = load ptr, ptr %z, align 8 call void %fn_phi(ptr %11) @@ -117,6 +124,7 @@ match: ; preds = %8 %type5 = load ptr, ptr %.cachedtype4, align 8 %15 = icmp eq ptr %14, %type5 br i1 %15, label %cache_hit8, label %cache_miss6 + cache_miss6: ; preds = %match %ptradd7 = getelementptr inbounds i8, ptr %14, i64 16 %16 = load ptr, ptr %ptradd7, align 8 @@ -124,17 +132,21 @@ cache_miss6: ; preds = %match store ptr %17, ptr %.inlinecache3, align 8 store ptr %14, ptr %.cachedtype4, align 8 br label %18 + cache_hit8: ; preds = %match %cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8 br label %18 + 18: ; preds = %cache_hit8, %cache_miss6 %fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ] %19 = icmp eq ptr %fn_phi10, null br i1 %19, label %missing_function11, label %match12 + missing_function11: ; preds = %18 %20 = load ptr, ptr @std.core.builtin.panic, align 8 call void %20(ptr @.panic_msg, i64 41, ptr @.file unreachable + match12: ; preds = %18 %21 = load ptr, ptr %w, align 8 call void %fn_phi10(ptr %21) @@ -149,47 +161,59 @@ entry: define weak_odr ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat { entry: br label %check + check: ; preds = %no_match, %entry %2 = phi ptr [ %0, %entry ], [ %9, %no_match ] %3 = icmp eq ptr %2, null br i1 %3, label %missing_function, label %compare + missing_function: ; preds = %check ret ptr null + compare: ; preds = %check %4 = getelementptr inbounds %5 = load ptr, ptr %4, align 8 %6 = icmp eq ptr %5, %1 br i1 %6, label %match, label %no_match + match: ; preds = %compare %7 = load ptr, ptr %2, align 8 ret ptr %7 + no_match: ; preds = %compare %8 = getelementptr inbounds %9 = load ptr, ptr %8, align 8 br label %check } + define internal void @.c3_dynamic_register() align 8 { entry: br label %dtable_check + dtable_check: ; preds = %dtable_next, %entry %dtable_ref = phi ptr [ getelementptr inbounds %dtable_ptr = load ptr, ptr %dtable_ref, align 8 %0 = icmp eq ptr %dtable_ptr, null br i1 %0, label %dtable_found, label %dtable_next + dtable_next: ; preds = %dtable_check %next_dtable_ref = getelementptr inbounds br label %dtable_check + dtable_found: ; preds = %dtable_check store ptr @"$ct.dyn.inherit.Test.tesT", ptr %dtable_ref, align 8 br label %dtable_check1 + dtable_check1: ; preds = %dtable_next4, %dtable_found %dtable_ref2 = phi ptr [ getelementptr inbounds %dtable_ptr3 = load ptr, ptr %dtable_ref2, align 8 %1 = icmp eq ptr %dtable_ptr3, null br i1 %1, label %dtable_found6, label %dtable_next4 + dtable_next4: ; preds = %dtable_check1 %next_dtable_ref5 = getelementptr inbounds br label %dtable_check1 + dtable_found6: ; preds = %dtable_check1 store ptr @"$ct.dyn.inherit.Test.hello", ptr %dtable_ref2, align 8 ret void diff --git a/test/test_suite/dynamic/inherit_macos.c3t b/test/test_suite/dynamic/inherit_macos.c3t index 4f277f118..50f37f0e1 100644 --- a/test/test_suite/dynamic/inherit_macos.c3t +++ b/test/test_suite/dynamic/inherit_macos.c3t @@ -41,27 +41,25 @@ fn void main() %.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] } %any = type { ptr, i64 } + @"$ct.inherit.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, align 8 @"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", align 1 @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 -@std.core.builtin.panic = external global ptr, align 8 +@std.core.builtin.panic = extern_weak global ptr, align 8 @"$sel.hello" = linkonce_odr constant [6 x i8] c"hello\00", align 1 @"$c3_dynamic" = internal global [2 x { ptr, ptr, i64 }] [{ ptr, ptr, i64 } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", i64 ptrtoint (ptr @"$ct.inherit.Test" to i64) }, { ptr, ptr, i64 } { ptr @inherit.Test.hello, ptr @"$sel.hello", i64 ptrtoint (ptr @"$ct.inherit.Test" to i64) }], section "__DATA,__c3_dynamic", align 8 -; Function Attrs: define void @inherit.Test.tesT(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @inherit.Test.hello(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @inherit.main() #0 { entry: %z = alloca %any, align 8 @@ -82,6 +80,7 @@ entry: %type = load ptr, ptr %.cachedtype, align 8 %5 = icmp eq ptr %4, %type br i1 %5, label %cache_hit, label %cache_miss + cache_miss: ; preds = %entry %ptradd1 = getelementptr inbounds i8, ptr %4, i64 16 %6 = load ptr, ptr %ptradd1, align 8 @@ -89,17 +88,21 @@ cache_miss: ; preds = %entry store ptr %7, ptr %.inlinecache, align 8 store ptr %4, ptr %.cachedtype, align 8 br label %8 + cache_hit: ; preds = %entry %cache_hit_fn = load ptr, ptr %.inlinecache, align 8 br label %8 + 8: ; preds = %cache_hit, %cache_miss %fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ] %9 = icmp eq ptr %fn_phi, null br i1 %9, label %missing_function, label %match + missing_function: ; preds = %8 %10 = load ptr, ptr @std.core.builtin.panic, align 8 call void %10(ptr @.panic_msg, i64 41, unreachable + match: ; preds = %8 %11 = load ptr, ptr %z, align 8 call void %fn_phi(ptr %11) @@ -111,6 +114,7 @@ match: ; preds = %8 %type5 = load ptr, ptr %.cachedtype4, align 8 %15 = icmp eq ptr %14, %type5 br i1 %15, label %cache_hit8, label %cache_miss6 + cache_miss6: ; preds = %match %ptradd7 = getelementptr inbounds i8, ptr %14, i64 16 %16 = load ptr, ptr %ptradd7, align 8 @@ -118,17 +122,21 @@ cache_miss6: ; preds = %match store ptr %17, ptr %.inlinecache3, align 8 store ptr %14, ptr %.cachedtype4, align 8 br label %18 + cache_hit8: ; preds = %match %cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8 br label %18 + 18: ; preds = %cache_hit8, %cache_miss6 %fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ] %19 = icmp eq ptr %fn_phi10, null br i1 %19, label %missing_function11, label %match12 + missing_function11: ; preds = %18 %20 = load ptr, ptr @std.core.builtin.panic, align 8 call void %20(ptr @.panic_msg, i64 41 unreachable + match12: ; preds = %18 %21 = load ptr, ptr %w, align 8 call void %fn_phi10(ptr %21) @@ -142,20 +150,25 @@ entry: define weak_odr ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr { entry: br label %check + check: ; preds = %no_match, %entry %2 = phi ptr [ %0, %entry ], [ %9, %no_match ] %3 = icmp eq ptr %2, null br i1 %3, label %missing_function, label %compare + missing_function: ; preds = %check ret ptr null + compare: ; preds = %check %4 = getelementptr inbounds %5 = load ptr, ptr %4, align 8 %6 = icmp eq ptr %5, %1 br i1 %6, label %match, label %no_match + match: ; preds = %compare %7 = load ptr, ptr %2, align 8 ret ptr %7 + no_match: ; preds = %compare %8 = getelementptr inbounds %9 = load ptr, ptr %8, align 8 diff --git a/test/test_suite/dynamic/overlapping_function_linux.c3t b/test/test_suite/dynamic/overlapping_function_linux.c3t index dfaf4a9b6..6c63cecfa 100644 --- a/test/test_suite/dynamic/overlapping_function_linux.c3t +++ b/test/test_suite/dynamic/overlapping_function_linux.c3t @@ -40,24 +40,23 @@ fn void main() @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.file = internal constant [30 x i8] c"overlapping_function_linux.c3\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 -@std.core.builtin.panic = external global ptr, align 8 +@std.core.builtin.panic = extern_weak global ptr, align 8 @"$ct.dyn.overlap.Test.tesT" = global { ptr, ptr, ptr } { ptr @overlap.Test.tesT, ptr @"$sel.tesT", ptr null }, align 8 @"$ct.dyn.overlap.Test.foo" = global { ptr, ptr, ptr } { ptr @overlap.Test.foo, ptr @"$sel.foo", ptr null }, align 8 @"$sel.foo" = linkonce_odr constant [4 x i8] c"foo\00", comdat, align 1 @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_register, ptr null }] + ; Function Attrs: nounwind uwtable define void @overlap.Test.tesT(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @overlap.Test.foo(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @overlap.main() #0 { entry: %z = alloca %any, align 8 @@ -78,6 +77,7 @@ entry: %type = load ptr, ptr %.cachedtype, align 8 %5 = icmp eq ptr %4, %type br i1 %5, label %cache_hit, label %cache_miss + cache_miss: ; preds = %entry %ptradd1 = getelementptr inbounds i8, ptr %4, i64 16 %6 = load ptr, ptr %ptradd1, align 8 @@ -85,17 +85,21 @@ cache_miss: ; preds = %entry store ptr %7, ptr %.inlinecache, align 8 store ptr %4, ptr %.cachedtype, align 8 br label %8 + cache_hit: ; preds = %entry %cache_hit_fn = load ptr, ptr %.inlinecache, align 8 br label %8 + 8: ; preds = %cache_hit, %cache_miss %fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ] %9 = icmp eq ptr %fn_phi, null br i1 %9, label %missing_function, label %match + missing_function: ; preds = %8 %10 = load ptr, ptr @std.core.builtin.panic, align 8 call void %10(ptr @.panic_msg, i64 41, ptr @.file unreachable + match: ; preds = %8 %11 = load ptr, ptr %z, align 8 call void %fn_phi(ptr %11) @@ -107,6 +111,7 @@ match: ; preds = %8 %type5 = load ptr, ptr %.cachedtype4, align 8 %15 = icmp eq ptr %14, %type5 br i1 %15, label %cache_hit8, label %cache_miss6 + cache_miss6: ; preds = %match %ptradd7 = getelementptr inbounds i8, ptr %14, i64 16 %16 = load ptr, ptr %ptradd7, align 8 @@ -114,24 +119,27 @@ cache_miss6: ; preds = %match store ptr %17, ptr %.inlinecache3, align 8 store ptr %14, ptr %.cachedtype4, align 8 br label %18 + cache_hit8: ; preds = %match %cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8 br label %18 + 18: ; preds = %cache_hit8, %cache_miss6 %fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ] %19 = icmp eq ptr %fn_phi10, null br i1 %19, label %missing_function11, label %match12 + missing_function11: ; preds = %18 %20 = load ptr, ptr @std.core.builtin.panic, align 8 call void %20(ptr @.panic_msg, i64 41, ptr @.file unreachable + match12: ; preds = %18 %21 = load ptr, ptr %w, align 8 call void %fn_phi10(ptr %21) ret void } -; Function Attrs: define i32 @main(i32 %0, ptr %1) #0 { entry: call void @overlap.main() @@ -142,47 +150,59 @@ entry: define weak_odr ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat { entry: br label %check + check: ; preds = %no_match, %entry %2 = phi ptr [ %0, %entry ], [ %9, %no_match ] %3 = icmp eq ptr %2, null br i1 %3, label %missing_function, label %compare + missing_function: ; preds = %check ret ptr null + compare: ; preds = %check %4 = getelementptr inbounds %5 = load ptr, ptr %4, align 8 %6 = icmp eq ptr %5, %1 br i1 %6, label %match, label %no_match + match: ; preds = %compare %7 = load ptr, ptr %2, align 8 ret ptr %7 + no_match: ; preds = %compare %8 = getelementptr inbounds %9 = load ptr, ptr %8, align 8 br label %check } + define internal void @.c3_dynamic_register() align 8 { entry: br label %dtable_check + dtable_check: ; preds = %dtable_next, %entry %dtable_ref = phi ptr [ getelementptr inbounds %dtable_ptr = load ptr, ptr %dtable_ref, align 8 %0 = icmp eq ptr %dtable_ptr, null br i1 %0, label %dtable_found, label %dtable_next + dtable_next: ; preds = %dtable_check %next_dtable_ref = getelementptr inbounds br label %dtable_check + dtable_found: ; preds = %dtable_check store ptr @"$ct.dyn.overlap.Test.tesT", ptr %dtable_ref, align 8 br label %dtable_check1 + dtable_check1: ; preds = %dtable_next4, %dtable_found %dtable_ref2 = phi ptr [ getelementptr inbounds %dtable_ptr3 = load ptr, ptr %dtable_ref2, align 8 %1 = icmp eq ptr %dtable_ptr3, null br i1 %1, label %dtable_found6, label %dtable_next4 + dtable_next4: ; preds = %dtable_check1 %next_dtable_ref5 = getelementptr inbounds br label %dtable_check1 + dtable_found6: ; preds = %dtable_check1 store ptr @"$ct.dyn.overlap.Test.foo", ptr %dtable_ref2, align 8 ret void diff --git a/test/test_suite/dynamic/overlapping_function_macos.c3t b/test/test_suite/dynamic/overlapping_function_macos.c3t index 310b58641..45841f000 100644 --- a/test/test_suite/dynamic/overlapping_function_macos.c3t +++ b/test/test_suite/dynamic/overlapping_function_macos.c3t @@ -40,7 +40,7 @@ fn void main() @.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1 @.file = internal constant [30 x i8] c"overlapping_function_macos.c3\00", align 1 @.func = internal constant [5 x i8] c"main\00", align 1 -@std.core.builtin.panic = external global ptr, align 8 +@std.core.builtin.panic = extern_weak global ptr, align 8 @"$sel.foo" = linkonce_odr constant [4 x i8] c"foo\00", align 1 @"$c3_dynamic" = internal global [2 x { ptr, ptr, i64 }] [{ ptr, ptr, i64 } { ptr @overlap.Test.tesT, ptr @"$sel.tesT", i64 ptrtoint (ptr @"$ct.overlap.Test" to i64) }, { ptr, ptr, i64 } { ptr @overlap.Test.foo, ptr @"$sel.foo", i64 ptrtoint (ptr @"$ct.overlap.Test" to i64) }], section "__DATA,__c3_dynamic", align 8 @@ -50,13 +50,11 @@ entry: ret void } -; Function Attrs: define void @overlap.Test.foo(ptr %0) #0 { entry: ret void } -; Function Attrs: define void @overlap.main() #0 { entry: %z = alloca %any, align 8 diff --git a/test/test_suite/enumerations/enum_values.c3t b/test/test_suite/enumerations/enum_values.c3t index fd863582f..fb6b6172f 100644 --- a/test/test_suite/enumerations/enum_values.c3t +++ b/test/test_suite/enumerations/enum_values.c3t @@ -19,10 +19,9 @@ fn void test(int x) /* #expect: test.ll @test.zfok = local_unnamed_addr global i32 0, align 4 -@.taddr = private global [2 x i32] [i32 0, i32 1], align 4 +@.taddr = private unnamed_addr global [2 x i32] [i32 0, i32 1], align 4 @test.zw = local_unnamed_addr global %"int[]" { ptr @.taddr, i64 2 }, align 8 -; Function Attrs: define void @test.test(i32 %0) #0 { entry: %zonk = alloca i32, align 4 diff --git a/test/test_suite/initializer_lists/subarrays.c3t b/test/test_suite/initializer_lists/subarrays.c3t index c7900a682..b154ca5af 100644 --- a/test/test_suite/initializer_lists/subarrays.c3t +++ b/test/test_suite/initializer_lists/subarrays.c3t @@ -56,7 +56,7 @@ fn int main() @subarrays.arrbar = local_unnamed_addr global %"Bar[]" { ptr @.__const_slice, i64 2 }, align 8 @.__const_slice.3 = private unnamed_addr global [2 x i32] [i32 1, i32 2], align 4 @subarrays.xd = local_unnamed_addr global %"int[]" { ptr @.__const_slice.3, i64 2 }, align 8 -@.taddr = private global [2 x i32] [i32 3, i32 4], align 4 +@.taddr = private unnamed_addr global [2 x i32] [i32 3, i32 4], align 4 @subarrays.fofeo = local_unnamed_addr global ptr @.taddr, align 8 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @.__const = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4 diff --git a/test/test_suite/switch/simple_jump.c3t b/test/test_suite/switch/simple_jump.c3t index 9dcbce76d..883fcf557 100644 --- a/test/test_suite/switch/simple_jump.c3t +++ b/test/test_suite/switch/simple_jump.c3t @@ -66,13 +66,12 @@ fn void test6(int a) /* #expect: simple_jump.ll -@jumptable = private constant [3 x ptr] [ptr blockaddress(@simple_jump.test1, %switch.case1), ptr blockaddress(@simple_jump.test1, %switch.case), ptr blockaddress(@simple_jump.test1, %switch.case1)], align 4 -@jumptable.1 = private constant [2 x ptr] [ptr blockaddress(@simple_jump.test2, %switch.case), ptr blockaddress(@simple_jump.test2, %switch.case1)], align 4 -@jumptable.2 = private constant [3 x ptr] [ptr blockaddress(@simple_jump.test3, %switch.case), ptr blockaddress(@simple_jump.test3, %switch.exit), ptr blockaddress(@simple_jump.test3, %switch.case1)], align 4 -@jumptable.3 = private constant [1 x ptr] [ptr blockaddress(@simple_jump.test4, %switch.case)], align 4 -@jumptable.4 = private constant [4 x ptr] [ptr blockaddress(@simple_jump.test5, %switch.case), ptr blockaddress(@simple_jump.test5, %switch.default), ptr blockaddress(@simple_jump.test5, %switch.default), ptr blockaddress(@simple_jump.test5, %switch.case1)], align 4 -@jumptable.5 = private constant [5 x ptr] [ptr blockaddress(@simple_jump.test6, %switch.case), ptr blockaddress(@simple_jump.test6, %switch.default), ptr blockaddress(@simple_jump.test6, %switch.default), ptr blockaddress(@simple_jump.test6, %switch.case1), ptr blockaddress(@simple_jump.test6, %switch.case2)], align 4 - +@jumptable = private unnamed_addr constant [3 x ptr] [ptr blockaddress(@simple_jump.test1, %switch.case1), ptr blockaddress(@simple_jump.test1, %switch.case), ptr blockaddress(@simple_jump.test1, %switch.case1)], align 4 +@jumptable.1 = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@simple_jump.test2, %switch.case), ptr blockaddress(@simple_jump.test2, %switch.case1)], align 4 +@jumptable.2 = private unnamed_addr constant [3 x ptr] [ptr blockaddress(@simple_jump.test3, %switch.case), ptr blockaddress(@simple_jump.test3, %switch.exit), ptr blockaddress(@simple_jump.test3, %switch.case1)], align 4 +@jumptable.3 = private unnamed_addr constant [1 x ptr] [ptr blockaddress(@simple_jump.test4, %switch.case)], align 4 +@jumptable.4 = private unnamed_addr constant [4 x ptr] [ptr blockaddress(@simple_jump.test5, %switch.case), ptr blockaddress(@simple_jump.test5, %switch.default), ptr blockaddress(@simple_jump.test5, %switch.default), ptr blockaddress(@simple_jump.test5, %switch.case1)], align 4 +@jumptable.5 = private unnamed_addr constant [5 x ptr] [ptr blockaddress(@simple_jump.test6, %switch.case), ptr blockaddress(@simple_jump.test6, %switch.default), ptr blockaddress(@simple_jump.test6, %switch.default), ptr blockaddress(@simple_jump.test6, %switch.case1), ptr blockaddress(@simple_jump.test6, %switch.case2)], align 4 after_check12: ; preds = %noerr_block8 br label %noerr_block14 diff --git a/test/test_suite/switch/switch_in_defer_macro.c3t b/test/test_suite/switch/switch_in_defer_macro.c3t index 12c33d4c9..72cf41ada 100644 --- a/test/test_suite/switch/switch_in_defer_macro.c3t +++ b/test/test_suite/switch/switch_in_defer_macro.c3t @@ -709,7 +709,7 @@ fn void test() @.str.5 = private unnamed_addr constant [3 x i8] c"*/\00", align 1 @"lexer_test.Comment$end" = linkonce constant [2 x %"char[]"] [%"char[]" { ptr @.str.4, i64 1 }, %"char[]" { ptr @.str.5, i64 2 }], align 8 @"$ct.std.io.ByteReader" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8 -@std.core.mem.allocator.thread_allocator = external thread_local global %any, align 8 +@std.core.mem.allocator.thread_allocator = extern_weak thread_local global %any, align 8 ; Function Attrs: define zeroext i8 @lexer_test.is_ident_char(i64 %0, i8 zeroext %1) #0 {