diff --git a/src/all_types.hpp b/src/all_types.hpp index d40df52df..8628bf007 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1510,6 +1510,7 @@ struct CodeGen { size_t version_patch; bool verbose; bool verbose_link; + bool verbose_ir; ErrColor err_color; ImportTableEntry *root_import; ImportTableEntry *bootstrap_import; diff --git a/src/codegen.cpp b/src/codegen.cpp index 3860dab0b..2d7b5bb1d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1343,10 +1343,28 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m return result; case DivKindTrunc: { - LLVMValueRef floored = gen_floor(g, result, type_entry); - LLVMValueRef ceiled = gen_ceil(g, result, type_entry); + LLVMBasicBlockRef ltz_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncLTZero"); + LLVMBasicBlockRef gez_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncGEZero"); + LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd"); LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, ""); - return LLVMBuildSelect(g->builder, ltz, ceiled, floored, ""); + LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block); + + LLVMPositionBuilderAtEnd(g->builder, ltz_block); + LLVMValueRef ceiled = gen_ceil(g, result, type_entry); + LLVMBasicBlockRef ceiled_end_block = LLVMGetInsertBlock(g->builder); + LLVMBuildBr(g->builder, end_block); + + LLVMPositionBuilderAtEnd(g->builder, gez_block); + LLVMValueRef floored = gen_floor(g, result, type_entry); + LLVMBasicBlockRef floored_end_block = LLVMGetInsertBlock(g->builder); + LLVMBuildBr(g->builder, end_block); + + LLVMPositionBuilderAtEnd(g->builder, end_block); + LLVMValueRef phi = LLVMBuildPhi(g->builder, type_entry->type_ref, ""); + LLVMValueRef incoming_values[] = { ceiled, floored }; + LLVMBasicBlockRef incoming_blocks[] = { ceiled_end_block, floored_end_block }; + LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2); + return phi; } case DivKindFloor: return gen_floor(g, result, type_entry); @@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) { } static void do_code_gen(CodeGen *g) { - if (g->verbose) { + if (g->verbose || g->verbose_ir) { fprintf(stderr, "\nCode Generation:\n"); fprintf(stderr, "------------------\n"); } @@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) { ZigLLVMDIBuilderFinalize(g->dbuilder); - if (g->verbose) { + if (g->verbose || g->verbose_ir) { LLVMDumpModule(g->module); } diff --git a/src/main.cpp b/src/main.cpp index ca5e99ed3..0c74b5bbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,6 +48,7 @@ static int usage(const char *arg0) { " --target-os [name] specify target operating system\n" " --verbose turn on compiler debug output\n" " --verbose-link turn on compiler debug output for linking only\n" + " --verbose-ir turn on compiler debug output for IR only\n" " --zig-std-dir [path] directory where zig standard library resides\n" " -dirafter [dir] same as -isystem but do it last\n" " -isystem [dir] add additional search path for other .h files\n" @@ -186,6 +187,7 @@ int main(int argc, char **argv) { const char *out_name = nullptr; bool verbose = false; bool verbose_link = false; + bool verbose_ir = false; ErrColor color = ErrColorAuto; const char *libc_lib_dir = nullptr; const char *libc_static_lib_dir = nullptr; @@ -352,6 +354,8 @@ int main(int argc, char **argv) { verbose = true; } else if (strcmp(arg, "--verbose-link") == 0) { verbose_link = true; + } else if (strcmp(arg, "--verbose-ir") == 0) { + verbose_ir = true; } else if (strcmp(arg, "-mwindows") == 0) { mwindows = true; } else if (strcmp(arg, "-mconsole") == 0) { @@ -630,6 +634,7 @@ int main(int argc, char **argv) { codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); codegen_set_verbose(g, verbose); g->verbose_link = verbose_link; + g->verbose_ir = verbose_ir; codegen_set_errmsg_color(g, color); for (size_t i = 0; i < lib_dirs.length; i += 1) {