&self not runtime null-checked in macro #1827. Regression in temp allocators.

This commit is contained in:
Christoffer Lerno
2025-03-23 22:50:09 +01:00
parent b48588ca8f
commit 82f1b543ed
14 changed files with 335 additions and 224 deletions

View File

@@ -203,10 +203,11 @@ fn void*? TempAllocator.resize(&self, void* pointer, usz size, usz alignment) @d
}
}
void* data = self.acquire(size, NO_ZERO, alignment)!;
mem::copy(data, pointer, chunk.size, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
usz len_to_copy = chunk.size > size ? size : chunk.size;
mem::copy(data, pointer, len_to_copy, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
if (is_realloc_of_last)
{
self.used = ((void*)chunk - &self.data);
self.used = (uptr)chunk - (uptr)&self.data;
$if env::ADDRESS_SANITIZER:
asan::poison_memory_region(chunk, TempAllocatorChunk.sizeof + chunk.size);
$endif

View File

@@ -317,12 +317,13 @@ macro void clear_inline(void* dst, usz $len, usz $dst_align = 0, bool $is_volati
Copy memory from src to dst efficiently, assuming the memory ranges do not overlap.
@param [&out] dst : "The destination to copy to"
@param [&in] src : "The source to copy from"
@param [in] src : "The source to copy from"
@param len : "The number of bytes to copy"
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
@require src != null || len == 0 : "Copying a null with non-zero length is invalid"
@require len == 0 || dst + len <= src || src + len <= dst : "Ranges may not overlap"
*>
macro void copy(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
@@ -335,12 +336,13 @@ macro void copy(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_alig
will always be inlined and never call memcopy
@param [&out] dst : "The destination to copy to"
@param [&in] src : "The source to copy from"
@param [in] src : "The source to copy from"
@param $len : "The number of bytes to copy"
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
@require src != null || len == 0 : "Copying a null with non-zero length is invalid"
@require $len == 0 || dst + $len <= src || src + $len <= dst : "Ranges may not overlap"
*>
macro void copy_inline(void* dst, void* src, usz $len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
@@ -352,11 +354,13 @@ macro void copy_inline(void* dst, void* src, usz $len, usz $dst_align = 0, usz $
Copy memory from src to dst but correctly handle the possibility of overlapping ranges.
@param [&out] dst : "The destination to copy to"
@param [&in] src : "The source to copy from"
@param [in] src : "The source to copy from"
@param len : "The number of bytes to copy"
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
@require src != null || len == 0 : "Moving a null with non-zero length is invalid"
*>
macro void move(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
{

View File

@@ -433,7 +433,7 @@ fn Allocator create_temp_allocator_on_demand() @private
if (!auto_create_temp)
{
auto_create_temp = true;
abort("Use '@pool_init()' to enable the temp allocator on a new thread. A pool is implicitly created only on the main thread.");
abort("Use '@pool_init()' to enable the temp allocator on a new thread. A temp allocator is only implicitly created on the main thread.");
}
return create_temp_allocator(base_allocator(), temp_allocator_size());
}

View File

@@ -55,6 +55,7 @@
- Crash resolving a method on `Foo[2]` when `Foo` is distinct #2042.
- Bug due to missing cast when doing `$i[$x] = $z`.
- Incorrectly allowed getting pointer to a macro #2049.
- &self not runtime null-checked in macro #1827.
### Stdlib changes
- `new_*` functions in general moved to version without `new_` prefix.

View File

@@ -2195,6 +2195,7 @@ Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v);
Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value);
Expr *expr_new_const_typeid(SourceSpan span, Type *type);
Expr *expr_new_const_string(SourceSpan span, const char *string);
Expr *expr_new_const_null(SourceSpan span, Type *type);
Expr *expr_new_const_initializer(SourceSpan span, Type *type, ConstInitializer *initializer);
const char *expr_kind_to_string(ExprKind kind);
bool expr_is_simple(Expr *expr, bool to_float);

View File

@@ -1035,6 +1035,19 @@ Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value)
return expr;
}
Expr *expr_new_const_null(SourceSpan span, Type *type)
{
Expr *expr = expr_calloc();
expr->expr_kind = EXPR_CONST;
expr->span = span;
expr->type = type;
ASSERT(type_flatten(type)->type_kind == TYPE_POINTER);
expr->const_expr.ptr = 0;
expr->const_expr.const_kind = CONST_POINTER;
expr->resolve_status = RESOLVE_DONE;
return expr;
}
Expr *expr_new_const_string(SourceSpan span, const char *string)
{
Expr *expr = expr_calloc();

View File

@@ -1821,7 +1821,7 @@ static inline bool sema_call_check_contract_param_match(SemaContext *context, De
{
if (param->var.not_null && expr_is_const_pointer(expr) && !expr->const_expr.ptr)
{
RETURN_SEMA_ERROR(expr, "You may not pass null to a '&' parameter.");
RETURN_SEMA_ERROR(expr, "You may not pass null to the '&' parameter.");
}
if (expr->expr_kind == EXPR_UNARY && expr->unary_expr.expr->expr_kind == EXPR_IDENTIFIER)
{
@@ -2211,15 +2211,37 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
BlockExit** block_exit_ref = CALLOCS(BlockExit*);
macro_context.block_exit_ref = block_exit_ref;
FOREACH(Decl *, param, params)
AstId assert_first = 0;
AstId* next = &assert_first;
FOREACH_IDX(idx, Decl *, param, params)
{
// Skip raw vararg
if (!param) continue;
if (!sema_add_local(&macro_context, param)) goto EXIT_FAIL;
if (param->var.init_expr && param->var.not_null)
{
Expr *expr = expr_variable(param);
Expr *binary = expr_new_expr(EXPR_BINARY, expr);
binary->binary_expr.left = exprid(expr);
binary->binary_expr.right = exprid(expr_new_const_null(expr->span, type_voidptr));
binary->binary_expr.operator = BINARYOP_NE;
if (!sema_analyse_expr_rhs(context, type_bool, binary, false, NULL, false)) goto EXIT_FAIL;
const char *string = struct_var && idx == 0 ? "Called a method on a null value." : "Passed null to a ref ('&') parameter.";
if (expr_is_const_bool(binary) && !binary->const_expr.b)
{
sema_error_at(context, param->var.init_expr->span, string);
goto EXIT_FAIL;
}
AstId assert_first = 0;
AstId* next = &assert_first;
Ast *assert = new_ast(AST_ASSERT_STMT, param->var.init_expr->span);
assert->assert_stmt.is_ensure = true;
assert->assert_stmt.expr = exprid(binary);
Expr *comment_expr = expr_new_const_string(expr->span, string);
assert->assert_stmt.message = exprid(comment_expr);
ast_append(&next, assert);
}
}
bool has_ensures = false;
if (!sema_analyse_contracts(&macro_context, docs, &next, call_expr->span, &has_ensures)) goto EXIT_FAIL;

View File

@@ -69,6 +69,8 @@ entry:
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 8, i1 false)
%0 = call i32 @test.Abc.add(ptr %x)
store i32 %0, ptr %a, align 4
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%1 = load i32, ptr %x, align 4
%ptradd = getelementptr inbounds i8, ptr %x, i64 4
%2 = load i32, ptr %ptradd, align 4
@@ -76,8 +78,10 @@ entry:
store i32 %add, ptr %b, align 4
store i32 100, ptr %f, align 4
call void @test.Foo.add(ptr %f)
%neq1 = icmp ne ptr %f, null
call void @llvm.assume(i1 %neq1)
%3 = load i32, ptr %f, align 4
%add1 = add i32 %3, 1
store i32 %add1, ptr %f, align 4
%add2 = add i32 %3, 1
store i32 %add2, ptr %f, align 4
ret void
}

View File

@@ -131,43 +131,51 @@ entry:
%i = alloca i32, align 4
%y = alloca i32, align 4
%a = alloca i32, align 4
%.anon2 = alloca i32, align 4
%i6 = alloca i32, align 4
%y7 = alloca ptr, align 8
%a8 = alloca i32, align 4
%.anon13 = alloca i32, align 4
%i17 = alloca i32, align 4
%y18 = alloca i32, align 4
%a19 = alloca i32, align 4
%.anon24 = alloca i32, align 4
%i28 = alloca i32, align 4
%y29 = alloca i32, align 4
%a30 = alloca i32, align 4
%.anon35 = alloca i32, align 4
%i39 = alloca i32, align 4
%y40 = alloca i32, align 4
%a41 = alloca i32, align 4
%.anon47 = alloca [5 x i32], align 16
%.anon48 = alloca i64, align 8
%i51 = alloca i64, align 8
%y52 = alloca i32, align 4
%.anon56 = alloca [5 x i32], align 16
%.anon57 = alloca i64, align 8
%i61 = alloca i64, align 8
%y62 = alloca i32, align 4
%.anon7 = alloca i32, align 4
%i11 = alloca i32, align 4
%y12 = alloca ptr, align 8
%a13 = alloca i32, align 4
%.anon20 = alloca i32, align 4
%i24 = alloca i32, align 4
%y25 = alloca i32, align 4
%a26 = alloca i32, align 4
%.anon33 = alloca i32, align 4
%i37 = alloca i32, align 4
%y38 = alloca i32, align 4
%a39 = alloca i32, align 4
%.anon46 = alloca i32, align 4
%i50 = alloca i32, align 4
%y51 = alloca i32, align 4
%a52 = alloca i32, align 4
%.anon59 = alloca [5 x i32], align 16
%.anon60 = alloca i64, align 8
%i63 = alloca i64, align 8
%y64 = alloca i32, align 4
%.anon68 = alloca [5 x i32], align 16
%.anon69 = alloca i64, align 8
%i73 = alloca i64, align 8
%y74 = alloca i32, align 4
%sretparam = alloca [5 x i32], align 4
%.anon66 = alloca i64, align 8
%i70 = alloca i64, align 8
%y71 = alloca i32, align 4
%y76 = alloca ptr, align 8
%.anon78 = alloca i64, align 8
%i82 = alloca i64, align 8
%y83 = alloca i32, align 4
%y90 = alloca ptr, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const.2, i32 12, i1 false)
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%neq1 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq1)
%ptradd = getelementptr inbounds i8, ptr %x, i64 4
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
%neq2 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq2)
%ptradd3 = getelementptr inbounds i8, ptr %x, i64 8
%0 = load i32, ptr %x, align 4
%1 = load i32, ptr %ptradd, align 4
%2 = load i32, ptr %ptradd1, align 4
%2 = load i32, ptr %ptradd3, align 4
call void (ptr, ...) @printf(ptr @.str.3, i32 %0, i32 %1, i32 %2)
%3 = call ptr @foo.call(ptr %x)
%neq4 = icmp ne ptr %3, null
call void @llvm.assume(i1 %neq4)
store i32 0, ptr %.anon, align 4
br label %loop.cond
@@ -181,6 +189,8 @@ loop.body: ; preds = %loop.cond
store i32 %5, ptr %i, align 4
%6 = load i32, ptr %.anon, align 4
store i32 %6, ptr %a, align 4
%neq5 = icmp ne ptr %3, null
call void @llvm.assume(i1 %neq5)
%7 = load i32, ptr %a, align 4
%sext = sext i32 %7 to i64
%ptroffset = getelementptr inbounds [4 x i8], ptr %3, i64 %sext
@@ -195,212 +205,238 @@ loop.body: ; preds = %loop.cond
br label %loop.cond
loop.exit: ; preds = %loop.cond
store i32 0, ptr %.anon2, align 4
br label %loop.cond3
%neq6 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq6)
store i32 0, ptr %.anon7, align 4
br label %loop.cond8
loop.cond3: ; preds = %loop.body5, %loop.exit
%12 = load i32, ptr %.anon2, align 4
%lt4 = icmp slt i32 %12, 3
br i1 %lt4, label %loop.body5, label %loop.exit12
loop.cond8: ; preds = %loop.body10, %loop.exit
%12 = load i32, ptr %.anon7, align 4
%lt9 = icmp slt i32 %12, 3
br i1 %lt9, label %loop.body10, label %loop.exit18
loop.body5: ; preds = %loop.cond3
%13 = load i32, ptr %.anon2, align 4
store i32 %13, ptr %i6, align 4
%14 = load i32, ptr %.anon2, align 4
store i32 %14, ptr %a8, align 4
%15 = load i32, ptr %a8, align 4
%sext9 = sext i32 %15 to i64
%ptroffset10 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext9
store ptr %ptroffset10, ptr %y7, align 8
%16 = load ptr, ptr %y7, align 8
loop.body10: ; preds = %loop.cond8
%13 = load i32, ptr %.anon7, align 4
store i32 %13, ptr %i11, align 4
%14 = load i32, ptr %.anon7, align 4
store i32 %14, ptr %a13, align 4
%neq14 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq14)
%15 = load i32, ptr %a13, align 4
%sext15 = sext i32 %15 to i64
%ptroffset16 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext15
store ptr %ptroffset16, ptr %y12, align 8
%16 = load ptr, ptr %y12, align 8
%17 = load i32, ptr %16, align 4
%add = add i32 %17, 1
store i32 %add, ptr %16, align 4
%18 = load ptr, ptr %y7, align 8
%19 = load i32, ptr %i6, align 4
%18 = load ptr, ptr %y12, align 8
%19 = load i32, ptr %i11, align 4
%20 = load i32, ptr %18, align 4
call void (ptr, ...) @printf(ptr @.str.5, i32 %19, i32 %20)
%21 = load i32, ptr %.anon2, align 4
%addnsw11 = add nsw i32 %21, 1
store i32 %addnsw11, ptr %.anon2, align 4
br label %loop.cond3
%21 = load i32, ptr %.anon7, align 4
%addnsw17 = add nsw i32 %21, 1
store i32 %addnsw17, ptr %.anon7, align 4
br label %loop.cond8
loop.exit12: ; preds = %loop.cond3
store i32 0, ptr %.anon13, align 4
br label %loop.cond14
loop.exit18: ; preds = %loop.cond8
%neq19 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq19)
store i32 0, ptr %.anon20, align 4
br label %loop.cond21
loop.cond14: ; preds = %loop.body16, %loop.exit12
%22 = load i32, ptr %.anon13, align 4
%lt15 = icmp slt i32 %22, 3
br i1 %lt15, label %loop.body16, label %loop.exit23
loop.cond21: ; preds = %loop.body23, %loop.exit18
%22 = load i32, ptr %.anon20, align 4
%lt22 = icmp slt i32 %22, 3
br i1 %lt22, label %loop.body23, label %loop.exit31
loop.body16: ; preds = %loop.cond14
%23 = load i32, ptr %.anon13, align 4
store i32 %23, ptr %i17, align 4
%24 = load i32, ptr %.anon13, align 4
store i32 %24, ptr %a19, align 4
%25 = load i32, ptr %a19, align 4
%sext20 = sext i32 %25 to i64
%ptroffset21 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext20
%26 = load i32, ptr %ptroffset21, align 4
store i32 %26, ptr %y18, align 4
%27 = load i32, ptr %i17, align 4
%28 = load i32, ptr %y18, align 4
loop.body23: ; preds = %loop.cond21
%23 = load i32, ptr %.anon20, align 4
store i32 %23, ptr %i24, align 4
%24 = load i32, ptr %.anon20, align 4
store i32 %24, ptr %a26, align 4
%neq27 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq27)
%25 = load i32, ptr %a26, align 4
%sext28 = sext i32 %25 to i64
%ptroffset29 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext28
%26 = load i32, ptr %ptroffset29, align 4
store i32 %26, ptr %y25, align 4
%27 = load i32, ptr %i24, align 4
%28 = load i32, ptr %y25, align 4
call void (ptr, ...) @printf(ptr @.str.6, i32 %27, i32 %28)
%29 = load i32, ptr %.anon13, align 4
%addnsw22 = add nsw i32 %29, 1
store i32 %addnsw22, ptr %.anon13, align 4
br label %loop.cond14
%29 = load i32, ptr %.anon20, align 4
%addnsw30 = add nsw i32 %29, 1
store i32 %addnsw30, ptr %.anon20, align 4
br label %loop.cond21
loop.exit23: ; preds = %loop.cond14
store i32 0, ptr %.anon24, align 4
br label %loop.cond25
loop.exit31: ; preds = %loop.cond21
%neq32 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq32)
store i32 0, ptr %.anon33, align 4
br label %loop.cond34
loop.cond25: ; preds = %loop.body27, %loop.exit23
%30 = load i32, ptr %.anon24, align 4
%lt26 = icmp slt i32 %30, 3
br i1 %lt26, label %loop.body27, label %loop.exit34
loop.cond34: ; preds = %loop.body36, %loop.exit31
%30 = load i32, ptr %.anon33, align 4
%lt35 = icmp slt i32 %30, 3
br i1 %lt35, label %loop.body36, label %loop.exit44
loop.body27: ; preds = %loop.cond25
%31 = load i32, ptr %.anon24, align 4
store i32 %31, ptr %i28, align 4
%32 = load i32, ptr %.anon24, align 4
store i32 %32, ptr %a30, align 4
%33 = load i32, ptr %a30, align 4
%sext31 = sext i32 %33 to i64
%ptroffset32 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext31
%34 = load i32, ptr %ptroffset32, align 4
store i32 %34, ptr %y29, align 4
%35 = load i32, ptr %i28, align 4
%36 = load i32, ptr %y29, align 4
loop.body36: ; preds = %loop.cond34
%31 = load i32, ptr %.anon33, align 4
store i32 %31, ptr %i37, align 4
%32 = load i32, ptr %.anon33, align 4
store i32 %32, ptr %a39, align 4
%neq40 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq40)
%33 = load i32, ptr %a39, align 4
%sext41 = sext i32 %33 to i64
%ptroffset42 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext41
%34 = load i32, ptr %ptroffset42, align 4
store i32 %34, ptr %y38, align 4
%35 = load i32, ptr %i37, align 4
%36 = load i32, ptr %y38, align 4
call void (ptr, ...) @printf(ptr @.str.7, i32 %35, i32 %36)
%37 = load i32, ptr %.anon24, align 4
%addnsw33 = add nsw i32 %37, 1
store i32 %addnsw33, ptr %.anon24, align 4
br label %loop.cond25
%37 = load i32, ptr %.anon33, align 4
%addnsw43 = add nsw i32 %37, 1
store i32 %addnsw43, ptr %.anon33, align 4
br label %loop.cond34
loop.exit34: ; preds = %loop.cond25
store i32 0, ptr %.anon35, align 4
br label %loop.cond36
loop.exit44: ; preds = %loop.cond34
%neq45 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq45)
store i32 0, ptr %.anon46, align 4
br label %loop.cond47
loop.cond36: ; preds = %loop.body38, %loop.exit34
%38 = load i32, ptr %.anon35, align 4
%lt37 = icmp slt i32 %38, 3
br i1 %lt37, label %loop.body38, label %loop.exit46
loop.cond47: ; preds = %loop.body49, %loop.exit44
%38 = load i32, ptr %.anon46, align 4
%lt48 = icmp slt i32 %38, 3
br i1 %lt48, label %loop.body49, label %loop.exit58
loop.body38: ; preds = %loop.cond36
%39 = load i32, ptr %.anon35, align 4
store i32 %39, ptr %i39, align 4
%40 = load i32, ptr %.anon35, align 4
store i32 %40, ptr %a41, align 4
%41 = load i32, ptr %a41, align 4
%sext42 = sext i32 %41 to i64
%ptroffset43 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext42
%42 = load i32, ptr %ptroffset43, align 4
store i32 %42, ptr %y40, align 4
%43 = load i32, ptr %i39, align 4
%44 = load i32, ptr %y40, align 4
loop.body49: ; preds = %loop.cond47
%39 = load i32, ptr %.anon46, align 4
store i32 %39, ptr %i50, align 4
%40 = load i32, ptr %.anon46, align 4
store i32 %40, ptr %a52, align 4
%neq53 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq53)
%41 = load i32, ptr %a52, align 4
%sext54 = sext i32 %41 to i64
%ptroffset55 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext54
%42 = load i32, ptr %ptroffset55, align 4
store i32 %42, ptr %y51, align 4
%43 = load i32, ptr %i50, align 4
%44 = load i32, ptr %y51, align 4
call void (ptr, ...) @printf(ptr @.str.8, i32 %43, i32 %44)
%45 = load i32, ptr %i39, align 4
%add44 = add i32 %45, 1
store i32 %add44, ptr %i39, align 4
%46 = load i32, ptr %.anon35, align 4
%addnsw45 = add nsw i32 %46, 1
store i32 %addnsw45, ptr %.anon35, align 4
br label %loop.cond36
%45 = load i32, ptr %i50, align 4
%add56 = add i32 %45, 1
store i32 %add56, ptr %i50, align 4
%46 = load i32, ptr %.anon46, align 4
%addnsw57 = add nsw i32 %46, 1
store i32 %addnsw57, ptr %.anon46, align 4
br label %loop.cond47
loop.exit46: ; preds = %loop.cond36
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon47, ptr align 16 @.__const.9, i32 20, i1 false)
store i64 0, ptr %.anon48, align 8
br label %loop.cond49
loop.exit58: ; preds = %loop.cond47
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon59, ptr align 16 @.__const.9, i32 20, i1 false)
store i64 0, ptr %.anon60, align 8
br label %loop.cond61
loop.cond49: ; preds = %loop.body50, %loop.exit46
%47 = load i64, ptr %.anon48, align 8
loop.cond61: ; preds = %loop.body62, %loop.exit58
%47 = load i64, ptr %.anon60, align 8
%gt = icmp ugt i64 5, %47
br i1 %gt, label %loop.body50, label %loop.exit55
br i1 %gt, label %loop.body62, label %loop.exit67
loop.body50: ; preds = %loop.cond49
%48 = load i64, ptr %.anon48, align 8
store i64 %48, ptr %i51, align 8
%49 = load i64, ptr %.anon48, align 8
%ptroffset53 = getelementptr inbounds [4 x i8], ptr %.anon47, i64 %49
%50 = load i32, ptr %ptroffset53, align 4
store i32 %50, ptr %y52, align 4
%51 = load i64, ptr %i51, align 8
%52 = load i32, ptr %y52, align 4
loop.body62: ; preds = %loop.cond61
%48 = load i64, ptr %.anon60, align 8
store i64 %48, ptr %i63, align 8
%49 = load i64, ptr %.anon60, align 8
%ptroffset65 = getelementptr inbounds [4 x i8], ptr %.anon59, i64 %49
%50 = load i32, ptr %ptroffset65, align 4
store i32 %50, ptr %y64, align 4
%51 = load i64, ptr %i63, align 8
%52 = load i32, ptr %y64, align 4
call void (ptr, ...) @printf(ptr @.str.10, i64 %51, i32 %52)
%53 = load i64, ptr %i51, align 8
%add54 = add i64 %53, 1
store i64 %add54, ptr %i51, align 8
%54 = load i64, ptr %.anon48, align 8
%53 = load i64, ptr %i63, align 8
%add66 = add i64 %53, 1
store i64 %add66, ptr %i63, align 8
%54 = load i64, ptr %.anon60, align 8
%addnuw = add nuw i64 %54, 1
store i64 %addnuw, ptr %.anon48, align 8
br label %loop.cond49
store i64 %addnuw, ptr %.anon60, align 8
br label %loop.cond61
loop.exit55: ; preds = %loop.cond49
call void @foo.getFields(ptr sret([5 x i32]) align 4 %.anon56)
store i64 0, ptr %.anon57, align 8
br label %loop.cond58
loop.exit67: ; preds = %loop.cond61
call void @foo.getFields(ptr sret([5 x i32]) align 4 %.anon68)
store i64 0, ptr %.anon69, align 8
br label %loop.cond70
loop.cond58: ; preds = %loop.body60, %loop.exit55
%55 = load i64, ptr %.anon57, align 8
%gt59 = icmp ugt i64 5, %55
br i1 %gt59, label %loop.body60, label %loop.exit65
loop.cond70: ; preds = %loop.body72, %loop.exit67
%55 = load i64, ptr %.anon69, align 8
%gt71 = icmp ugt i64 5, %55
br i1 %gt71, label %loop.body72, label %loop.exit77
loop.body60: ; preds = %loop.cond58
%56 = load i64, ptr %.anon57, align 8
store i64 %56, ptr %i61, align 8
%57 = load i64, ptr %.anon57, align 8
%ptroffset63 = getelementptr inbounds [4 x i8], ptr %.anon56, i64 %57
%58 = load i32, ptr %ptroffset63, align 4
store i32 %58, ptr %y62, align 4
%59 = load i64, ptr %i61, align 8
%60 = load i32, ptr %y62, align 4
loop.body72: ; preds = %loop.cond70
%56 = load i64, ptr %.anon69, align 8
store i64 %56, ptr %i73, align 8
%57 = load i64, ptr %.anon69, align 8
%ptroffset75 = getelementptr inbounds [4 x i8], ptr %.anon68, i64 %57
%58 = load i32, ptr %ptroffset75, align 4
store i32 %58, ptr %y74, align 4
%59 = load i64, ptr %i73, align 8
%60 = load i32, ptr %y74, align 4
call void (ptr, ...) @printf(ptr @.str.11, i64 %59, i32 %60)
%61 = load i64, ptr %.anon57, align 8
%addnuw64 = add nuw i64 %61, 1
store i64 %addnuw64, ptr %.anon57, align 8
br label %loop.cond58
%61 = load i64, ptr %.anon69, align 8
%addnuw76 = add nuw i64 %61, 1
store i64 %addnuw76, ptr %.anon69, align 8
br label %loop.cond70
loop.exit65: ; preds = %loop.cond58
loop.exit77: ; preds = %loop.cond70
call void @foo.getFields(ptr sret([5 x i32]) align 4 %sretparam)
store i64 0, ptr %.anon66, align 8
br label %loop.cond67
store i64 0, ptr %.anon78, align 8
br label %loop.cond79
loop.cond67: ; preds = %loop.body69, %loop.exit65
%62 = load i64, ptr %.anon66, align 8
%gt68 = icmp ugt i64 5, %62
br i1 %gt68, label %loop.body69, label %loop.exit74
loop.cond79: ; preds = %loop.body81, %loop.exit77
%62 = load i64, ptr %.anon78, align 8
%gt80 = icmp ugt i64 5, %62
br i1 %gt80, label %loop.body81, label %loop.exit86
loop.body69: ; preds = %loop.cond67
%63 = load i64, ptr %.anon66, align 8
store i64 %63, ptr %i70, align 8
%64 = load i64, ptr %.anon66, align 8
%ptroffset72 = getelementptr inbounds [4 x i8], ptr %sretparam, i64 %64
%65 = load i32, ptr %ptroffset72, align 4
store i32 %65, ptr %y71, align 4
%66 = load i64, ptr %i70, align 8
%67 = load i32, ptr %y71, align 4
loop.body81: ; preds = %loop.cond79
%63 = load i64, ptr %.anon78, align 8
store i64 %63, ptr %i82, align 8
%64 = load i64, ptr %.anon78, align 8
%ptroffset84 = getelementptr inbounds [4 x i8], ptr %sretparam, i64 %64
%65 = load i32, ptr %ptroffset84, align 4
store i32 %65, ptr %y83, align 4
%66 = load i64, ptr %i82, align 8
%67 = load i32, ptr %y83, align 4
call void (ptr, ...) @printf(ptr @.str.12, i64 %66, i32 %67)
%68 = load i64, ptr %.anon66, align 8
%addnuw73 = add nuw i64 %68, 1
store i64 %addnuw73, ptr %.anon66, align 8
br label %loop.cond67
%68 = load i64, ptr %.anon78, align 8
%addnuw85 = add nuw i64 %68, 1
store i64 %addnuw85, ptr %.anon78, align 8
br label %loop.cond79
loop.exit74: ; preds = %loop.cond67
%ptradd75 = getelementptr inbounds i8, ptr %x, i64 4
loop.exit86: ; preds = %loop.cond79
%neq87 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq87)
%neq88 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq88)
%ptradd89 = getelementptr inbounds i8, ptr %x, i64 4
%69 = load i32, ptr %x, align 4
%70 = load i32, ptr %ptradd75, align 4
%70 = load i32, ptr %ptradd89, align 4
call void (ptr, ...) @printf(ptr @.str.13, i32 %69, i32 %70)
%ptradd77 = getelementptr inbounds i8, ptr %x, i64 4
store ptr %ptradd77, ptr %y76, align 8
%71 = load ptr, ptr %y76, align 8
%neq91 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq91)
%ptradd92 = getelementptr inbounds i8, ptr %x, i64 4
store ptr %ptradd92, ptr %y90, align 8
%71 = load ptr, ptr %y90, align 8
%72 = load i32, ptr %71, align 4
%add78 = add i32 %72, 1
store i32 %add78, ptr %71, align 4
%ptradd79 = getelementptr inbounds i8, ptr %x, i64 4
%add93 = add i32 %72, 1
store i32 %add93, ptr %71, align 4
%neq94 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq94)
%neq95 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq95)
%ptradd96 = getelementptr inbounds i8, ptr %x, i64 4
%73 = load i32, ptr %x, align 4
%74 = load i32, ptr %ptradd79, align 4
%74 = load i32, ptr %ptradd96, align 4
call void (ptr, ...) @printf(ptr @.str.14, i32 %73, i32 %74)
ret void
}

View File

@@ -45,6 +45,8 @@ entry:
%0 = insertvalue %"int[]" undef, ptr %i, 0
%1 = insertvalue %"int[]" %0, i64 3, 1
store %"int[]" %1, ptr %x, align 8
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd, align 8
store i64 0, ptr %.anon, align 8
@@ -58,6 +60,8 @@ loop.cond: ; preds = %entry
loop.body: ; preds = %loop.cond
%4 = load i64, ptr %.anon, align 8
store i64 %4, ptr %index, align 8
%neq1 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq1)
%5 = load ptr, ptr %x, align 8
%6 = load i64, ptr %index, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %6
@@ -65,19 +69,17 @@ loop.body: ; preds = %loop.cond
store i32 %7, ptr %f, align 4
%8 = load i32, ptr %f, align 4
%9 = call i32 (ptr, ...) @printf(ptr @.str, i32 %8)
br label %loop.body1
br label %loop.body2
loop.body1: ; preds = %loop.body
loop.body2: ; preds = %loop.body
br label %loop.exit
loop.exit: ; preds = %loop.body1, %loop.cond
loop.exit: ; preds = %loop.body2, %loop.cond
ret void
}
; Function Attrs:
declare i32 @printf(ptr, ...) #0
; Function Attrs:
define i32 @main(i32 %0, ptr %1) #0 {
entry:
call void @test.main()

View File

@@ -51,6 +51,8 @@ entry:
%0 = insertvalue %"int[]" undef, ptr %i, 0
%1 = insertvalue %"int[]" %0, i64 3, 1
store %"int[]" %1, ptr %x, align 8
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd, align 8
store i64 0, ptr %.anon, align 8
@@ -64,6 +66,8 @@ loop.cond: ; preds = %entry
loop.body: ; preds = %loop.cond
%4 = load i64, ptr %.anon, align 8
store i64 %4, ptr %index, align 8
%neq1 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq1)
%5 = load ptr, ptr %x, align 8
%6 = load i64, ptr %index, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %6
@@ -71,12 +75,12 @@ loop.body: ; preds = %loop.cond
store i32 %7, ptr %f, align 4
%8 = load i32, ptr %f, align 4
%9 = call i32 (ptr, ...) @printf(ptr @.str, i32 %8)
br label %loop.body1
br label %loop.body2
loop.body1: ; preds = %loop.body
loop.body2: ; preds = %loop.body
br label %loop.exit
loop.exit: ; preds = %loop.body1, %loop.cond
loop.exit: ; preds = %loop.body2, %loop.cond
ret void
}

View File

@@ -45,6 +45,8 @@ entry:
%0 = insertvalue %"int[]" undef, ptr %i, 0
%1 = insertvalue %"int[]" %0, i64 3, 1
store %"int[]" %1, ptr %x, align 8
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd, align 8
store i64 %2, ptr %.anon, align 8
@@ -61,6 +63,8 @@ loop.body: ; preds = %loop.cond
store i64 %subnuw, ptr %.anon, align 8
%5 = load i64, ptr %.anon, align 8
store i64 %5, ptr %index, align 8
%neq1 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq1)
%6 = load ptr, ptr %x, align 8
%7 = load i64, ptr %index, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %6, i64 %7
@@ -68,12 +72,12 @@ loop.body: ; preds = %loop.cond
store i32 %8, ptr %f, align 4
%9 = load i32, ptr %f, align 4
%10 = call i32 (ptr, ...) @printf(ptr @.str, i32 %9)
br label %loop.body1
br label %loop.body2
loop.body1: ; preds = %loop.body
loop.body2: ; preds = %loop.body
br label %loop.exit
loop.exit: ; preds = %loop.body1, %loop.cond
loop.exit: ; preds = %loop.body2, %loop.cond
ret void
}

View File

@@ -44,6 +44,8 @@ entry:
%0 = insertvalue %"int[]" undef, ptr %i, 0
%1 = insertvalue %"int[]" %0, i64 3, 1
store %"int[]" %1, ptr %x, align 8
%neq = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq)
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
%2 = load i64, ptr %ptradd, align 8
store i64 %2, ptr %.anon, align 8
@@ -60,6 +62,8 @@ loop.body: ; preds = %loop.cond
store i64 %subnuw, ptr %.anon, align 8
%5 = load i64, ptr %.anon, align 8
store i64 %5, ptr %index, align 8
%neq1 = icmp ne ptr %x, null
call void @llvm.assume(i1 %neq1)
%6 = load ptr, ptr %x, align 8
%7 = load i64, ptr %index, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %6, i64 %7
@@ -67,11 +71,11 @@ loop.body: ; preds = %loop.cond
store i32 %8, ptr %f, align 4
%9 = load i32, ptr %f, align 4
%10 = call i32 (ptr, ...) @printf(ptr @.str, i32 %9)
br label %loop.body1
br label %loop.body2
loop.body1: ; preds = %loop.body
loop.body2: ; preds = %loop.body
br label %loop.exit
loop.exit: ; preds = %loop.body1, %loop.cond
loop.exit: ; preds = %loop.body2, %loop.cond
ret void
}

View File

@@ -0,0 +1,15 @@
module temp_mem;
fn void test_realloc() @test
{
void* mem = tmalloc(10);
for (int i = 1; i < 4096 * 32 * 16 * 2; i <<= 1)
{
mem = mem::trealloc(mem, i);
}
for (int i = 4096 * 32 * 16 * 2; i > 2; i >>= 1)
{
mem = mem::trealloc(mem, i);
(void)tmalloc(1235);
}
}