- Remove use of LLVMGetGlobalContext for single module compilation.

- Fixed bug where constants would get modified when slicing them. #2660
This commit is contained in:
Christoffer Lerno
2025-12-19 17:17:41 +01:00
parent 9aec5de105
commit 4e6cd4283c
6 changed files with 84 additions and 8 deletions

View File

@@ -5,6 +5,8 @@
### Changes / improvements
- Add `--custom-libc` option for custom libc implementations.
- Remove use of LLVMGetGlobalContext for single module compilation.
- Fixed bug where constants would get modified when slicing them. #2660
### Fixes
- Regression with npot vector in struct triggering an assert #2219.

View File

@@ -1556,7 +1556,7 @@ void **llvm_gen(Module** modules, unsigned module_count)
llvm_codegen_setup();
if (compiler.build.single_module == SINGLE_MODULE_ON)
{
LLVMContextRef context = LLVMGetGlobalContext();
LLVMContextRef context = LLVMContextCreate();
for (int i = 0; i < module_count; i++)
{
GenContext *result = llvm_gen_module(modules[i], context);

View File

@@ -1765,7 +1765,7 @@ INLINE Expr **sema_splat_struct_insert(SemaContext *context, Expr **args, Expr *
args[i + index] = expr;
break;
case CONST_INIT_VALUE:
expr = expr_copy(c->init_value);
expr = copy_expr_single(c->init_value);
break;
default:
expr = expr_calloc();
@@ -2033,7 +2033,7 @@ INLINE bool sema_call_evaluate_arguments(SemaContext *context, CalledDecl *calle
Expr *inner_new = inner;
if (type_is_arraylike(inner->type))
{
inner_new = expr_copy(inner);
inner_new = copy_expr_single(inner);
if (sema_cast_const(inner_new) && expr_is_const_initializer(inner_new))
{
ConstInitializer *initializer = inner_new->const_expr.initializer;
@@ -3621,7 +3621,7 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr)
expr_rewrite_const_bool(expr, type_bool, true);
return true;
}
expr_replace(expr, expr_copy(value));
expr_replace(expr, copy_expr_single(value));
return true;
NOT_FOUND:
if (is_has)
@@ -3726,7 +3726,7 @@ static inline bool sema_call_analyse_member_get(SemaContext *context, Expr *expr
// Constant fold the get
if (target_kind == TYPE_ENUM && sema_cast_const(inner) && expr_is_const_enum(inner))
{
expr_replace(expr, expr_copy(inner->const_expr.enum_val->enum_constant.associated[index]));
expr_replace(expr, copy_expr_single(inner->const_expr.enum_val->enum_constant.associated[index]));
return true;
}
expr->expr_kind = target_kind == TYPE_BITSTRUCT ? EXPR_BITACCESS : EXPR_ACCESS_RESOLVED;
@@ -6270,7 +6270,7 @@ static inline void sema_expr_flatten_const_ident(Expr *expr)
sema_expr_flatten_const_ident(init_expr);
if (expr_is_const(init_expr))
{
expr_replace(expr, expr_copy(init_expr));
expr_replace(expr, copy_expr_single(init_expr));
}
}

View File

@@ -951,7 +951,7 @@ void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value)
Decl *ident = decl_flatten(value->ident_expr);
ASSERT(ident->decl_kind == DECL_VAR);
ASSERT(ident->var.kind == VARDECL_CONST);
const_init_rewrite_to_value(const_init, expr_copy(ident->var.init_expr));
const_init_rewrite_to_value(const_init, copy_expr_single(ident->var.init_expr));
return;
}
const_init->init_value = value;

View File

@@ -0,0 +1,27 @@
module my_module { GENNY };
import std::io;
const uint[5] H = { 1, 2, 3, 4, 5 };
macro void get(String to_print)
{
uint[3] slice_thing;
io::printfn(to_print, GENNY);
$if GENNY != 1:
io::printn("not");
$else
// !< PROBLEM LINES >!
slice_thing[:1] = H[:1];
slice_thing[1:2] = H[3:2];
// ===================
io::printn("is!");
$endif
}
module testing_branch;
import my_module;
fn void main()
{
my_module::get{1}("The %d string");
}

View File

@@ -33,7 +33,8 @@ fn int main()
/* #expect: test.ll
@test.FOO = local_unnamed_addr constant [2 x i32] [i32 2, i32 3], align 16
@test.FOO = local_unnamed_addr constant [4 x i32] [i32 1, i32 2, i32 3, i32 4], align 16
@.__const_slice = private unnamed_addr global [2 x i32] [i32 2, i32 3], align 4
@test.y2 = local_unnamed_addr global %"int[]" { ptr @.__const_slice, i64 2 }, align 8
@.__const = private unnamed_addr constant [1 x i32] [i32 1], align 4
@@ -299,24 +300,31 @@ assign_optional71: ; preds = %noerr_block68
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
%47 = call i64 @std.io.File.flush(ptr %36)
%not_err76 = icmp eq i64 %47, 0
%48 = call i1 @llvm.expect.i1(i1 %not_err76, i1 true)
br i1 %48, label %after_check78, label %assign_optional77
assign_optional77: ; preds = %noerr_block74
store i64 %47, 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
%49 = load i64, ptr %len52, align 8
%add81 = add i64 %49, 1
br label %voiderr82
voiderr82: ; preds = %noerr_block80, %guard_block79, %guard_block73, %guard_block67
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal83, ptr align 4 @.__const.6, i32 12, i1 false)
%50 = insertvalue %"int[]" undef, ptr %literal83, 0
@@ -339,13 +347,17 @@ voiderr82: ; preds = %noerr_block80, %gua
%not_err96 = icmp eq i64 %58, 0
%59 = call i1 @llvm.expect.i1(i1 %not_err96, i1 true)
br i1 %59, label %after_check98, label %assign_optional97
assign_optional97: ; preds = %voiderr82
store i64 %58, ptr %error_var85, align 8
br label %guard_block99
after_check98: ; preds = %voiderr82
br label %noerr_block100
guard_block99: ; preds = %assign_optional97
br label %voiderr114
noerr_block100: ; preds = %after_check98
%60 = load i64, ptr %retparam90, align 8
store i64 %60, ptr %len84, align 8
@@ -353,29 +365,38 @@ noerr_block100: ; preds = %after_check98
%not_err102 = icmp eq i64 %61, 0
%62 = call i1 @llvm.expect.i1(i1 %not_err102, i1 true)
br i1 %62, label %after_check104, label %assign_optional103
assign_optional103: ; preds = %noerr_block100
store i64 %61, ptr %error_var101, align 8
br label %guard_block105
after_check104: ; preds = %noerr_block100
br label %noerr_block106
guard_block105: ; preds = %assign_optional103
br label %voiderr114
noerr_block106: ; preds = %after_check104
%63 = call i64 @std.io.File.flush(ptr %52)
%not_err108 = icmp eq i64 %63, 0
%64 = call i1 @llvm.expect.i1(i1 %not_err108, i1 true)
br i1 %64, label %after_check110, label %assign_optional109
assign_optional109: ; preds = %noerr_block106
store i64 %63, ptr %error_var107, align 8
br label %guard_block111
after_check110: ; preds = %noerr_block106
br label %noerr_block112
guard_block111: ; preds = %assign_optional109
br label %voiderr114
noerr_block112: ; preds = %after_check110
%65 = load i64, ptr %len84, align 8
%add113 = add i64 %65, 1
br label %voiderr114
voiderr114: ; preds = %noerr_block112, %guard_block111, %guard_block105, %guard_block99
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal115, ptr align 4 @.__const.8, i32 8, i1 false)
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x116, ptr align 4 %literal115, i32 8, i1 false)
@@ -398,13 +419,17 @@ voiderr114: ; preds = %noerr_block112, %gu
%not_err130 = icmp eq i64 %72, 0
%73 = call i1 @llvm.expect.i1(i1 %not_err130, i1 true)
br i1 %73, label %after_check132, label %assign_optional131
assign_optional131: ; preds = %voiderr114
store i64 %72, ptr %error_var119, align 8
br label %guard_block133
after_check132: ; preds = %voiderr114
br label %noerr_block134
guard_block133: ; preds = %assign_optional131
br label %voiderr148
noerr_block134: ; preds = %after_check132
%74 = load i64, ptr %retparam124, align 8
store i64 %74, ptr %len118, align 8
@@ -412,29 +437,38 @@ noerr_block134: ; preds = %after_check132
%not_err136 = icmp eq i64 %75, 0
%76 = call i1 @llvm.expect.i1(i1 %not_err136, i1 true)
br i1 %76, label %after_check138, label %assign_optional137
assign_optional137: ; preds = %noerr_block134
store i64 %75, ptr %error_var135, align 8
br label %guard_block139
after_check138: ; preds = %noerr_block134
br label %noerr_block140
guard_block139: ; preds = %assign_optional137
br label %voiderr148
noerr_block140: ; preds = %after_check138
%77 = call i64 @std.io.File.flush(ptr %66)
%not_err142 = icmp eq i64 %77, 0
%78 = call i1 @llvm.expect.i1(i1 %not_err142, i1 true)
br i1 %78, label %after_check144, label %assign_optional143
assign_optional143: ; preds = %noerr_block140
store i64 %77, ptr %error_var141, align 8
br label %guard_block145
after_check144: ; preds = %noerr_block140
br label %noerr_block146
guard_block145: ; preds = %assign_optional143
br label %voiderr148
noerr_block146: ; preds = %after_check144
%79 = load i64, ptr %len118, align 8
%add147 = add i64 %79, 1
br label %voiderr148
voiderr148: ; preds = %noerr_block146, %guard_block145, %guard_block139, %guard_block133
%80 = call ptr @std.io.stdout()
%81 = insertvalue %any undef, ptr %80, 0
@@ -454,13 +488,17 @@ voiderr148: ; preds = %noerr_block146, %gu
%not_err161 = icmp eq i64 %86, 0
%87 = call i1 @llvm.expect.i1(i1 %not_err161, i1 true)
br i1 %87, label %after_check163, label %assign_optional162
assign_optional162: ; preds = %voiderr148
store i64 %86, ptr %error_var150, align 8
br label %guard_block164
after_check163: ; preds = %voiderr148
br label %noerr_block165
guard_block164: ; preds = %assign_optional162
br label %voiderr179
noerr_block165: ; preds = %after_check163
%88 = load i64, ptr %retparam155, align 8
store i64 %88, ptr %len149, align 8
@@ -468,29 +506,38 @@ noerr_block165: ; preds = %after_check163
%not_err167 = icmp eq i64 %89, 0
%90 = call i1 @llvm.expect.i1(i1 %not_err167, i1 true)
br i1 %90, label %after_check169, label %assign_optional168
assign_optional168: ; preds = %noerr_block165
store i64 %89, ptr %error_var166, align 8
br label %guard_block170
after_check169: ; preds = %noerr_block165
br label %noerr_block171
guard_block170: ; preds = %assign_optional168
br label %voiderr179
noerr_block171: ; preds = %after_check169
%91 = call i64 @std.io.File.flush(ptr %80)
%not_err173 = icmp eq i64 %91, 0
%92 = call i1 @llvm.expect.i1(i1 %not_err173, i1 true)
br i1 %92, label %after_check175, label %assign_optional174
assign_optional174: ; preds = %noerr_block171
store i64 %91, ptr %error_var172, align 8
br label %guard_block176
after_check175: ; preds = %noerr_block171
br label %noerr_block177
guard_block176: ; preds = %assign_optional174
br label %voiderr179
noerr_block177: ; preds = %after_check175
%93 = load i64, ptr %len149, align 8
%add178 = add i64 %93, 1
br label %voiderr179
voiderr179: ; preds = %noerr_block177, %guard_block176, %guard_block170, %guard_block164
ret i32 0
}