| 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 | 1510 | size_t version_patch; |
| 1511 | 1511 | bool verbose; |
| 1512 | 1512 | bool verbose_link; |
| 1513 | bool verbose_ir; | |
| 1513 | 1514 | ErrColor err_color; |
| 1514 | 1515 | ImportTableEntry *root_import; |
| 1515 | 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 | 1343 | return result; |
| 1344 | 1344 | case DivKindTrunc: |
| 1345 | 1345 | { |
| 1346 | LLVMValueRef floored = gen_floor(g, result, type_entry); | |
| 1347 | LLVMValueRef ceiled = gen_ceil(g, result, type_entry); | |
| 1346 | LLVMBasicBlockRef ltz_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncLTZero"); | |
| 1347 | LLVMBasicBlockRef gez_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncGEZero"); | |
| 1348 | LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd"); | |
| 1348 | 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 | 1369 | case DivKindFloor: |
| 1352 | 1370 | return gen_floor(g, result, type_entry); |
| ... | ... | @@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) { |
| 4080 | 4098 | } |
| 4081 | 4099 | |
| 4082 | 4100 | static void do_code_gen(CodeGen *g) { |
| 4083 | if (g->verbose) { | |
| 4101 | if (g->verbose || g->verbose_ir) { | |
| 4084 | 4102 | fprintf(stderr, "\nCode Generation:\n"); |
| 4085 | 4103 | fprintf(stderr, "------------------\n"); |
| 4086 | 4104 | } |
| ... | ... | @@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) { |
| 4358 | 4376 | |
| 4359 | 4377 | ZigLLVMDIBuilderFinalize(g->dbuilder); |
| 4360 | 4378 | |
| 4361 | if (g->verbose) { | |
| 4379 | if (g->verbose || g->verbose_ir) { | |
| 4362 | 4380 | LLVMDumpModule(g->module); |
| 4363 | 4381 | } |
| 4364 | 4382 |
src/main.cpp+5| ... | ... | @@ -48,6 +48,7 @@ static int usage(const char *arg0) { |
| 48 | 48 | " --target-os [name] specify target operating system\n" |
| 49 | 49 | " --verbose turn on compiler debug output\n" |
| 50 | 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 | 52 | " --zig-std-dir [path] directory where zig standard library resides\n" |
| 52 | 53 | " -dirafter [dir] same as -isystem but do it last\n" |
| 53 | 54 | " -isystem [dir] add additional search path for other .h files\n" |
| ... | ... | @@ -186,6 +187,7 @@ int main(int argc, char **argv) { |
| 186 | 187 | const char *out_name = nullptr; |
| 187 | 188 | bool verbose = false; |
| 188 | 189 | bool verbose_link = false; |
| 190 | bool verbose_ir = false; | |
| 189 | 191 | ErrColor color = ErrColorAuto; |
| 190 | 192 | const char *libc_lib_dir = nullptr; |
| 191 | 193 | const char *libc_static_lib_dir = nullptr; |
| ... | ... | @@ -352,6 +354,8 @@ int main(int argc, char **argv) { |
| 352 | 354 | verbose = true; |
| 353 | 355 | } else if (strcmp(arg, "--verbose-link") == 0) { |
| 354 | 356 | verbose_link = true; |
| 357 | } else if (strcmp(arg, "--verbose-ir") == 0) { | |
| 358 | verbose_ir = true; | |
| 355 | 359 | } else if (strcmp(arg, "-mwindows") == 0) { |
| 356 | 360 | mwindows = true; |
| 357 | 361 | } else if (strcmp(arg, "-mconsole") == 0) { |
| ... | ... | @@ -630,6 +634,7 @@ int main(int argc, char **argv) { |
| 630 | 634 | codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker)); |
| 631 | 635 | codegen_set_verbose(g, verbose); |
| 632 | 636 | g->verbose_link = verbose_link; |
| 637 | g->verbose_ir = verbose_ir; | |
| 633 | 638 | codegen_set_errmsg_color(g, color); |
| 634 | 639 | |
| 635 | 640 | for (size_t i = 0; i < lib_dirs.length; i += 1) { |