From 6dba1f1c8eee5e2f037c7ef216bc64423aef8e00 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 12 Feb 2017 17:22:35 -0500 Subject: slice and array re-work plus some misc. changes * `@truncate` builtin allows casting to the same size integer. It also performs two's complement casting between signed and unsigned integers. * The idiomatic way to convert between bytes and numbers is now `mem.readInt` and `mem.writeInt` instead of an unsafe cast. It works at compile time, is safer, and looks cleaner. * Implicitly casting an array to a slice is allowed only if the slice is const. * Constant pointer values know if their memory is from a compile- time constant value or a compile-time variable. * Cast from [N]u8 to []T no longer allowed, but [N]u8 to []const T still allowed. * Fix inability to pass a mutable pointer to comptime variable at compile-time to a function and have the function modify the memory pointed to by the pointer. * Add the `comptime T: type` parameter back to mem.eql. Prevents accidentally creating instantiations for arrays. --- src/codegen.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index e56c3b7de2..b98d549e84 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1859,9 +1859,18 @@ static LLVMValueRef ir_render_div_exact(CodeGen *g, IrExecutable *executable, Ir } static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) { - TypeTableEntry *dest_type = get_underlying_type(instruction->base.value.type); LLVMValueRef target_val = ir_llvm_value(g, instruction->target); - return LLVMBuildTrunc(g->builder, target_val, dest_type->type_ref, ""); + TypeTableEntry *dest_type = get_underlying_type(instruction->base.value.type); + TypeTableEntry *src_type = get_underlying_type(instruction->target->value.type); + if (dest_type == src_type) { + // no-op + return target_val; + } if (src_type->data.integral.bit_count == dest_type->data.integral.bit_count) { + return LLVMBuildBitCast(g->builder, target_val, dest_type->type_ref, ""); + } else { + LLVMValueRef target_val = ir_llvm_value(g, instruction->target); + return LLVMBuildTrunc(g->builder, target_val, dest_type->type_ref, ""); + } } static LLVMValueRef ir_render_alloca(CodeGen *g, IrExecutable *executable, IrInstructionAlloca *instruction) { @@ -1945,10 +1954,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) { assert(instruction->tmp_ptr); - TypeTableEntry *array_type = get_underlying_type(instruction->ptr->value.type); + LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr); + TypeTableEntry *array_ptr_type = instruction->ptr->value.type; + assert(array_ptr_type->id == TypeTableEntryIdPointer); + bool is_volatile = array_ptr_type->data.pointer.is_volatile; + TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type; + LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, is_volatile); LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr; - LLVMValueRef array_ptr = ir_llvm_value(g, instruction->ptr); bool want_debug_safety = instruction->safety_check_on && ir_want_debug_safety(g, &instruction->base); @@ -2582,7 +2595,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { return LLVMGetUndef(canon_type->type_ref); case ConstValSpecialStatic: break; - } switch (canon_type->id) { -- cgit v1.2.3