Commit 4582ec518f

Andrew Kelley <andrew@ziglang.org>
2019-06-11 01:49:24
result location semantics for vector to array
```zig export fn entry() void { var x: @Vector(4, i32) = undefined; var y: [4]i32 = x; } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %x = alloca <4 x i32>, align 16 %y = alloca [4 x i32], align 4 %0 = bitcast <4 x i32>* %x to i8*, !dbg !47 call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 -86, i64 16, i1 false), !dbg !47 call void @llvm.dbg.declare(metadata <4 x i32>* %x, metadata !39, metadata !DIExpression()), !dbg !47 %1 = load <4 x i32>, <4 x i32>* %x, align 16, !dbg !48 %2 = bitcast [4 x i32]* %y to <4 x i32>*, !dbg !48 store <4 x i32> %1, <4 x i32>* %2, align 16, !dbg !48 call void @llvm.dbg.declare(metadata [4 x i32]* %y, metadata !45, metadata !DIExpression()), !dbg !49 ret void, !dbg !50 } ```
1 parent 9a324ec
src/all_types.hpp
@@ -3522,7 +3522,7 @@ struct IrInstructionVectorToArray {
     IrInstruction base;
 
     IrInstruction *vector;
-    LLVMValueRef tmp_ptr;
+    IrInstruction *result_loc;
 };
 
 struct IrInstructionAssertZero {
src/codegen.cpp
@@ -5386,12 +5386,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab
     ZigType *array_type = instruction->base.value.type;
     assert(array_type->id == ZigTypeIdArray);
     assert(handle_is_ptr(array_type));
-    assert(instruction->tmp_ptr);
+    LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
     LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
-    LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,
+    LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc,
             LLVMPointerType(get_llvm_type(g, instruction->vector->value.type), 0), "");
     gen_store_untyped(g, vector, casted_ptr, 0, false);
-    return instruction->tmp_ptr;
+    return result_loc;
 }
 
 static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
@@ -6838,10 +6838,6 @@ static void do_code_gen(CodeGen *g) {
                 slot = &ref_instruction->tmp_ptr;
                 assert(instruction->value.type->id == ZigTypeIdPointer);
                 slot_type = instruction->value.type->data.pointer.child_type;
-            } else if (instruction->id == IrInstructionIdVectorToArray) {
-                IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
-                alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
-                slot = &vector_to_array_instruction->tmp_ptr;
             } else {
                 zig_unreachable();
             }
src/ir.cpp
@@ -3131,16 +3131,16 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
 }
 
 static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,
-        IrInstruction *vector, ZigType *result_type)
+        ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc)
 {
     IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb,
         source_instruction->scope, source_instruction->source_node);
     instruction->base.value.type = result_type;
     instruction->vector = vector;
+    instruction->result_loc = result_loc;
 
     ir_ref_instruction(vector, ira->new_irb.current_basic_block);
-
-    ir_add_alloca(ira, &instruction->base, result_type);
+    ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
 
     return &instruction->base;
 }
@@ -11985,7 +11985,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *
 }
 
 static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,
-    IrInstruction *vector, ZigType *array_type)
+    IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc)
 {
     if (instr_is_comptime(vector)) {
         // arrays and vectors have the same ConstExprValue representation
@@ -11994,7 +11994,11 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
         result->value.type = array_type;
         return result;
     }
-    return ir_build_vector_to_array(ira, source_instr, vector, array_type);
+    IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr);
+    if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
+        return result_loc_inst;
+    }
+    return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst);
 }
 
 static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr,
@@ -12453,7 +12457,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
         types_match_const_cast_only(ira, wanted_type->data.array.child_type,
             actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
     {
-        return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type);
+        return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc);
     }
 
     // cast from [N]T to @Vector(N, T)
@@ -24484,6 +24488,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
         case IrInstructionIdPtrOfArrayToSlice:
         case IrInstructionIdSliceGen:
         case IrInstructionIdOptionalWrap:
+        case IrInstructionIdVectorToArray:
             return true;
 
         case IrInstructionIdPhi:
@@ -24578,7 +24583,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
         case IrInstructionIdFromBytes:
         case IrInstructionIdToBytes:
         case IrInstructionIdEnumToInt:
-        case IrInstructionIdVectorToArray:
         case IrInstructionIdArrayToVector:
         case IrInstructionIdHasDecl:
         case IrInstructionIdAllocaSrc:
src/ir_print.cpp
@@ -1102,7 +1102,8 @@ static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *i
 static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
     fprintf(irp->f, "VectorToArray(");
     ir_print_other_instruction(irp, instruction->vector);
-    fprintf(irp->f, ")");
+    fprintf(irp->f, ")result=");
+    ir_print_other_instruction(irp, instruction->result_loc);
 }
 
 static void ir_print_ptr_of_array_to_slice(IrPrint *irp, IrInstructionPtrOfArrayToSlice *instruction) {