diff options
| author | gitlost <burmartke@gmail.com> | 2022-03-18 13:57:22 +0000 |
|---|---|---|
| committer | gitlost <burmartke@gmail.com> | 2022-03-18 13:57:22 +0000 |
| commit | fdbbf242718746ad71cb410162c6d0b8c68c5af0 (patch) | |
| tree | e59916b9492dfd5e178997ce365e4e6af97534d3 /src/llvm_backend_general.cpp | |
| parent | df233f72a9d1bddb801bdaf150537477d4c23962 (diff) | |
Fix issue #1592 "LLVM code gen error when using a constant in an if"
Changes lb_build_if_stmt() to return null lbValue if condition is
cmpAnd, cmpOr or non-const neg and check in lb_build_if_stmt()
to avoid short circuiting if that's the case
Adds test to "tests/issues" and adds step in CI to check this dir
Diffstat (limited to 'src/llvm_backend_general.cpp')
| -rw-r--r-- | src/llvm_backend_general.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 1c98aa77f..dd1555193 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2602,6 +2602,9 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f GB_ASSERT(true_block != nullptr); GB_ASSERT(false_block != nullptr); + // Use to signal not to do compile time short circuit for consts + lbValue no_comptime_short_circuit = {}; + switch (cond->kind) { case_ast_node(pe, ParenExpr, cond); return lb_build_cond(p, pe->expr, true_block, false_block); @@ -2609,7 +2612,11 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f case_ast_node(ue, UnaryExpr, cond); if (ue->op.kind == Token_Not) { - return lb_build_cond(p, ue->expr, false_block, true_block); + lbValue cond_val = lb_build_cond(p, ue->expr, false_block, true_block); + if (cond_val.value && LLVMIsConstant(cond_val.value)) { + return lb_const_bool(p->module, cond_val.type, LLVMConstIntGetZExtValue(cond_val.value) == 0); + } + return no_comptime_short_circuit; } case_end; @@ -2618,12 +2625,14 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f lbBlock *block = lb_create_block(p, "cmp.and"); lb_build_cond(p, be->left, block, false_block); lb_start_block(p, block); - return lb_build_cond(p, be->right, true_block, false_block); + lb_build_cond(p, be->right, true_block, false_block); + return no_comptime_short_circuit; } else if (be->op.kind == Token_CmpOr) { lbBlock *block = lb_create_block(p, "cmp.or"); lb_build_cond(p, be->left, true_block, block); lb_start_block(p, block); - return lb_build_cond(p, be->right, true_block, false_block); + lb_build_cond(p, be->right, true_block, false_block); + return no_comptime_short_circuit; } case_end; } |