diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 8a3bf686d..8ce882e55 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4509,6 +4509,14 @@ static inline void gencontext_emit_expression_list_expr(GenContext *context, BEV static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value, Type *type, Ast **stmts) { + // First case - an empty block + unsigned count = vec_size(stmts); + if (!count) + { + llvm_value_set(be_value, NULL, type_void); + return; + } + Type *type_lowered = type_lowering(type); LLVMValueRef old_ret_out = context->return_out; LLVMBasicBlockRef saved_block_return_exit = context->block_return_exit; @@ -4533,23 +4541,65 @@ static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value context->error_var = NULL; context->catch_block = NULL; - VECEACH(stmts, i) + // Process all but the last statement. + for (unsigned i = 0; i < count - 1; i++) { llvm_emit_stmt(context, stmts[i]); } + + Ast *last_stmt = stmts[count - 1]; + + do + { + // Do we have more than one exit? + // Then follow the normal path. + if (!llvm_basic_block_is_unused(expr_block)) break; + + // Do we have a void function? That's the only + // possible case if the last statement isn't return. + if (last_stmt->ast_kind != AST_RETURN_STMT) break; + + // Defers? In that case we also use the default behaviour. + // We might optimize this later. + if (last_stmt->return_stmt.defer) break; + + Expr *ret_expr = last_stmt->return_stmt.expr; + + // If this is a void return, we can just skip here! + if (!ret_expr) + { + llvm_value_set(be_value, NULL, type_void); + goto DONE; + } + + // Failable? Then we use the normal path + if (IS_FAILABLE(ret_expr)) break; + + // Optimization, emit directly to value + llvm_emit_expr(context, be_value, ret_expr); + // And remove the alloca + LLVMInstructionRemoveFromParent(context->return_out); + goto DONE; + + } while (0); + + // Emit the last statement + llvm_emit_stmt(context, last_stmt); + + // In the case of a void with no return, then this may be true. + if (llvm_basic_block_is_unused(expr_block)) + { + // Skip the expr block. + assert(!context->return_out); + llvm_value_set(be_value, NULL, type_void); + goto DONE; + } + llvm_emit_br(context, expr_block); // Emit the exit block. llvm_emit_block(context, expr_block); - context->return_out = old_ret_out; - context->catch_block = error_block; - context->error_var = error_out; - context->block_return_exit = saved_block_return_exit; - context->block_failable_exit = saved_block_failable_exit; - context->block_error_var = saved_block_error; - context->in_block--; - if (return_out) { llvm_value_set_address(be_value, return_out, type_lowered); @@ -4558,6 +4608,16 @@ static inline void llvm_emit_return_block(GenContext *context, BEValue *be_value { llvm_value_set(be_value, NULL, type_void); } + +DONE: + context->return_out = old_ret_out; + context->catch_block = error_block; + context->error_var = error_out; + context->block_return_exit = saved_block_return_exit; + context->block_failable_exit = saved_block_failable_exit; + context->block_error_var = saved_block_error; + context->in_block--; + } static inline void llvm_emit_expr_block(GenContext *context, BEValue *be_value, Expr *expr) diff --git a/src/version.h b/src/version.h index 15a1c727d..fdca69187 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "PRE.3" \ No newline at end of file +#define COMPILER_VERSION "PRE.4" \ No newline at end of file diff --git a/test/test_suite/compile_time/typeof_example.c3t b/test/test_suite/compile_time/typeof_example.c3t index a8d8ea5a3..f00a26baf 100644 --- a/test/test_suite/compile_time/typeof_example.c3t +++ b/test/test_suite/compile_time/typeof_example.c3t @@ -17,50 +17,38 @@ fn void main() // #expect: typeof_example.ll - %f = alloca float, align 4 - %i = alloca i32, align 4 - %value = alloca float, align 4 - %blockret = alloca i32, align 4 - %temp = alloca float, align 4 - %result = alloca i32*, align 8 - %f2 = alloca float, align 4 - %value1 = alloca i32, align 4 - %blockret2 = alloca float, align 4 - %temp3 = alloca i32, align 4 - %result4 = alloca float*, align 8 - store float 1.000000e+02, float* %f, align 4 - %0 = load float, float* %f, align 4 - store float %0, float* %value, align 4 - %1 = load float, float* %value, align 4 - store float %1, float* %temp, align 4 - %ptrptr = bitcast float* %temp to i32* - store i32* %ptrptr, i32** %result, align 8 - %2 = load i32*, i32** %result, align 8 - %3 = load i32, i32* %2, align 8 - store i32 %3, i32* %blockret, align 4 - br label %expr_block.exit - -expr_block.exit: - %4 = load i32, i32* %blockret, align 4 - store i32 %4, i32* %i, align 4 - %5 = load i32, i32* %i, align 4 - store i32 %5, i32* %value1, align 4 - %6 = load i32, i32* %value1, align 4 - store i32 %6, i32* %temp3, align 4 - %ptrptr5 = bitcast i32* %temp3 to float* - store float* %ptrptr5, float** %result4, align 8 - %7 = load float*, float** %result4, align 8 - %8 = load float, float* %7, align 8 - store float %8, float* %blockret2, align 4 - br label %expr_block.exit6 - -expr_block.exit6: - %9 = load float, float* %blockret2, align 4 - store float %9, float* %f2, align 4 - %10 = load float, float* %f, align 4 - %fpfpext = fpext float %10 to double - %11 = load i32, i32* %i, align 4 - %12 = load float, float* %f2, align 4 - %fpfpext7 = fpext float %12 to double - call void (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %11, double %fpfpext7) - ret void \ No newline at end of file + %f = alloca float, align 4 + %i = alloca i32, align 4 + %value = alloca float, align 4 + %temp = alloca float, align 4 + %result = alloca i32*, align 8 + %f2 = alloca float, align 4 + %value1 = alloca i32, align 4 + %temp2 = alloca i32, align 4 + %result3 = alloca float*, align 8 + store float 1.000000e+02, float* %f, align 4 + %0 = load float, float* %f, align 4 + store float %0, float* %value, align 4 + %1 = load float, float* %value, align 4 + store float %1, float* %temp, align 4 + %ptrptr = bitcast float* %temp to i32* + store i32* %ptrptr, i32** %result, align 8 + %2 = load i32*, i32** %result, align 8 + %3 = load i32, i32* %2, align 8 + store i32 %3, i32* %i, align 4 + %4 = load i32, i32* %i, align 4 + store i32 %4, i32* %value1, align 4 + %5 = load i32, i32* %value1, align 4 + store i32 %5, i32* %temp2, align 4 + %ptrptr4 = bitcast i32* %temp2 to float* + store float* %ptrptr4, float** %result3, align 8 + %6 = load float*, float** %result3, align 8 + %7 = load float, float* %6, align 8 + store float %7, float* %f2, align 4 + %8 = load float, float* %f, align 4 + %fpfpext = fpext float %8 to double + %9 = load i32, i32* %i, align 4 + %10 = load float, float* %f2, align 4 + %fpfpext5 = fpext float %10 to double + call void (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %9, double %fpfpext5) + ret void \ No newline at end of file diff --git a/test/test_suite/from_docs/examples_macro_function.c3t b/test/test_suite/from_docs/examples_macro_function.c3t index d1a73e8ce..b5096cb80 100644 --- a/test/test_suite/from_docs/examples_macro_function.c3t +++ b/test/test_suite/from_docs/examples_macro_function.c3t @@ -39,7 +39,6 @@ entry: %b = alloca i32, align 4 %a1 = alloca i32 (i32)*, align 8 %b2 = alloca i32, align 4 - %blockret = alloca i32, align 4 store i32 2, i32* %a, align 4 store i32 3, i32* %b, align 4 store i32 (i32)* @example.square, i32 (i32)** %a1, align 8 @@ -47,14 +46,9 @@ entry: %0 = load i32 (i32)*, i32 (i32)** %a1, align 8 %1 = load i32, i32* %b2, align 4 %2 = call i32 %0(i32 %1) - store i32 %2, i32* %blockret, align 4 - br label %expr_block.exit - -expr_block.exit: ; preds = %entry - %3 = load i32, i32* %blockret, align 4 - %4 = load i32, i32* %a, align 4 - %add = add i32 %3, %4 - %5 = load i32, i32* %b, align 4 - %add3 = add i32 %add, %5 + %3 = load i32, i32* %a, align 4 + %add = add i32 %2, %3 + %4 = load i32, i32* %b, align 4 + %add3 = add i32 %add, %4 ret i32 %add3 } \ No newline at end of file diff --git a/test/test_suite/macros/macro_with_body.c3t b/test/test_suite/macros/macro_with_body.c3t index 7d59e3f20..76af6d816 100644 --- a/test/test_suite/macros/macro_with_body.c3t +++ b/test/test_suite/macros/macro_with_body.c3t @@ -83,20 +83,17 @@ define void @main() %6 = load i32, i32* %x, align 4 %7 = load i32, i32* %dy, align 4 %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i32 0, i32 0), i32 %6, i32 %7) - br label %expr_block.exit - -expr_block.exit: store i32 10, i32* %times, align 4 store i32 0, i32* %i, align 4 br label %for.cond -for.cond: +for.cond: ; preds = %for.inc, %entry %9 = load i32, i32* %i, align 4 %10 = load i32, i32* %times, align 4 %lt = icmp slt i32 %9, %10 br i1 %lt, label %for.body, label %for.exit -for.body: +for.body: ; preds = %for.cond %11 = load i32, i32* %i, align 4 %add = add i32 %11, 1 store i32 %add, i32* %loop, align 4 @@ -104,14 +101,12 @@ for.body: %13 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.1, i32 0, i32 0), i32 %12) br label %for.inc -for.inc: +for.inc: ; preds = %for.body %14 = load i32, i32* %i, align 4 %add1 = add i32 %14, 1 store i32 %add1, i32* %i, align 4 br label %for.cond -for.exit: - br label %expr_block.exit2 - -expr_block.exit2: +for.exit: ; preds = %for.cond ret void +} diff --git a/test/test_suite/macros/type_params.c3t b/test/test_suite/macros/type_params.c3t index 4354361a5..2af84ec15 100644 --- a/test/test_suite/macros/type_params.c3t +++ b/test/test_suite/macros/type_params.c3t @@ -19,48 +19,24 @@ fn void test() /* #expect: type_params.ll %x = alloca i32, align 4 - %blockret = alloca i32, align 4 %a = alloca i32, align 4 %d = alloca double, align 8 - %blockret1 = alloca double, align 8 - %a2 = alloca double, align 8 + %a1 = alloca double, align 8 %d2 = alloca double, align 8 - %blockret4 = alloca double, align 8 - %a5 = alloca double, align 8 + %a2 = alloca double, align 8 %z = alloca i16, align 2 - %blockret7 = alloca i16, align 2 - %a8 = alloca i16, align 2 + %a3 = alloca i16, align 2 store i32 0, i32* %a, align 4 %0 = load i32, i32* %a, align 4 - store i32 %0, i32* %blockret, align 4 - br label %expr_block.exit - -expr_block.exit: ; preds = %entry - %1 = load i32, i32* %blockret, align 4 - store i32 %1, i32* %x, align 4 + store i32 %0, i32* %x, align 4 + store double 0.000000e+00, double* %a1, align 8 + %1 = load double, double* %a1, align 8 + store double %1, double* %d, align 8 store double 0.000000e+00, double* %a2, align 8 %2 = load double, double* %a2, align 8 - store double %2, double* %blockret1, align 8 - br label %expr_block.exit3 - -expr_block.exit3: ; preds = %expr_block.exit - %3 = load double, double* %blockret1, align 8 - store double %3, double* %d, align 8 - store double 0.000000e+00, double* %a5, align 8 - %4 = load double, double* %a5, align 8 - store double %4, double* %blockret4, align 8 - br label %expr_block.exit6 - -expr_block.exit6: ; preds = %expr_block.exit3 - %5 = load double, double* %blockret4, align 8 - store double %5, double* %d2, align 8 - store i16 0, i16* %a8, align 2 - %6 = load i16, i16* %a8, align 2 - store i16 %6, i16* %blockret7, align 2 - br label %expr_block.exit9 - -expr_block.exit9: ; preds = %expr_block.exit6 - %7 = load i16, i16* %blockret7, align 2 - store i16 %7, i16* %z, align 2 + store double %2, double* %d2, align 8 + store i16 0, i16* %a3, align 2 + %3 = load i16, i16* %a3, align 2 + store i16 %3, i16* %z, align 2 ret void } diff --git a/test/test_suite/macros/userland_bitcast.c3t b/test/test_suite/macros/userland_bitcast.c3t index 36e230cf1..6cc4c1830 100644 --- a/test/test_suite/macros/userland_bitcast.c3t +++ b/test/test_suite/macros/userland_bitcast.c3t @@ -87,7 +87,6 @@ entry: %x = alloca i16, align 2 %z = alloca %Foo, align 2 %expr = alloca %Foo, align 2 - %blockret = alloca i64, align 8 %x1 = alloca i64, align 8 %b = alloca i16*, align 8 %to = alloca i16*, align 8 @@ -131,12 +130,7 @@ for.inc: ; preds = %for.body for.exit: ; preds = %for.cond %12 = load i64, i64* %x1, align 8 - store i64 %12, i64* %blockret, align 8 - br label %expr_block.exit - -expr_block.exit: ; preds = %for.exit - %13 = load i64, i64* %blockret, align 8 - ret i64 %13 + ret i64 %12 } ; Function Attrs: nounwind @@ -144,7 +138,6 @@ define i32 @userland_bitcast.test(float %0) #0 { entry: %x = alloca float, align 4 %expr = alloca float, align 4 - %blockret = alloca [4 x i8], align 1 %x1 = alloca [4 x i8], align 1 %b = alloca i8*, align 8 %to = alloca i8*, align 8 @@ -183,17 +176,11 @@ for.inc: ; preds = %for.body br label %for.cond for.exit: ; preds = %for.cond - %9 = bitcast [4 x i8]* %blockret to i8* + %9 = bitcast i32* %tempcoerce to i8* %10 = bitcast [4 x i8]* %x1 to i8* - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %9, i8* align 1 %10, i32 4, i1 false) - br label %expr_block.exit - -expr_block.exit: ; preds = %for.exit - %11 = bitcast i32* %tempcoerce to i8* - %12 = bitcast [4 x i8]* %blockret to i8* - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %11, i8* align 1 %12, i32 4, i1 false) - %13 = load i32, i32* %tempcoerce, align 4 - ret i32 %13 + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %9, i8* align 1 %10, i32 4, i1 false) + %11 = load i32, i32* %tempcoerce, align 4 + ret i32 %11 } ; Function Attrs: nounwind @@ -202,33 +189,29 @@ entry: %f = alloca float, align 4 %i = alloca i32, align 4 %expr = alloca float, align 4 - %blockret = alloca i32, align 4 %x = alloca i32, align 4 %b = alloca i32*, align 8 %to = alloca i32*, align 8 %i1 = alloca i64, align 8 %f2 = alloca float, align 4 %expr3 = alloca i32, align 4 - %blockret4 = alloca float, align 4 - %x5 = alloca float, align 4 - %b6 = alloca i32*, align 8 - %to7 = alloca i32*, align 8 - %i9 = alloca i64, align 8 + %x4 = alloca float, align 4 + %b5 = alloca i32*, align 8 + %to6 = alloca i32*, align 8 + %i8 = alloca i64, align 8 %d = alloca double, align 8 %l = alloca i64, align 8 - %expr20 = alloca double, align 8 - %blockret21 = alloca i64, align 8 - %x22 = alloca i64, align 8 - %b23 = alloca i64*, align 8 - %to25 = alloca i64*, align 8 - %i26 = alloca i64, align 8 + %expr18 = alloca double, align 8 + %x19 = alloca i64, align 8 + %b20 = alloca i64*, align 8 + %to22 = alloca i64*, align 8 + %i23 = alloca i64, align 8 %d2 = alloca double, align 8 - %expr36 = alloca double, align 8 - %blockret37 = alloca double, align 8 - %x38 = alloca double, align 8 - %b39 = alloca i64*, align 8 - %to41 = alloca i64*, align 8 - %i43 = alloca i64, align 8 + %expr32 = alloca double, align 8 + %x33 = alloca double, align 8 + %b34 = alloca i64*, align 8 + %to36 = alloca i64*, align 8 + %i38 = alloca i64, align 8 store float 0x4028B4BC60000000, float* %f, align 4 %0 = load float, float* %f, align 4 store float %0, float* %expr, align 4 @@ -262,137 +245,117 @@ for.inc: ; preds = %for.body for.exit: ; preds = %for.cond %8 = load i32, i32* %x, align 4 - store i32 %8, i32* %blockret, align 4 - br label %expr_block.exit + store i32 %8, i32* %i, align 4 + %9 = load i32, i32* %i, align 4 + store i32 %9, i32* %expr3, align 4 + store i32* %expr3, i32** %b5, align 8 + %ptrptr7 = bitcast float* %x4 to i32* + store i32* %ptrptr7, i32** %to6, align 8 + store i64 0, i64* %i8, align 8 + br label %for.cond9 -expr_block.exit: ; preds = %for.exit - %9 = load i32, i32* %blockret, align 4 - store i32 %9, i32* %i, align 4 - %10 = load i32, i32* %i, align 4 - store i32 %10, i32* %expr3, align 4 - store i32* %expr3, i32** %b6, align 8 - %ptrptr8 = bitcast float* %x5 to i32* - store i32* %ptrptr8, i32** %to7, align 8 - store i64 0, i64* %i9, align 8 - br label %for.cond10 +for.cond9: ; preds = %for.inc14, %for.exit + %10 = load i64, i64* %i8, align 8 + %lt10 = icmp ult i64 %10, 4 + br i1 %lt10, label %for.body11, label %for.exit16 -for.cond10: ; preds = %for.inc15, %expr_block.exit - %11 = load i64, i64* %i9, align 8 - %lt11 = icmp ult i64 %11, 4 - br i1 %lt11, label %for.body12, label %for.exit17 +for.body11: ; preds = %for.cond9 + %11 = load i32*, i32** %to6, align 8 + %12 = load i64, i64* %i8, align 8 + %ptroffset12 = getelementptr inbounds i32, i32* %11, i64 %12 + %13 = load i32*, i32** %b5, align 8 + %14 = load i64, i64* %i8, align 8 + %ptroffset13 = getelementptr inbounds i32, i32* %13, i64 %14 + %15 = load i32, i32* %ptroffset13, align 4 + store i32 %15, i32* %ptroffset12, align 4 + br label %for.inc14 -for.body12: ; preds = %for.cond10 - %12 = load i32*, i32** %to7, align 8 - %13 = load i64, i64* %i9, align 8 - %ptroffset13 = getelementptr inbounds i32, i32* %12, i64 %13 - %14 = load i32*, i32** %b6, align 8 - %15 = load i64, i64* %i9, align 8 - %ptroffset14 = getelementptr inbounds i32, i32* %14, i64 %15 - %16 = load i32, i32* %ptroffset14, align 4 - store i32 %16, i32* %ptroffset13, align 4 - br label %for.inc15 +for.inc14: ; preds = %for.body11 + %16 = load i64, i64* %i8, align 8 + %add15 = add i64 %16, 4 + store i64 %add15, i64* %i8, align 8 + br label %for.cond9 -for.inc15: ; preds = %for.body12 - %17 = load i64, i64* %i9, align 8 - %add16 = add i64 %17, 4 - store i64 %add16, i64* %i9, align 8 - br label %for.cond10 - -for.exit17: ; preds = %for.cond10 - %18 = load float, float* %x5, align 4 - store float %18, float* %blockret4, align 4 - br label %expr_block.exit18 - -expr_block.exit18: ; preds = %for.exit17 - %19 = load float, float* %blockret4, align 4 - store float %19, float* %f2, align 4 - %20 = load float, float* %f, align 4 - %fpfpext = fpext float %20 to double - %21 = load i32, i32* %i, align 4 - %22 = load float, float* %f2, align 4 - %fpfpext19 = fpext float %22 to double - call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %21, double %fpfpext19) +for.exit16: ; preds = %for.cond9 + %17 = load float, float* %x4, align 4 + store float %17, float* %f2, align 4 + %18 = load float, float* %f, align 4 + %fpfpext = fpext float %18 to double + %19 = load i32, i32* %i, align 4 + %20 = load float, float* %f2, align 4 + %fpfpext17 = fpext float %20 to double + call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i32 0, i32 0), double %fpfpext, i32 %19, double %fpfpext17) store double 1.235300e+268, double* %d, align 8 - %23 = load double, double* %d, align 8 - store double %23, double* %expr20, align 8 - %ptrptr24 = bitcast double* %expr20 to i64* - store i64* %ptrptr24, i64** %b23, align 8 - store i64* %x22, i64** %to25, align 8 - store i64 0, i64* %i26, align 8 - br label %for.cond27 + %21 = load double, double* %d, align 8 + store double %21, double* %expr18, align 8 + %ptrptr21 = bitcast double* %expr18 to i64* + store i64* %ptrptr21, i64** %b20, align 8 + store i64* %x19, i64** %to22, align 8 + store i64 0, i64* %i23, align 8 + br label %for.cond24 -for.cond27: ; preds = %for.inc32, %expr_block.exit18 - %24 = load i64, i64* %i26, align 8 - %lt28 = icmp ult i64 %24, 8 - br i1 %lt28, label %for.body29, label %for.exit34 +for.cond24: ; preds = %for.inc29, %for.exit16 + %22 = load i64, i64* %i23, align 8 + %lt25 = icmp ult i64 %22, 8 + br i1 %lt25, label %for.body26, label %for.exit31 -for.body29: ; preds = %for.cond27 - %25 = load i64*, i64** %to25, align 8 - %26 = load i64, i64* %i26, align 8 - %ptroffset30 = getelementptr inbounds i64, i64* %25, i64 %26 - %27 = load i64*, i64** %b23, align 8 - %28 = load i64, i64* %i26, align 8 - %ptroffset31 = getelementptr inbounds i64, i64* %27, i64 %28 - %29 = load i64, i64* %ptroffset31, align 8 - store i64 %29, i64* %ptroffset30, align 8 - br label %for.inc32 +for.body26: ; preds = %for.cond24 + %23 = load i64*, i64** %to22, align 8 + %24 = load i64, i64* %i23, align 8 + %ptroffset27 = getelementptr inbounds i64, i64* %23, i64 %24 + %25 = load i64*, i64** %b20, align 8 + %26 = load i64, i64* %i23, align 8 + %ptroffset28 = getelementptr inbounds i64, i64* %25, i64 %26 + %27 = load i64, i64* %ptroffset28, align 8 + store i64 %27, i64* %ptroffset27, align 8 + br label %for.inc29 -for.inc32: ; preds = %for.body29 - %30 = load i64, i64* %i26, align 8 - %add33 = add i64 %30, 8 - store i64 %add33, i64* %i26, align 8 - br label %for.cond27 +for.inc29: ; preds = %for.body26 + %28 = load i64, i64* %i23, align 8 + %add30 = add i64 %28, 8 + store i64 %add30, i64* %i23, align 8 + br label %for.cond24 -for.exit34: ; preds = %for.cond27 - %31 = load i64, i64* %x22, align 8 - store i64 %31, i64* %blockret21, align 8 - br label %expr_block.exit35 +for.exit31: ; preds = %for.cond24 + %29 = load i64, i64* %x19, align 8 + store i64 %29, i64* %l, align 8 + %30 = load double, double* %d, align 8 + store double %30, double* %expr32, align 8 + %ptrptr35 = bitcast double* %expr32 to i64* + store i64* %ptrptr35, i64** %b34, align 8 + %ptrptr37 = bitcast double* %x33 to i64* + store i64* %ptrptr37, i64** %to36, align 8 + store i64 0, i64* %i38, align 8 + br label %for.cond39 -expr_block.exit35: ; preds = %for.exit34 - %32 = load i64, i64* %blockret21, align 8 - store i64 %32, i64* %l, align 8 - %33 = load double, double* %d, align 8 - store double %33, double* %expr36, align 8 - %ptrptr40 = bitcast double* %expr36 to i64* - store i64* %ptrptr40, i64** %b39, align 8 - %ptrptr42 = bitcast double* %x38 to i64* - store i64* %ptrptr42, i64** %to41, align 8 - store i64 0, i64* %i43, align 8 - br label %for.cond44 +for.cond39: ; preds = %for.inc44, %for.exit31 + %31 = load i64, i64* %i38, align 8 + %lt40 = icmp ult i64 %31, 8 + br i1 %lt40, label %for.body41, label %for.exit46 -for.cond44: ; preds = %for.inc49, %expr_block.exit35 - %34 = load i64, i64* %i43, align 8 - %lt45 = icmp ult i64 %34, 8 - br i1 %lt45, label %for.body46, label %for.exit51 +for.body41: ; preds = %for.cond39 + %32 = load i64*, i64** %to36, align 8 + %33 = load i64, i64* %i38, align 8 + %ptroffset42 = getelementptr inbounds i64, i64* %32, i64 %33 + %34 = load i64*, i64** %b34, align 8 + %35 = load i64, i64* %i38, align 8 + %ptroffset43 = getelementptr inbounds i64, i64* %34, i64 %35 + %36 = load i64, i64* %ptroffset43, align 8 + store i64 %36, i64* %ptroffset42, align 8 + br label %for.inc44 -for.body46: ; preds = %for.cond44 - %35 = load i64*, i64** %to41, align 8 - %36 = load i64, i64* %i43, align 8 - %ptroffset47 = getelementptr inbounds i64, i64* %35, i64 %36 - %37 = load i64*, i64** %b39, align 8 - %38 = load i64, i64* %i43, align 8 - %ptroffset48 = getelementptr inbounds i64, i64* %37, i64 %38 - %39 = load i64, i64* %ptroffset48, align 8 - store i64 %39, i64* %ptroffset47, align 8 - br label %for.inc49 +for.inc44: ; preds = %for.body41 + %37 = load i64, i64* %i38, align 8 + %add45 = add i64 %37, 8 + store i64 %add45, i64* %i38, align 8 + br label %for.cond39 -for.inc49: ; preds = %for.body46 - %40 = load i64, i64* %i43, align 8 - %add50 = add i64 %40, 8 - store i64 %add50, i64* %i43, align 8 - br label %for.cond44 - -for.exit51: ; preds = %for.cond44 - %41 = load double, double* %x38, align 8 - store double %41, double* %blockret37, align 8 - br label %expr_block.exit52 - -expr_block.exit52: ; preds = %for.exit51 - %42 = load double, double* %blockret37, align 8 - store double %42, double* %d2, align 8 - %43 = load double, double* %d, align 8 - %44 = load i64, i64* %l, align 8 - %45 = load double, double* %d2, align 8 - call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %43, i64 %44, double %45) +for.exit46: ; preds = %for.cond39 + %38 = load double, double* %x33, align 8 + store double %38, double* %d2, align 8 + %39 = load double, double* %d, align 8 + %40 = load i64, i64* %l, align 8 + %41 = load double, double* %d2, align 8 + call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %39, i64 %40, double %41) ret void } \ No newline at end of file diff --git a/test/test_suite/statements/foreach_custom_macro.c3t b/test/test_suite/statements/foreach_custom_macro.c3t index e28d6c0fc..99b3f9eb5 100644 --- a/test/test_suite/statements/foreach_custom_macro.c3t +++ b/test/test_suite/statements/foreach_custom_macro.c3t @@ -45,11 +45,10 @@ entry: %f = alloca i32, align 4 %.iterator = alloca %FooIterator, align 8 %f1 = alloca %Foo*, align 8 - %blockret = alloca %FooIterator, align 8 %literal = alloca %FooIterator, align 8 %it = alloca %FooIterator*, align 8 %value = alloca i32*, align 8 - %blockret2 = alloca i8, align 1 + %blockret = alloca i8, align 1 %0 = bitcast [3 x i32]* %i to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false) %1 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0 @@ -64,68 +63,62 @@ entry: %6 = getelementptr inbounds %FooIterator, %FooIterator* %literal, i32 0, i32 1 %7 = load %Foo*, %Foo** %f1, align 8 store %Foo* %7, %Foo** %6, align 8 - %8 = bitcast %FooIterator* %blockret to i8* + %8 = bitcast %FooIterator* %.iterator to i8* %9 = bitcast %FooIterator* %literal to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %8, i8* align 8 %9, i32 16, i1 false) - br label %expr_block.exit - -expr_block.exit: ; preds = %entry - %10 = bitcast %FooIterator* %.iterator to i8* - %11 = bitcast %FooIterator* %blockret to i8* - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %10, i8* align 8 %11, i32 16, i1 false) br label %for.cond -for.cond: ; preds = %expr_block.exit +for.cond: ; preds = %entry store %FooIterator* %.iterator, %FooIterator** %it, align 8 store i32* %f, i32** %value, align 8 - %12 = load %FooIterator*, %FooIterator** %it, align 8 - %13 = getelementptr inbounds %FooIterator, %FooIterator* %12, i32 0, i32 0 - %14 = load i64, i64* %13, align 8 - %15 = load %FooIterator*, %FooIterator** %it, align 8 - %16 = getelementptr inbounds %FooIterator, %FooIterator* %15, i32 0, i32 1 - %17 = load %Foo*, %Foo** %16, align 8 - %18 = getelementptr inbounds %Foo, %Foo* %17, i32 0, i32 0 - %19 = getelementptr inbounds %"int[]", %"int[]"* %18, i32 0, i32 1 - %20 = load i64, i64* %19, align 8 - %eq = icmp eq i64 %14, %20 + %10 = load %FooIterator*, %FooIterator** %it, align 8 + %11 = getelementptr inbounds %FooIterator, %FooIterator* %10, i32 0, i32 0 + %12 = load i64, i64* %11, align 8 + %13 = load %FooIterator*, %FooIterator** %it, align 8 + %14 = getelementptr inbounds %FooIterator, %FooIterator* %13, i32 0, i32 1 + %15 = load %Foo*, %Foo** %14, align 8 + %16 = getelementptr inbounds %Foo, %Foo* %15, i32 0, i32 0 + %17 = getelementptr inbounds %"int[]", %"int[]"* %16, i32 0, i32 1 + %18 = load i64, i64* %17, align 8 + %eq = icmp eq i64 %12, %18 br i1 %eq, label %if.then, label %if.exit if.then: ; preds = %for.cond - store i8 0, i8* %blockret2, align 1 - br label %expr_block.exit3 + store i8 0, i8* %blockret, align 1 + br label %expr_block.exit if.exit: ; preds = %for.cond - %21 = load i32*, i32** %value, align 8 - %22 = load %FooIterator*, %FooIterator** %it, align 8 - %23 = getelementptr inbounds %FooIterator, %FooIterator* %22, i32 0, i32 1 - %24 = load %Foo*, %Foo** %23, align 8 - %25 = getelementptr inbounds %Foo, %Foo* %24, i32 0, i32 0 - %26 = getelementptr inbounds %"int[]", %"int[]"* %25, i32 0, i32 0 - %27 = load i32*, i32** %26, align 8 - %28 = load %FooIterator*, %FooIterator** %it, align 8 - %29 = getelementptr inbounds %FooIterator, %FooIterator* %28, i32 0, i32 0 - %30 = load i64, i64* %29, align 8 - %add = add i64 %30, 1 - store i64 %add, i64* %29, align 8 - %ptroffset = getelementptr inbounds i32, i32* %27, i64 %30 - %31 = load i32, i32* %ptroffset, align 4 - store i32 %31, i32* %21, align 8 - store i8 1, i8* %blockret2, align 1 - br label %expr_block.exit3 + %19 = load i32*, i32** %value, align 8 + %20 = load %FooIterator*, %FooIterator** %it, align 8 + %21 = getelementptr inbounds %FooIterator, %FooIterator* %20, i32 0, i32 1 + %22 = load %Foo*, %Foo** %21, align 8 + %23 = getelementptr inbounds %Foo, %Foo* %22, i32 0, i32 0 + %24 = getelementptr inbounds %"int[]", %"int[]"* %23, i32 0, i32 0 + %25 = load i32*, i32** %24, align 8 + %26 = load %FooIterator*, %FooIterator** %it, align 8 + %27 = getelementptr inbounds %FooIterator, %FooIterator* %26, i32 0, i32 0 + %28 = load i64, i64* %27, align 8 + %add = add i64 %28, 1 + store i64 %add, i64* %27, align 8 + %ptroffset = getelementptr inbounds i32, i32* %25, i64 %28 + %29 = load i32, i32* %ptroffset, align 4 + store i32 %29, i32* %19, align 8 + store i8 1, i8* %blockret, align 1 + br label %expr_block.exit -expr_block.exit3: ; preds = %if.exit, %if.then - %32 = load i8, i8* %blockret2, align 1 - %33 = trunc i8 %32 to i1 - br i1 %33, label %for.body, label %for.exit +expr_block.exit: ; preds = %if.exit, %if.then + %30 = load i8, i8* %blockret, align 1 + %31 = trunc i8 %30 to i1 + br i1 %31, label %for.body, label %for.exit -for.body: ; preds = %expr_block.exit3 - %34 = load i32, i32* %f, align 4 - %35 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %34) +for.body: ; preds = %expr_block.exit + %32 = load i32, i32* %f, align 4 + %33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %32) br label %while.begin while.begin: ; preds = %for.body br label %for.exit -for.exit: ; preds = %while.begin, %expr_block.exit3 +for.exit: ; preds = %while.begin, %expr_block.exit ret void } \ No newline at end of file