From 83bd7c73c4bae18ef3fed24f72885d969dfd3757 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 8 Sep 2021 11:49:07 +0100 Subject: [PATCH] Fix #1120 code generation --- src/llvm_backend_expr.cpp | 57 +++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 7ac1b3d36..8e632d5bc 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -51,14 +51,61 @@ lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast incoming_blocks[done->preds.count] = p->curr_block->block; lb_emit_jump(p, done); - lb_start_block(p, done); + lb_start_block(p, done); + + LLVMTypeRef dst_type = lb_type(m, type); + LLVMValueRef phi = nullptr; + + GB_ASSERT(incoming_values.count == incoming_blocks.count); + GB_ASSERT(incoming_values.count > 0); + LLVMTypeRef phi_type = nullptr; + for_array(i, incoming_values) { + LLVMValueRef incoming_value = incoming_values[i]; + if (!LLVMIsConstant(incoming_value)) { + phi_type = LLVMTypeOf(incoming_value); + break; + } + } + + if (phi_type == nullptr) { + phi = LLVMBuildPhi(p->builder, dst_type, ""); + LLVMAddIncoming(phi, incoming_values.data, incoming_blocks.data, cast(unsigned)incoming_values.count); + goto phi_end; + } + + for_array(i, incoming_values) { + LLVMValueRef incoming_value = incoming_values[i]; + LLVMTypeRef incoming_type = LLVMTypeOf(incoming_value); + + if (phi_type != incoming_type) { + GB_ASSERT_MSG(LLVMIsConstant(incoming_value), "%s vs %s", LLVMPrintTypeToString(phi_type), LLVMPrintTypeToString(incoming_type)); + bool ok = !!LLVMConstIntGetZExtValue(incoming_value); + incoming_values[i] = LLVMConstInt(phi_type, ok, false); + } + + } + + phi = LLVMBuildPhi(p->builder, phi_type, ""); + LLVMAddIncoming(phi, incoming_values.data, incoming_blocks.data, cast(unsigned)incoming_values.count); + + LLVMTypeRef i1 = LLVMInt1TypeInContext(m->ctx); + if ((phi_type == i1) ^ (dst_type == i1)) { + if (phi_type == i1) { + phi = LLVMBuildZExt(p->builder, phi, dst_type, ""); + } else { + phi = LLVMBuildTruncOrBitCast(p->builder, phi, dst_type, ""); + } + } else if (lb_sizeof(phi_type) < lb_sizeof(dst_type)) { + phi = LLVMBuildZExt(p->builder, phi, dst_type, ""); + } else { + phi = LLVMBuildTruncOrBitCast(p->builder, phi, dst_type, ""); + } + +phi_end:; lbValue res = {}; res.type = type; - res.value = LLVMBuildPhi(p->builder, lb_type(m, type), ""); - GB_ASSERT(incoming_values.count == incoming_blocks.count); - LLVMAddIncoming(res.value, incoming_values.data, incoming_blocks.data, cast(unsigned)incoming_values.count); - + res.value = phi; return res; }