better divTrunc codegen
branch and phi instead of select instruction fixes division test for windows. See #302master
parent
588d2862d9
commit
ba3d21ca67
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue