| author | |
| committer | |
| log | ba3d21ca67af0ce47841bc2d0258903ccaf89a75 |
| tree | 36947cb623508014b1215ee2f986580c8f575732 |
| parent | 588d2862d90b65b7227975ecd3c8dfdaabbdefc6 |
branch and phi instead of select instruction
fixes division test for windows. See #3023 files changed, 29 insertions(+), 5 deletions(-)
src/all_types.hpp+1| ... | @@ -1510,6 +1510,7 @@ struct CodeGen { | ... | @@ -1510,6 +1510,7 @@ struct CodeGen { |
| 1510 | size_t version_patch; | 1510 | size_t version_patch; |
| 1511 | bool verbose; | 1511 | bool verbose; |
| 1512 | bool verbose_link; | 1512 | bool verbose_link; |
| 1513 | bool verbose_ir; | ||
| 1513 | ErrColor err_color; | 1514 | ErrColor err_color; |
| 1514 | ImportTableEntry *root_import; | 1515 | ImportTableEntry *root_import; |
| 1515 | ImportTableEntry *bootstrap_import; | 1516 | ImportTableEntry *bootstrap_import; |
src/codegen.cpp+23-5| ... | @@ -1343,10 +1343,28 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m | ... | @@ -1343,10 +1343,28 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m |
| 1343 | return result; | 1343 | return result; |
| 1344 | case DivKindTrunc: | 1344 | case DivKindTrunc: |
| 1345 | { | 1345 | { |
| 1346 | LLVMValueRef floored = gen_floor(g, result, type_entry); | 1346 | LLVMBasicBlockRef ltz_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncLTZero"); |
| 1347 | LLVMValueRef ceiled = gen_ceil(g, result, type_entry); | 1347 | LLVMBasicBlockRef gez_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncGEZero"); |
| 1348 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd"); | ||
| 1348 | LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, ""); | 1349 | LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, ""); |
| 1349 | return LLVMBuildSelect(g->builder, ltz, ceiled, floored, ""); | 1350 | LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block); |
| 1351 | |||
| 1352 | LLVMPositionBuilderAtEnd(g->builder, ltz_block); | ||
| 1353 | LLVMValueRef ceiled = gen_ceil(g, result, type_entry); | ||
| 1354 | LLVMBasicBlockRef ceiled_end_block = LLVMGetInsertBlock(g->builder); | ||
| 1355 | LLVMBuildBr(g->builder, end_block); | ||
| 1356 | |||
| 1357 | LLVMPositionBuilderAtEnd(g->builder, gez_block); | ||
| 1358 | LLVMValueRef floored = gen_floor(g, result, type_entry); | ||
| 1359 | LLVMBasicBlockRef floored_end_block = LLVMGetInsertBlock(g->builder); | ||
| 1360 | LLVMBuildBr(g->builder, end_block); | ||
| 1361 | |||
| 1362 | LLVMPositionBuilderAtEnd(g->builder, end_block); | ||
| 1363 | LLVMValueRef phi = LLVMBuildPhi(g->builder, type_entry->type_ref, ""); | ||
| 1364 | LLVMValueRef incoming_values[] = { ceiled, floored }; | ||
| 1365 | LLVMBasicBlockRef incoming_blocks[] = { ceiled_end_block, floored_end_block }; | ||
| 1366 | LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2); | ||
| 1367 | return phi; | ||
| 1350 | } | 1368 | } |
| 1351 | case DivKindFloor: | 1369 | case DivKindFloor: |
| 1352 | return gen_floor(g, result, type_entry); | 1370 | return gen_floor(g, result, type_entry); |
| ... | @@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) { | ... | @@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) { |
| 4080 | } | 4098 | } |
| 4081 | 4099 | ||
| 4082 | static void do_code_gen(CodeGen *g) { | 4100 | static void do_code_gen(CodeGen *g) { |
| 4083 | if (g->verbose) { | 4101 | if (g->verbose || g->verbose_ir) { |
| 4084 | fprintf(stderr, "\nCode Generation:\n"); | 4102 | fprintf(stderr, "\nCode Generation:\n"); |
| 4085 | fprintf(stderr, "------------------\n"); | 4103 | fprintf(stderr, "------------------\n"); |
| 4086 | } | 4104 | } |
| ... | @@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) { |
| 4358 | 4376 | ||
| 4359 | ZigLLVMDIBuilderFinalize(g->dbuilder); | 4377 | ZigLLVMDIBuilderFinalize(g->dbuilder); |
| 4360 | 4378 | ||
| 4361 | if (g->verbose) { | 4379 | if (g->verbose || g->verbose_ir) { |
| 4362 | LLVMDumpModule(g->module); | 4380 | LLVMDumpModule(g->module); |
| 4363 | } | 4381 | } |
| 4364 | 4382 |
src/main.cpp+5| ... | @@ -48,6 +48,7 @@ static int usage(const char *arg0) { | ... | @@ -48,6 +48,7 @@ static int usage(const char *arg0) { |
| 48 | " --target-os [name] specify target operating system\n" | 48 | " --target-os [name] specify target operating system\n" |
| 49 | " --verbose turn on compiler debug output\n" | 49 | " --verbose turn on compiler debug output\n" |
| 50 | " --verbose-link turn on compiler debug output for linking only\n" | 50 | " --verbose-link turn on compiler debug output for linking only\n" |
| 51 | " --verbose-ir turn on compiler debug output for IR only\n" | ||
| 51 | " --zig-std-dir [path] directory where zig standard library resides\n" | 52 | " --zig-std-dir [path] directory where zig standard library resides\n" |
| 52 | " -dirafter [dir] same as -isystem but do it last\n" | 53 | " -dirafter [dir] same as -isystem but do it last\n" |
| 53 | " -isystem [dir] add additional search path for other .h files\n" | 54 | " -isystem [dir] add additional search path for other .h files\n" |
| ... | @@ -186,6 +187,7 @@ int main(int argc, char **argv) { | ... | @@ -186,6 +187,7 @@ int main(int argc, char **argv) { |
| 186 | const char *out_name = nullptr; | 187 | const char *out_name = nullptr; |
| 187 | bool verbose = false; | 188 | bool verbose = false; |
| 188 | bool verbose_link = false; | 189 | bool verbose_link = false; |
| 190 | bool verbose_ir = false; | ||
| 189 | ErrColor color = ErrColorAuto; | 191 | ErrColor color = ErrColorAuto; |
| 190 | const char *libc_lib_dir = nullptr; | 192 | const char *libc_lib_dir = nullptr; |
| 191 | const char *libc_static_lib_dir = nullptr; | 193 | const char *libc_static_lib_dir = nullptr; |
| ... | @@ -352,6 +354,8 @@ int main(int argc, char **argv) { | ... | @@ -352,6 +354,8 @@ int main(int argc, char **argv) { |
| 352 | verbose = true; | 354 | verbose = true; |
| 353 | } else if (strcmp(arg, "--verbose-link") == 0) { | 355 | } else if (strcmp(arg, "--verbose-link") == 0) { |
| 354 | verbose_link = true; | 356 | verbose_link = true; |
| 357 | } else if (strcmp(arg, "--verbose-ir") == 0) { | ||
| 358 | verbose_ir = true; | ||
| 355 | } else if (strcmp(arg, "-mwindows") == 0) { | 359 | } else if (strcmp(arg, "-mwindows") == 0) { |
| 356 | mwindows = true; | 360 | mwindows = true; |
| 357 | } else if (strcmp(arg, "-mconsole") == 0) { | 361 | } else if (strcmp(arg, "-mconsole") == 0) { |
| ... | @@ -630,6 +634,7 @@ int main(int argc, char **argv) { | ... | @@ -630,6 +634,7 @@ int main(int argc, char **argv) { |
| 630 | codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); | 634 | codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); |
| 631 | codegen_set_verbose(g, verbose); | 635 | codegen_set_verbose(g, verbose); |
| 632 | g->verbose_link = verbose_link; | 636 | g->verbose_link = verbose_link; |
| 637 | g->verbose_ir = verbose_ir; | ||
| 633 | codegen_set_errmsg_color(g, color); | 638 | codegen_set_errmsg_color(g, color); |
| 634 | 639 | ||
| 635 | for (size_t i = 0; i < lib_dirs.length; i += 1) { | 640 | for (size_t i = 0; i < lib_dirs.length; i += 1) { |