authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-30 16:59:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-30 16:59:31-04:00
logba3d21ca67af0ce47841bc2d0258903ccaf89a75
tree36947cb623508014b1215ee2f986580c8f575732
parent588d2862d90b65b7227975ecd3c8dfdaabbdefc6

better divTrunc codegen

branch and phi instead of select instruction fixes division test for windows. See #302

3 files changed, 29 insertions(+), 5 deletions(-)

src/all_types.hpp+1
......@@ -1510,6 +1510,7 @@ struct CodeGen {
15101510 size_t version_patch;
15111511 bool verbose;
15121512 bool verbose_link;
1513 bool verbose_ir;
15131514 ErrColor err_color;
15141515 ImportTableEntry *root_import;
15151516 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
13431343 return result;
13441344 case DivKindTrunc:
13451345 {
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");
13481349 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;
13501368 }
13511369 case DivKindFloor:
13521370 return gen_floor(g, result, type_entry);
......@@ -4080,7 +4098,7 @@ static void validate_inline_fns(CodeGen *g) {
40804098}
40814099
40824100static void do_code_gen(CodeGen *g) {
4083 if (g->verbose) {
4101 if (g->verbose || g->verbose_ir) {
40844102 fprintf(stderr, "\nCode Generation:\n");
40854103 fprintf(stderr, "------------------\n");
40864104 }
......@@ -4358,7 +4376,7 @@ static void do_code_gen(CodeGen *g) {
43584376
43594377 ZigLLVMDIBuilderFinalize(g->dbuilder);
43604378
4361 if (g->verbose) {
4379 if (g->verbose || g->verbose_ir) {
43624380 LLVMDumpModule(g->module);
43634381 }
43644382
src/main.cpp+5
......@@ -48,6 +48,7 @@ static int usage(const char *arg0) {
4848 " --target-os [name] specify target operating system\n"
4949 " --verbose turn on compiler debug output\n"
5050 " --verbose-link turn on compiler debug output for linking only\n"
51 " --verbose-ir turn on compiler debug output for IR only\n"
5152 " --zig-std-dir [path] directory where zig standard library resides\n"
5253 " -dirafter [dir] same as -isystem but do it last\n"
5354 " -isystem [dir] add additional search path for other .h files\n"
......@@ -186,6 +187,7 @@ int main(int argc, char **argv) {
186187 const char *out_name = nullptr;
187188 bool verbose = false;
188189 bool verbose_link = false;
190 bool verbose_ir = false;
189191 ErrColor color = ErrColorAuto;
190192 const char *libc_lib_dir = nullptr;
191193 const char *libc_static_lib_dir = nullptr;
......@@ -352,6 +354,8 @@ int main(int argc, char **argv) {
352354 verbose = true;
353355 } else if (strcmp(arg, "--verbose-link") == 0) {
354356 verbose_link = true;
357 } else if (strcmp(arg, "--verbose-ir") == 0) {
358 verbose_ir = true;
355359 } else if (strcmp(arg, "-mwindows") == 0) {
356360 mwindows = true;
357361 } else if (strcmp(arg, "-mconsole") == 0) {
......@@ -630,6 +634,7 @@ int main(int argc, char **argv) {
630634 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
631635 codegen_set_verbose(g, verbose);
632636 g->verbose_link = verbose_link;
637 g->verbose_ir = verbose_ir;
633638 codegen_set_errmsg_color(g, color);
634639
635640 for (size_t i = 0; i < lib_dirs.length; i += 1) {