Skip to content

Commit ba3d21c

Browse files
committed
better divTrunc codegen
branch and phi instead of select instruction fixes division test for windows. See #302
1 parent 588d286 commit ba3d21c

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

src/all_types.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

40824100
static 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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

0 commit comments

Comments
 (0)