authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-04 20:30:00-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-04 20:30:00-05:00
log8c6fa982cd0a02775264b616c37da9907cc603bb
treebf8101fa59d6909ea4e3364d0b31e63fbdf3c69e
parent2828a9695f088f5454f445fdd0544d805a33837b
signaturelock-open Commit is signed but in an unrecognized format.

SIMD: array to vector, vector to array, wrapping int add

also vectors and arrays now use the same ConstExprVal representation See #903

8 files changed, 403 insertions(+), 224 deletions(-)

src/all_types.hpp+15-5
......@@ -252,10 +252,6 @@ struct ConstArgTuple {
252252 size_t end_index;
253253};
254254
255struct ConstVector {
256 ConstExprValue *elements;
257};
258
259255enum ConstValSpecial {
260256 ConstValSpecialRuntime,
261257 ConstValSpecialStatic,
......@@ -322,7 +318,6 @@ struct ConstExprValue {
322318 ConstPtrValue x_ptr;
323319 ImportTableEntry *x_import;
324320 ConstArgTuple x_arg_tuple;
325 ConstVector x_vector;
326321
327322 // populated if special == ConstValSpecialRuntime
328323 RuntimeHintErrorUnion rh_error_union;
......@@ -2239,6 +2234,8 @@ enum IrInstructionId {
22392234 IrInstructionIdToBytes,
22402235 IrInstructionIdFromBytes,
22412236 IrInstructionIdCheckRuntimeScope,
2237 IrInstructionIdVectorToArray,
2238 IrInstructionIdArrayToVector,
22422239};
22432240
22442241struct IrInstruction {
......@@ -3368,6 +3365,19 @@ struct IrInstructionBitReverse {
33683365 IrInstruction *op;
33693366};
33703367
3368struct IrInstructionArrayToVector {
3369 IrInstruction base;
3370
3371 IrInstruction *array;
3372};
3373
3374struct IrInstructionVectorToArray {
3375 IrInstruction base;
3376
3377 IrInstruction *vector;
3378 LLVMValueRef tmp_ptr;
3379};
3380
33713381static const size_t slice_ptr_index = 0;
33723382static const size_t slice_len_index = 1;
33733383
src/analyze.cpp+90-88
......@@ -4457,7 +4457,15 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
44574457 return new_entry;
44584458}
44594459
4460bool is_valid_vector_elem_type(ZigType *elem_type) {
4461 return elem_type->id == ZigTypeIdInt ||
4462 elem_type->id == ZigTypeIdFloat ||
4463 get_codegen_ptr_type(elem_type) != nullptr;
4464}
4465
44604466ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
4467 assert(is_valid_vector_elem_type(elem_type));
4468
44614469 TypeId type_id = {};
44624470 type_id.id = ZigTypeIdVector;
44634471 type_id.data.vector.len = len;
......@@ -5749,6 +5757,28 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
57495757 zig_unreachable();
57505758}
57515759
5760static bool const_values_equal_array(CodeGen *g, ConstExprValue *a, ConstExprValue *b, size_t len) {
5761 assert(a->data.x_array.special != ConstArraySpecialUndef);
5762 assert(b->data.x_array.special != ConstArraySpecialUndef);
5763 if (a->data.x_array.special == ConstArraySpecialBuf &&
5764 b->data.x_array.special == ConstArraySpecialBuf)
5765 {
5766 return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
5767 }
5768 expand_undef_array(g, a);
5769 expand_undef_array(g, b);
5770
5771 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
5772 ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
5773
5774 for (size_t i = 0; i < len; i += 1) {
5775 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5776 return false;
5777 }
5778
5779 return true;
5780}
5781
57525782bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
57535783 assert(a->type->id == b->type->id);
57545784 assert(a->special == ConstValSpecialStatic);
......@@ -5803,28 +5833,12 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
58035833 case ZigTypeIdPointer:
58045834 case ZigTypeIdFn:
58055835 return const_values_equal_ptr(a, b);
5836 case ZigTypeIdVector:
5837 assert(a->type->data.vector.len == b->type->data.vector.len);
5838 return const_values_equal_array(g, a, b, a->type->data.vector.len);
58065839 case ZigTypeIdArray: {
58075840 assert(a->type->data.array.len == b->type->data.array.len);
5808 assert(a->data.x_array.special != ConstArraySpecialUndef);
5809 assert(b->data.x_array.special != ConstArraySpecialUndef);
5810 if (a->data.x_array.special == ConstArraySpecialBuf &&
5811 b->data.x_array.special == ConstArraySpecialBuf)
5812 {
5813 return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
5814 }
5815 expand_undef_array(g, a);
5816 expand_undef_array(g, b);
5817
5818 size_t len = a->type->data.array.len;
5819 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
5820 ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
5821
5822 for (size_t i = 0; i < len; i += 1) {
5823 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5824 return false;
5825 }
5826
5827 return true;
5841 return const_values_equal_array(g, a, b, a->type->data.array.len);
58285842 }
58295843 case ZigTypeIdStruct:
58305844 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
......@@ -5853,20 +5867,6 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
58535867 case ZigTypeIdArgTuple:
58545868 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
58555869 a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
5856 case ZigTypeIdVector: {
5857 assert(a->type->data.vector.len == b->type->data.vector.len);
5858
5859 size_t len = a->type->data.vector.len;
5860 ConstExprValue *a_elems = a->data.x_vector.elements;
5861 ConstExprValue *b_elems = b->data.x_vector.elements;
5862
5863 for (size_t i = 0; i < len; i += 1) {
5864 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5865 return false;
5866 }
5867
5868 return true;
5869 }
58705870 case ZigTypeIdBoundFn:
58715871 case ZigTypeIdInvalid:
58725872 case ZigTypeIdUnreachable:
......@@ -5985,6 +5985,40 @@ static void render_const_val_err_set(CodeGen *g, Buf *buf, ConstExprValue *const
59855985 }
59865986}
59875987
5988static void render_const_val_array(CodeGen *g, Buf *buf, ConstExprValue *const_val, size_t len) {
5989 switch (const_val->data.x_array.special) {
5990 case ConstArraySpecialUndef:
5991 buf_append_str(buf, "undefined");
5992 return;
5993 case ConstArraySpecialBuf: {
5994 Buf *array_buf = const_val->data.x_array.data.s_buf;
5995 buf_append_char(buf, '"');
5996 for (size_t i = 0; i < buf_len(array_buf); i += 1) {
5997 uint8_t c = buf_ptr(array_buf)[i];
5998 if (c == '"') {
5999 buf_append_str(buf, "\\\"");
6000 } else {
6001 buf_append_char(buf, c);
6002 }
6003 }
6004 buf_append_char(buf, '"');
6005 return;
6006 }
6007 case ConstArraySpecialNone: {
6008 buf_appendf(buf, "%s{", buf_ptr(&const_val->type->name));
6009 for (uint64_t i = 0; i < len; i += 1) {
6010 if (i != 0)
6011 buf_appendf(buf, ",");
6012 ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
6013 render_const_value(g, buf, child_value);
6014 }
6015 buf_appendf(buf, "}");
6016 return;
6017 }
6018 }
6019 zig_unreachable();
6020}
6021
59886022void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
59896023 switch (const_val->special) {
59906024 case ConstValSpecialRuntime:
......@@ -6065,51 +6099,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
60656099 }
60666100 case ZigTypeIdPointer:
60676101 return render_const_val_ptr(g, buf, const_val, type_entry);
6102 case ZigTypeIdVector:
6103 return render_const_val_array(g, buf, const_val, type_entry->data.vector.len);
60686104 case ZigTypeIdArray:
6069 switch (const_val->data.x_array.special) {
6070 case ConstArraySpecialUndef:
6071 buf_append_str(buf, "undefined");
6072 return;
6073 case ConstArraySpecialBuf: {
6074 Buf *array_buf = const_val->data.x_array.data.s_buf;
6075 buf_append_char(buf, '"');
6076 for (size_t i = 0; i < buf_len(array_buf); i += 1) {
6077 uint8_t c = buf_ptr(array_buf)[i];
6078 if (c == '"') {
6079 buf_append_str(buf, "\\\"");
6080 } else {
6081 buf_append_char(buf, c);
6082 }
6083 }
6084 buf_append_char(buf, '"');
6085 return;
6086 }
6087 case ConstArraySpecialNone: {
6088 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
6089 uint64_t len = type_entry->data.array.len;
6090 for (uint64_t i = 0; i < len; i += 1) {
6091 if (i != 0)
6092 buf_appendf(buf, ",");
6093 ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
6094 render_const_value(g, buf, child_value);
6095 }
6096 buf_appendf(buf, "}");
6097 return;
6098 }
6099 }
6100 zig_unreachable();
6101 case ZigTypeIdVector: {
6102 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
6103 uint64_t len = type_entry->data.vector.len;
6104 for (uint32_t i = 0; i < len; i += 1) {
6105 if (i != 0)
6106 buf_appendf(buf, ",");
6107 ConstExprValue *child_value = &const_val->data.x_vector.elements[i];
6108 render_const_value(g, buf, child_value);
6109 }
6110 buf_appendf(buf, "}");
6111 return;
6112 }
6105 return render_const_val_array(g, buf, const_val, type_entry->data.array.len);
61136106 case ZigTypeIdNull:
61146107 {
61156108 buf_appendf(buf, "null");
......@@ -6379,7 +6372,17 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
63796372
63806373// Canonicalize the array value as ConstArraySpecialNone
63816374void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
6382 assert(const_val->type->id == ZigTypeIdArray);
6375 size_t elem_count;
6376 ZigType *elem_type;
6377 if (const_val->type->id == ZigTypeIdArray) {
6378 elem_count = const_val->type->data.array.len;
6379 elem_type = const_val->type->data.array.child_type;
6380 } else if (const_val->type->id == ZigTypeIdVector) {
6381 elem_count = const_val->type->data.vector.len;
6382 elem_type = const_val->type->data.vector.elem_type;
6383 } else {
6384 zig_unreachable();
6385 }
63836386 if (const_val->special == ConstValSpecialUndef) {
63846387 const_val->special = ConstValSpecialStatic;
63856388 const_val->data.x_array.special = ConstArraySpecialUndef;
......@@ -6389,18 +6392,14 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
63896392 return;
63906393 case ConstArraySpecialUndef: {
63916394 const_val->data.x_array.special = ConstArraySpecialNone;
6392 size_t elem_count = const_val->type->data.array.len;
63936395 const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
63946396 for (size_t i = 0; i < elem_count; i += 1) {
63956397 ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
6396 element_val->type = const_val->type->data.array.child_type;
6398 element_val->type = elem_type;
63976399 init_const_undefined(g, element_val);
6398 ConstParent *parent = get_const_val_parent(g, element_val);
6399 if (parent != nullptr) {
6400 parent->id = ConstParentIdArray;
6401 parent->data.p_array.array_val = const_val;
6402 parent->data.p_array.elem_index = i;
6403 }
6400 element_val->parent.id = ConstParentIdArray;
6401 element_val->parent.data.p_array.array_val = const_val;
6402 element_val->parent.data.p_array.elem_index = i;
64046403 }
64056404 return;
64066405 }
......@@ -6411,7 +6410,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
64116410 g->string_literals_table.maybe_remove(buf);
64126411
64136412 const_val->data.x_array.special = ConstArraySpecialNone;
6414 size_t elem_count = const_val->type->data.array.len;
64156413 assert(elem_count == buf_len(buf));
64166414 const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
64176415 for (size_t i = 0; i < elem_count; i += 1) {
......@@ -6419,6 +6417,9 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
64196417 this_char->special = ConstValSpecialStatic;
64206418 this_char->type = g->builtin_types.entry_u8;
64216419 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
6420 this_char->parent.id = ConstParentIdArray;
6421 this_char->parent.data.p_array.array_val = const_val;
6422 this_char->parent.data.p_array.elem_index = i;
64226423 }
64236424 return;
64246425 }
......@@ -6426,6 +6427,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
64266427 zig_unreachable();
64276428}
64286429
6430// Deprecated. Reference the parent field directly.
64296431ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
64306432 return &value->parent;
64316433}
src/analyze.hpp+1
......@@ -74,6 +74,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag);
7474bool is_ref(ZigType *type_entry);
7575bool is_array_ref(ZigType *type_entry);
7676bool is_container_ref(ZigType *type_entry);
77bool is_valid_vector_elem_type(ZigType *elem_type);
7778void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
7879void scan_import(CodeGen *g, ImportTableEntry *import);
7980void preview_use_decl(CodeGen *g, AstNode *node);
src/codegen.cpp+78-20
......@@ -1921,9 +1921,8 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {
19211921}
19221922
19231923static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment) {
1924 assert(alignment > 0);
19251924 LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name);
1926 LLVMSetAlignment(result, alignment);
1925 LLVMSetAlignment(result, (alignment == 0) ? get_abi_alignment(g, type_entry) : alignment);
19271926 return result;
19281927}
19291928
......@@ -3246,6 +3245,22 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
32463245 return LLVMBuildTrunc(g->builder, shifted_value, child_type->type_ref, "");
32473246}
32483247
3248static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
3249 switch (const_val->data.x_array.special) {
3250 case ConstArraySpecialUndef:
3251 return true;
3252 case ConstArraySpecialBuf:
3253 return false;
3254 case ConstArraySpecialNone:
3255 for (size_t i = 0; i < len; i += 1) {
3256 if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i]))
3257 return false;
3258 }
3259 return true;
3260 }
3261 zig_unreachable();
3262}
3263
32493264static bool value_is_all_undef(ConstExprValue *const_val) {
32503265 switch (const_val->special) {
32513266 case ConstValSpecialRuntime:
......@@ -3260,19 +3275,9 @@ static bool value_is_all_undef(ConstExprValue *const_val) {
32603275 }
32613276 return true;
32623277 } else if (const_val->type->id == ZigTypeIdArray) {
3263 switch (const_val->data.x_array.special) {
3264 case ConstArraySpecialUndef:
3265 return true;
3266 case ConstArraySpecialBuf:
3267 return false;
3268 case ConstArraySpecialNone:
3269 for (size_t i = 0; i < const_val->type->data.array.len; i += 1) {
3270 if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i]))
3271 return false;
3272 }
3273 return true;
3274 }
3275 zig_unreachable();
3278 return value_is_all_undef_array(const_val, const_val->type->data.array.len);
3279 } else if (const_val->type->id == ZigTypeIdVector) {
3280 return value_is_all_undef_array(const_val, const_val->type->data.vector.len);
32763281 } else {
32773282 return false;
32783283 }
......@@ -5194,6 +5199,32 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable,
51945199 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
51955200}
51965201
5202static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executable,
5203 IrInstructionVectorToArray *instruction)
5204{
5205 ZigType *array_type = instruction->base.value.type;
5206 assert(array_type->id == ZigTypeIdArray);
5207 assert(handle_is_ptr(array_type));
5208 assert(instruction->tmp_ptr);
5209 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
5210 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,
5211 LLVMPointerType(instruction->vector->value.type->type_ref, 0), "");
5212 gen_store_untyped(g, vector, casted_ptr, 0, false);
5213 return instruction->tmp_ptr;
5214}
5215
5216static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
5217 IrInstructionArrayToVector *instruction)
5218{
5219 ZigType *vector_type = instruction->base.value.type;
5220 assert(vector_type->id == ZigTypeIdVector);
5221 assert(!handle_is_ptr(vector_type));
5222 LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array);
5223 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr,
5224 LLVMPointerType(vector_type->type_ref, 0), "");
5225 return gen_load_untyped(g, casted_ptr, 0, false, "");
5226}
5227
51975228static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
51985229 AstNode *source_node = instruction->source_node;
51995230 Scope *scope = instruction->scope;
......@@ -5439,6 +5470,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
54395470 return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
54405471 case IrInstructionIdBitReverse:
54415472 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
5473 case IrInstructionIdArrayToVector:
5474 return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
5475 case IrInstructionIdVectorToArray:
5476 return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
54425477 }
54435478 zig_unreachable();
54445479}
......@@ -6016,14 +6051,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
60166051 return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
60176052 }
60186053 }
6054 zig_unreachable();
60196055 }
60206056 case ZigTypeIdVector: {
60216057 uint32_t len = type_entry->data.vector.len;
6022 LLVMValueRef *values = allocate<LLVMValueRef>(len);
6023 for (uint32_t i = 0; i < len; i += 1) {
6024 values[i] = gen_const_val(g, &const_val->data.x_vector.elements[i], "");
6058 switch (const_val->data.x_array.special) {
6059 case ConstArraySpecialUndef:
6060 return LLVMGetUndef(type_entry->type_ref);
6061 case ConstArraySpecialNone: {
6062 LLVMValueRef *values = allocate<LLVMValueRef>(len);
6063 for (uint64_t i = 0; i < len; i += 1) {
6064 ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
6065 values[i] = gen_const_val(g, elem_value, "");
6066 }
6067 return LLVMConstVector(values, len);
6068 }
6069 case ConstArraySpecialBuf: {
6070 Buf *buf = const_val->data.x_array.data.s_buf;
6071 assert(buf_len(buf) == len);
6072 LLVMValueRef *values = allocate<LLVMValueRef>(len);
6073 for (uint64_t i = 0; i < len; i += 1) {
6074 values[i] = LLVMConstInt(g->builtin_types.entry_u8->type_ref, buf_ptr(buf)[i], false);
6075 }
6076 return LLVMConstVector(values, len);
6077 }
60256078 }
6026 return LLVMConstVector(values, len);
6079 zig_unreachable();
60276080 }
60286081 case ZigTypeIdUnion:
60296082 {
......@@ -6467,6 +6520,7 @@ static void do_code_gen(CodeGen *g) {
64676520 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
64686521 LLVMValueRef *slot;
64696522 ZigType *slot_type = instruction->value.type;
6523 uint32_t alignment_bytes = 0;
64706524 if (instruction->id == IrInstructionIdCast) {
64716525 IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;
64726526 slot = &cast_instruction->tmp_ptr;
......@@ -6502,10 +6556,14 @@ static void do_code_gen(CodeGen *g) {
65026556 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
65036557 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
65046558 slot = &cmpxchg_instruction->tmp_ptr;
6559 } else if (instruction->id == IrInstructionIdVectorToArray) {
6560 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
6561 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
6562 slot = &vector_to_array_instruction->tmp_ptr;
65056563 } else {
65066564 zig_unreachable();
65076565 }
6508 *slot = build_alloca(g, slot_type, "", get_abi_alignment(g, slot_type));
6566 *slot = build_alloca(g, slot_type, "", alignment_bytes);
65096567 }
65106568
65116569 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
src/ir.cpp+180-111
......@@ -168,6 +168,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
168168static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
169169static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
170170static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
171static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry);
171172
172173static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
173174 assert(get_src_ptr_type(const_val->type) != nullptr);
......@@ -899,6 +900,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScop
899900 return IrInstructionIdCheckRuntimeScope;
900901}
901902
903static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) {
904 return IrInstructionIdVectorToArray;
905}
906
907static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) {
908 return IrInstructionIdArrayToVector;
909}
910
902911template<typename T>
903912static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
904913 T *special_instruction = allocate<T>(1);
......@@ -2821,6 +2830,34 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
28212830 return &instruction->base;
28222831}
28232832
2833static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,
2834 IrInstruction *vector, ZigType *result_type)
2835{
2836 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb,
2837 source_instruction->scope, source_instruction->source_node);
2838 instruction->base.value.type = result_type;
2839 instruction->vector = vector;
2840
2841 ir_ref_instruction(vector, ira->new_irb.current_basic_block);
2842
2843 ir_add_alloca(ira, &instruction->base, result_type);
2844
2845 return &instruction->base;
2846}
2847
2848static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,
2849 IrInstruction *array, ZigType *result_type)
2850{
2851 IrInstructionArrayToVector *instruction = ir_build_instruction<IrInstructionArrayToVector>(&ira->new_irb,
2852 source_instruction->scope, source_instruction->source_node);
2853 instruction->base.value.type = result_type;
2854 instruction->array = array;
2855
2856 ir_ref_instruction(array, ira->new_irb.current_basic_block);
2857
2858 return &instruction->base;
2859}
2860
28242861static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
28252862 results[ReturnKindUnconditional] = 0;
28262863 results[ReturnKindError] = 0;
......@@ -8270,6 +8307,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
82708307
82718308 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt);
82728309 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat);
8310 assert(const_val_is_int || const_val_is_float);
82738311
82748312 if (other_type->id == ZigTypeIdFloat) {
82758313 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) {
......@@ -10714,6 +10752,32 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1071410752 }
1071510753}
1071610754
10755static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr,
10756 IrInstruction *array, ZigType *vector_type)
10757{
10758 if (instr_is_comptime(array)) {
10759 // arrays and vectors have the same ConstExprValue representation
10760 IrInstruction *result = ir_const(ira, source_instr, vector_type);
10761 copy_const_val(&result->value, &array->value, false);
10762 result->value.type = vector_type;
10763 return result;
10764 }
10765 return ir_build_array_to_vector(ira, source_instr, array, vector_type);
10766}
10767
10768static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,
10769 IrInstruction *vector, ZigType *array_type)
10770{
10771 if (instr_is_comptime(vector)) {
10772 // arrays and vectors have the same ConstExprValue representation
10773 IrInstruction *result = ir_const(ira, source_instr, array_type);
10774 copy_const_val(&result->value, &vector->value, false);
10775 result->value.type = array_type;
10776 return result;
10777 }
10778 return ir_build_vector_to_array(ira, source_instr, vector, array_type);
10779}
10780
1071710781static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
1071810782 ZigType *wanted_type, IrInstruction *value)
1071910783{
......@@ -11102,6 +11166,23 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1110211166 }
1110311167 }
1110411168
11169 // cast from @Vector(N, T) to [N]T
11170 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector &&
11171 wanted_type->data.array.len == actual_type->data.vector.len &&
11172 types_match_const_cast_only(ira, wanted_type->data.array.child_type,
11173 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
11174 {
11175 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type);
11176 }
11177
11178 // cast from [N]T to @Vector(N, T)
11179 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector &&
11180 actual_type->data.array.len == wanted_type->data.vector.len &&
11181 types_match_const_cast_only(ira, actual_type->data.array.child_type,
11182 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
11183 {
11184 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
11185 }
1110511186
1110611187 // cast from undefined to anything
1110711188 if (actual_type->id == ZigTypeIdUndefined) {
......@@ -11780,8 +11861,8 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1178011861 return result;
1178111862}
1178211863
11783static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
11784 IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val)
11864static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry,
11865 ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val)
1178511866{
1178611867 bool is_int;
1178711868 bool is_float;
......@@ -11803,10 +11884,10 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
1180311884 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod ||
1180411885 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ)
1180511886 {
11806 return ErrorDivByZero;
11887 return ir_add_error(ira, source_instr, buf_sprintf("division by zero"));
1180711888 }
1180811889 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) {
11809 return ErrorNegativeDenominator;
11890 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator"));
1181011891 }
1181111892
1181211893 switch (op_id) {
......@@ -11852,7 +11933,7 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
1185211933 BigInt orig_bigint;
1185311934 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint);
1185411935 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) {
11855 return ErrorShiftedOutOneBits;
11936 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits"));
1185611937 }
1185711938 break;
1185811939 }
......@@ -11920,14 +12001,14 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
1192012001 BigInt remainder;
1192112002 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
1192212003 if (bigint_cmp_zero(&remainder) != CmpEQ) {
11923 return ErrorExactDivRemainder;
12004 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
1192412005 }
1192512006 } else {
1192612007 float_div_trunc(out_val, op1_val, op2_val);
1192712008 ConstExprValue remainder;
1192812009 float_rem(&remainder, op1_val, op2_val);
1192912010 if (float_cmp_zero(&remainder) != CmpEQ) {
11930 return ErrorExactDivRemainder;
12011 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
1193112012 }
1193212013 }
1193312014 break;
......@@ -11951,13 +12032,51 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
1195112032 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count,
1195212033 type_entry->data.integral.is_signed))
1195312034 {
11954 return ErrorOverflow;
12035 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow"));
1195512036 }
1195612037 }
1195712038
1195812039 out_val->type = type_entry;
1195912040 out_val->special = ConstValSpecialStatic;
11960 return 0;
12041 return nullptr;
12042}
12043
12044// This works on operands that have already been checked to be comptime known.
12045static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr,
12046 ZigType *type_entry, ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val)
12047{
12048 IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry);
12049 ConstExprValue *out_val = &result_instruction->value;
12050 if (type_entry->id == ZigTypeIdVector) {
12051 expand_undef_array(ira->codegen, op1_val);
12052 expand_undef_array(ira->codegen, op2_val);
12053 out_val->special = ConstValSpecialUndef;
12054 expand_undef_array(ira->codegen, out_val);
12055 size_t len = type_entry->data.vector.len;
12056 ZigType *scalar_type = type_entry->data.vector.elem_type;
12057 for (size_t i = 0; i < len; i += 1) {
12058 ConstExprValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i];
12059 ConstExprValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i];
12060 ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i];
12061 assert(scalar_op1_val->type == scalar_type);
12062 assert(scalar_op2_val->type == scalar_type);
12063 assert(scalar_out_val->type == scalar_type);
12064 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type,
12065 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val);
12066 if (msg != nullptr) {
12067 add_error_note(ira->codegen, msg, source_instr->source_node,
12068 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i));
12069 return ira->codegen->invalid_instruction;
12070 }
12071 }
12072 out_val->type = type_entry;
12073 out_val->special = ConstValSpecialStatic;
12074 } else {
12075 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) {
12076 return ira->codegen->invalid_instruction;
12077 }
12078 }
12079 return ir_implicit_cast(ira, result_instruction, type_entry);
1196112080}
1196212081
1196312082static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
......@@ -12029,24 +12148,7 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b
1202912148 if (op2_val == nullptr)
1203012149 return ira->codegen->invalid_instruction;
1203112150
12032 IrInstruction *result_instruction = ir_const(ira, &bin_op_instruction->base, op1->value.type);
12033
12034 int err;
12035 if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, &result_instruction->value))) {
12036 if (err == ErrorOverflow) {
12037 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow"));
12038 return ira->codegen->invalid_instruction;
12039 } else if (err == ErrorShiftedOutOneBits) {
12040 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("exact shift shifted out 1 bits"));
12041 return ira->codegen->invalid_instruction;
12042 } else {
12043 zig_unreachable();
12044 }
12045 return ira->codegen->invalid_instruction;
12046 }
12047
12048 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);
12049 return result_instruction;
12151 return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value.type, op1_val, op_id, op2_val);
1205012152 } else if (op1->value.type->id == ZigTypeIdComptimeInt) {
1205112153 ir_add_error(ira, &bin_op_instruction->base,
1205212154 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known"));
......@@ -12292,30 +12394,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1229212394 if (op2_val == nullptr)
1229312395 return ira->codegen->invalid_instruction;
1229412396
12295 IrInstruction *result_instruction = ir_const(ira, &instruction->base, resolved_type);
12296
12297 int err;
12298 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, &result_instruction->value))) {
12299 if (err == ErrorDivByZero) {
12300 ir_add_error(ira, &instruction->base, buf_sprintf("division by zero"));
12301 return ira->codegen->invalid_instruction;
12302 } else if (err == ErrorOverflow) {
12303 ir_add_error(ira, &instruction->base, buf_sprintf("operation caused overflow"));
12304 return ira->codegen->invalid_instruction;
12305 } else if (err == ErrorExactDivRemainder) {
12306 ir_add_error(ira, &instruction->base, buf_sprintf("exact division had a remainder"));
12307 return ira->codegen->invalid_instruction;
12308 } else if (err == ErrorNegativeDenominator) {
12309 ir_add_error(ira, &instruction->base, buf_sprintf("negative denominator"));
12310 return ira->codegen->invalid_instruction;
12311 } else {
12312 zig_unreachable();
12313 }
12314 return ira->codegen->invalid_instruction;
12315 }
12316
12317 ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false);
12318 return result_instruction;
12397 return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val);
1231912398 }
1232012399
1232112400 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope,
......@@ -18745,10 +18824,7 @@ static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstr
1874518824 if (type_is_invalid(elem_type))
1874618825 return ira->codegen->invalid_instruction;
1874718826
18748 if (elem_type->id != ZigTypeIdInt &&
18749 elem_type->id != ZigTypeIdFloat &&
18750 get_codegen_ptr_type(elem_type) == nullptr)
18751 {
18827 if (!is_valid_vector_elem_type(elem_type)) {
1875218828 ir_add_error(ira, instruction->elem_type,
1875318829 buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid",
1875418830 buf_ptr(&elem_type->name)));
......@@ -20345,6 +20421,17 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
2034520421 return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value);
2034620422}
2034720423
20424static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExprValue *val, size_t len) {
20425 size_t buf_i = 0;
20426 // TODO optimize the buf case
20427 expand_undef_array(codegen, val);
20428 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
20429 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
20430 buf_write_value_bytes(codegen, &buf[buf_i], elem);
20431 buf_i += type_size(codegen, elem->type);
20432 }
20433}
20434
2034820435static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
2034920436 if (val->special == ConstValSpecialUndef)
2035020437 val->special = ConstValSpecialStatic;
......@@ -20390,26 +20477,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2039020477 zig_unreachable();
2039120478 }
2039220479 case ZigTypeIdArray:
20393 {
20394 size_t buf_i = 0;
20395 // TODO optimize the buf case
20396 expand_undef_array(codegen, val);
20397 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
20398 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
20399 buf_write_value_bytes(codegen, &buf[buf_i], elem);
20400 buf_i += type_size(codegen, elem->type);
20401 }
20402 }
20403 return;
20404 case ZigTypeIdVector: {
20405 size_t buf_i = 0;
20406 for (uint32_t elem_i = 0; elem_i < val->type->data.vector.len; elem_i += 1) {
20407 ConstExprValue *elem = &val->data.x_vector.elements[elem_i];
20408 buf_write_value_bytes(codegen, &buf[buf_i], elem);
20409 buf_i += type_size(codegen, elem->type);
20410 }
20411 return;
20412 }
20480 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len);
20481 case ZigTypeIdVector:
20482 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len);
2041320483 case ZigTypeIdStruct:
2041420484 zig_panic("TODO buf_write_value_bytes struct type");
2041520485 case ZigTypeIdOptional:
......@@ -20426,6 +20496,31 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2042620496 zig_unreachable();
2042720497}
2042820498
20499static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf,
20500 ConstExprValue *val, ZigType *elem_type, size_t len)
20501{
20502 Error err;
20503 uint64_t elem_size = type_size(codegen, elem_type);
20504
20505 switch (val->data.x_array.special) {
20506 case ConstArraySpecialNone:
20507 val->data.x_array.data.s_none.elements = create_const_vals(len);
20508 for (size_t i = 0; i < len; i++) {
20509 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i];
20510 elem->special = ConstValSpecialStatic;
20511 elem->type = elem_type;
20512 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
20513 return err;
20514 }
20515 return ErrorNone;
20516 case ConstArraySpecialUndef:
20517 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type");
20518 case ConstArraySpecialBuf:
20519 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type");
20520 }
20521 zig_unreachable();
20522}
20523
2042920524static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
2043020525 Error err;
2043120526 assert(val->special == ConstValSpecialStatic);
......@@ -20464,42 +20559,12 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2046420559 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
2046520560 return ErrorNone;
2046620561 }
20467 case ZigTypeIdArray: {
20468 uint64_t elem_size = type_size(codegen, val->type->data.array.child_type);
20469 size_t len = val->type->data.array.len;
20470
20471 switch (val->data.x_array.special) {
20472 case ConstArraySpecialNone:
20473 val->data.x_array.data.s_none.elements = create_const_vals(len);
20474 for (size_t i = 0; i < len; i++) {
20475 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i];
20476 elem->special = ConstValSpecialStatic;
20477 elem->type = val->type->data.array.child_type;
20478 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
20479 return err;
20480 }
20481 return ErrorNone;
20482 case ConstArraySpecialUndef:
20483 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type");
20484 case ConstArraySpecialBuf:
20485 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type");
20486 }
20487 zig_unreachable();
20488 }
20489 case ZigTypeIdVector: {
20490 uint64_t elem_size = type_size(codegen, val->type->data.vector.elem_type);
20491 uint32_t len = val->type->data.vector.len;
20492
20493 val->data.x_vector.elements = create_const_vals(len);
20494 for (uint32_t i = 0; i < len; i += 1) {
20495 ConstExprValue *elem = &val->data.x_vector.elements[i];
20496 elem->special = ConstValSpecialStatic;
20497 elem->type = val->type->data.vector.elem_type;
20498 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
20499 return err;
20500 }
20501 return ErrorNone;
20502 }
20562 case ZigTypeIdArray:
20563 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type,
20564 val->type->data.array.len);
20565 case ZigTypeIdVector:
20566 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type,
20567 val->type->data.vector.len);
2050320568 case ZigTypeIdEnum:
2050420569 switch (val->type->data.enumeration.layout) {
2050520570 case ContainerLayoutAuto:
......@@ -21634,6 +21699,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2163421699 case IrInstructionIdDeclVarGen:
2163521700 case IrInstructionIdPtrCastGen:
2163621701 case IrInstructionIdCmpxchgGen:
21702 case IrInstructionIdArrayToVector:
21703 case IrInstructionIdVectorToArray:
2163721704 zig_unreachable();
2163821705
2163921706 case IrInstructionIdReturn:
......@@ -22129,6 +22196,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2212922196 case IrInstructionIdFromBytes:
2213022197 case IrInstructionIdToBytes:
2213122198 case IrInstructionIdEnumToInt:
22199 case IrInstructionIdVectorToArray:
22200 case IrInstructionIdArrayToVector:
2213222201 return false;
2213322202
2213422203 case IrInstructionIdAsm:
src/ir_print.cpp+18
......@@ -972,6 +972,18 @@ static void ir_print_check_runtime_scope(IrPrint *irp, IrInstructionCheckRuntime
972972 fprintf(irp->f, ")");
973973}
974974
975static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *instruction) {
976 fprintf(irp->f, "ArrayToVector(");
977 ir_print_other_instruction(irp, instruction->array);
978 fprintf(irp->f, ")");
979}
980
981static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
982 fprintf(irp->f, "VectorToArray(");
983 ir_print_other_instruction(irp, instruction->vector);
984 fprintf(irp->f, ")");
985}
986
975987static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
976988 fprintf(irp->f, "inttoerr ");
977989 ir_print_other_instruction(irp, instruction->target);
......@@ -1825,6 +1837,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
18251837 case IrInstructionIdDeclVarGen:
18261838 ir_print_decl_var_gen(irp, (IrInstructionDeclVarGen *)instruction);
18271839 break;
1840 case IrInstructionIdArrayToVector:
1841 ir_print_array_to_vector(irp, (IrInstructionArrayToVector *)instruction);
1842 break;
1843 case IrInstructionIdVectorToArray:
1844 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
1845 break;
18281846 }
18291847 fprintf(irp->f, "\n");
18301848}
test/stage1/behavior.zig+1
......@@ -74,6 +74,7 @@ comptime {
7474 _ = @import("behavior/underscore.zig");
7575 _ = @import("behavior/union.zig");
7676 _ = @import("behavior/var_args.zig");
77 _ = @import("behavior/vector.zig");
7778 _ = @import("behavior/void.zig");
7879 _ = @import("behavior/while.zig");
7980 _ = @import("behavior/widening.zig");
test/stage1/behavior/vector.zig created+20
......@@ -0,0 +1,20 @@
1const std = @import("std");
2const assertOrPanic = std.debug.assertOrPanic;
3
4test "implicit array to vector and vector to array" {
5 const S = struct {
6 fn doTheTest() void {
7 var v: @Vector(4, i32) = [4]i32{10, 20, 30, 40};
8 const x: @Vector(4, i32) = [4]i32{1, 2, 3, 4};
9 v +%= x;
10 const result: [4]i32 = v;
11 assertOrPanic(result[0] == 11);
12 assertOrPanic(result[1] == 22);
13 assertOrPanic(result[2] == 33);
14 assertOrPanic(result[3] == 44);
15 }
16 };
17 S.doTheTest();
18 comptime S.doTheTest();
19}
20