mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-23 06:45:19 +00:00
Merge pull request #1632 from gitlost/const_in_if_#1592
Fix issue #1592 "LLVM code gen error when using a constant in an if"
This commit is contained in:
@@ -3028,7 +3028,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
||||
lbBlock *done = lb_create_block(p, "if.done"); // NOTE(bill): Append later
|
||||
lbBlock *else_ = lb_create_block(p, "if.else");
|
||||
|
||||
lbValue cond = lb_build_cond(p, te->cond, then, else_);
|
||||
lb_build_cond(p, te->cond, then, else_);
|
||||
lb_start_block(p, then);
|
||||
|
||||
Type *type = default_type(type_of_expr(expr));
|
||||
@@ -4646,7 +4646,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
lbBlock *done = lb_create_block(p, "if.done"); // NOTE(bill): Append later
|
||||
lbBlock *else_ = lb_create_block(p, "if.else");
|
||||
|
||||
lbValue cond = lb_build_cond(p, te->cond, then, else_);
|
||||
lb_build_cond(p, te->cond, then, else_);
|
||||
lb_start_block(p, then);
|
||||
|
||||
Type *ptr_type = alloc_type_pointer(default_type(type_of_expr(expr)));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1652,13 +1652,16 @@ void lb_build_if_stmt(lbProcedure *p, Ast *node) {
|
||||
}
|
||||
|
||||
lbValue cond = lb_build_cond(p, is->cond, then, else_);
|
||||
// Note `cond.value` only set for non-and/or conditions and const negs so that the `LLVMIsConstant()`
|
||||
// and `LLVMConstIntGetZExtValue()` calls below will be valid and `LLVMInstructionEraseFromParent()`
|
||||
// will target the correct (& only) branch statement
|
||||
|
||||
if (is->label != nullptr) {
|
||||
lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr);
|
||||
tl->is_block = true;
|
||||
}
|
||||
|
||||
if (LLVMIsConstant(cond.value)) {
|
||||
if (cond.value && LLVMIsConstant(cond.value)) {
|
||||
// NOTE(bill): Do a compile time short circuit for when the condition is constantly known.
|
||||
// This done manually rather than relying on the SSA passes because sometimes the SSA passes
|
||||
// miss some even if they are constantly known, especially with few optimization passes.
|
||||
|
||||
Reference in New Issue
Block a user