| author | |
| committer | |
| log | 01577a3af480cff02c5f78864f8056487b3d3b44 |
| tree | 9d029218b191a5c3f5701153fd1784eafae08e3f |
| parent | 0048bcbd71b9139203d7acee120d524d38e22a0e |
| signature |
6 files changed, 157 insertions(+), 10 deletions(-)
src/all_types.hpp+9| ... | @@ -1612,6 +1612,7 @@ enum BuiltinFnId { | ... | @@ -1612,6 +1612,7 @@ enum BuiltinFnId { |
| 1612 | BuiltinFnIdIntType, | 1612 | BuiltinFnIdIntType, |
| 1613 | BuiltinFnIdVectorType, | 1613 | BuiltinFnIdVectorType, |
| 1614 | BuiltinFnIdShuffle, | 1614 | BuiltinFnIdShuffle, |
| 1615 | BuiltinFnIdSplat, | ||
| 1615 | BuiltinFnIdSetCold, | 1616 | BuiltinFnIdSetCold, |
| 1616 | BuiltinFnIdSetRuntimeSafety, | 1617 | BuiltinFnIdSetRuntimeSafety, |
| 1617 | BuiltinFnIdSetFloatMode, | 1618 | BuiltinFnIdSetFloatMode, |
| ... | @@ -2431,6 +2432,7 @@ enum IrInstructionId { | ... | @@ -2431,6 +2432,7 @@ enum IrInstructionId { |
| 2431 | IrInstructionIdIntType, | 2432 | IrInstructionIdIntType, |
| 2432 | IrInstructionIdVectorType, | 2433 | IrInstructionIdVectorType, |
| 2433 | IrInstructionIdShuffleVector, | 2434 | IrInstructionIdShuffleVector, |
| 2435 | IrInstructionIdSplat, | ||
| 2434 | IrInstructionIdBoolNot, | 2436 | IrInstructionIdBoolNot, |
| 2435 | IrInstructionIdMemset, | 2437 | IrInstructionIdMemset, |
| 2436 | IrInstructionIdMemcpy, | 2438 | IrInstructionIdMemcpy, |
| ... | @@ -3681,6 +3683,13 @@ struct IrInstructionShuffleVector { | ... | @@ -3681,6 +3683,13 @@ struct IrInstructionShuffleVector { |
| 3681 | IrInstruction *mask; // This is in zig-format, not llvm format | 3683 | IrInstruction *mask; // This is in zig-format, not llvm format |
| 3682 | }; | 3684 | }; |
| 3683 | 3685 | ||
| 3686 | struct IrInstructionSplat { | ||
| 3687 | IrInstruction base; | ||
| 3688 | |||
| 3689 | IrInstruction *len; | ||
| 3690 | IrInstruction *scalar; | ||
| 3691 | }; | ||
| 3692 | |||
| 3684 | struct IrInstructionAssertZero { | 3693 | struct IrInstructionAssertZero { |
| 3685 | IrInstruction base; | 3694 | IrInstruction base; |
| 3686 | 3695 |
src/codegen.cpp+17| ... | @@ -4619,6 +4619,20 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executabl | ... | @@ -4619,6 +4619,20 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executabl |
| 4619 | llvm_mask_value, ""); | 4619 | llvm_mask_value, ""); |
| 4620 | } | 4620 | } |
| 4621 | 4621 | ||
| 4622 | static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutable *executable, IrInstructionSplat *instruction) { | ||
| 4623 | uint64_t len = bigint_as_u64(&instruction->len->value.data.x_bigint); | ||
| 4624 | LLVMValueRef wrapped_scalar_undef = LLVMGetUndef(instruction->base.value.type->llvm_type); | ||
| 4625 | LLVMValueRef wrapped_scalar = LLVMBuildInsertElement(g->builder, wrapped_scalar_undef, | ||
| 4626 | ir_llvm_value(g, instruction->scalar), | ||
| 4627 | LLVMConstInt(LLVMInt32Type(), 0, false), | ||
| 4628 | ""); | ||
| 4629 | return LLVMBuildShuffleVector(g->builder, | ||
| 4630 | wrapped_scalar, | ||
| 4631 | wrapped_scalar_undef, | ||
| 4632 | LLVMConstNull(LLVMVectorType(g->builtin_types.entry_u32->llvm_type, (uint32_t)len)), | ||
| 4633 | ""); | ||
| 4634 | } | ||
| 4635 | |||
| 4622 | static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { | 4636 | static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { |
| 4623 | ZigType *int_type = instruction->op->value.type; | 4637 | ZigType *int_type = instruction->op->value.type; |
| 4624 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); | 4638 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); |
| ... | @@ -6146,6 +6160,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -6146,6 +6160,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 6146 | return ir_render_spill_end(g, executable, (IrInstructionSpillEnd *)instruction); | 6160 | return ir_render_spill_end(g, executable, (IrInstructionSpillEnd *)instruction); |
| 6147 | case IrInstructionIdShuffleVector: | 6161 | case IrInstructionIdShuffleVector: |
| 6148 | return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction); | 6162 | return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction); |
| 6163 | case IrInstructionIdSplat: | ||
| 6164 | return ir_render_splat(g, executable, (IrInstructionSplat *) instruction); | ||
| 6149 | } | 6165 | } |
| 6150 | zig_unreachable(); | 6166 | zig_unreachable(); |
| 6151 | } | 6167 | } |
| ... | @@ -7837,6 +7853,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -7837,6 +7853,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 7837 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int | 7853 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int |
| 7838 | create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); | 7854 | create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); |
| 7839 | create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4); | 7855 | create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4); |
| 7856 | create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2); | ||
| 7840 | create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); | 7857 | create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); |
| 7841 | create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); | 7858 | create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); |
| 7842 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); | 7859 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); |
src/ir.cpp+82| ... | @@ -721,6 +721,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionShuffleVector *) | ... | @@ -721,6 +721,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionShuffleVector *) |
| 721 | return IrInstructionIdShuffleVector; | 721 | return IrInstructionIdShuffleVector; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSplat *) { | ||
| 725 | return IrInstructionIdSplat; | ||
| 726 | } | ||
| 727 | |||
| 724 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { | 728 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { |
| 725 | return IrInstructionIdBoolNot; | 729 | return IrInstructionIdBoolNot; |
| 726 | } | 730 | } |
| ... | @@ -2300,6 +2304,19 @@ static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstN | ... | @@ -2300,6 +2304,19 @@ static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstN |
| 2300 | return &instruction->base; | 2304 | return &instruction->base; |
| 2301 | } | 2305 | } |
| 2302 | 2306 | ||
| 2307 | static IrInstruction *ir_build_splat(IrBuilder *irb, Scope *scope, AstNode *source_node, | ||
| 2308 | IrInstruction *len, IrInstruction *scalar) | ||
| 2309 | { | ||
| 2310 | IrInstructionSplat *instruction = ir_build_instruction<IrInstructionSplat>(irb, scope, source_node); | ||
| 2311 | instruction->len = len; | ||
| 2312 | instruction->scalar = scalar; | ||
| 2313 | |||
| 2314 | ir_ref_instruction(len, irb->current_basic_block); | ||
| 2315 | ir_ref_instruction(scalar, irb->current_basic_block); | ||
| 2316 | |||
| 2317 | return &instruction->base; | ||
| 2318 | } | ||
| 2319 | |||
| 2303 | static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 2320 | static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 2304 | IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); | 2321 | IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); |
| 2305 | instruction->value = value; | 2322 | instruction->value = value; |
| ... | @@ -4985,6 +5002,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4985,6 +5002,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4985 | arg0_value, arg1_value, arg2_value, arg3_value); | 5002 | arg0_value, arg1_value, arg2_value, arg3_value); |
| 4986 | return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); | 5003 | return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); |
| 4987 | } | 5004 | } |
| 5005 | case BuiltinFnIdSplat: | ||
| 5006 | { | ||
| 5007 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 5008 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 5009 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 5010 | return arg0_value; | ||
| 5011 | |||
| 5012 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 5013 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 5014 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 5015 | return arg1_value; | ||
| 5016 | |||
| 5017 | IrInstruction *splat = ir_build_splat(irb, scope, node, | ||
| 5018 | arg0_value, arg1_value); | ||
| 5019 | return ir_lval_wrap(irb, scope, splat, lval, result_loc); | ||
| 5020 | } | ||
| 4988 | case BuiltinFnIdMemcpy: | 5021 | case BuiltinFnIdMemcpy: |
| 4989 | { | 5022 | { |
| 4990 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5023 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -22324,6 +22357,52 @@ static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrIn | ... | @@ -22324,6 +22357,52 @@ static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrIn |
| 22324 | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); | 22357 | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); |
| 22325 | } | 22358 | } |
| 22326 | 22359 | ||
| 22360 | static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstructionSplat *instruction) { | ||
| 22361 | IrInstruction *len = instruction->len->child; | ||
| 22362 | if (type_is_invalid(len->value.type)) | ||
| 22363 | return ira->codegen->invalid_instruction; | ||
| 22364 | |||
| 22365 | IrInstruction *scalar = instruction->scalar->child; | ||
| 22366 | if (type_is_invalid(scalar->value.type)) | ||
| 22367 | return ira->codegen->invalid_instruction; | ||
| 22368 | |||
| 22369 | uint64_t len_int; | ||
| 22370 | if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_int)) { | ||
| 22371 | ir_add_error(ira, len, | ||
| 22372 | buf_sprintf("splat length must be comptime")); | ||
| 22373 | return ira->codegen->invalid_instruction; | ||
| 22374 | } | ||
| 22375 | |||
| 22376 | if (!is_valid_vector_elem_type(scalar->value.type)) { | ||
| 22377 | ir_add_error(ira, len, | ||
| 22378 | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", | ||
| 22379 | buf_ptr(&scalar->value.type->name))); | ||
| 22380 | return ira->codegen->invalid_instruction; | ||
| 22381 | } | ||
| 22382 | |||
| 22383 | ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value.type); | ||
| 22384 | |||
| 22385 | if (instr_is_comptime(scalar)) { | ||
| 22386 | IrInstruction *result = ir_const_undef(ira, scalar, return_type); | ||
| 22387 | result->value.data.x_array.data.s_none.elements = | ||
| 22388 | allocate<ConstExprValue>(len_int); | ||
| 22389 | for (uint32_t i = 0; i < len_int; i++) { | ||
| 22390 | result->value.data.x_array.data.s_none.elements[i] = | ||
| 22391 | scalar->value; | ||
| 22392 | } | ||
| 22393 | result->value.type = return_type; | ||
| 22394 | result->value.special = ConstValSpecialStatic; | ||
| 22395 | return result; | ||
| 22396 | } | ||
| 22397 | |||
| 22398 | IrInstruction *result = ir_build_splat(&ira->new_irb, | ||
| 22399 | instruction->base.scope, instruction->base.source_node, | ||
| 22400 | instruction->len->child, instruction->scalar->child); | ||
| 22401 | result->value.type = return_type; | ||
| 22402 | result->value.special = ConstValSpecialRuntime; | ||
| 22403 | return result; | ||
| 22404 | } | ||
| 22405 | |||
| 22327 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { | 22406 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { |
| 22328 | IrInstruction *value = instruction->value->child; | 22407 | IrInstruction *value = instruction->value->child; |
| 22329 | if (type_is_invalid(value->value.type)) | 22408 | if (type_is_invalid(value->value.type)) |
| ... | @@ -25908,6 +25987,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction | ... | @@ -25908,6 +25987,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25908 | return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); | 25987 | return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); |
| 25909 | case IrInstructionIdShuffleVector: | 25988 | case IrInstructionIdShuffleVector: |
| 25910 | return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); | 25989 | return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); |
| 25990 | case IrInstructionIdSplat: | ||
| 25991 | return ir_analyze_instruction_splat(ira, (IrInstructionSplat *)instruction); | ||
| 25911 | case IrInstructionIdBoolNot: | 25992 | case IrInstructionIdBoolNot: |
| 25912 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); | 25993 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); |
| 25913 | case IrInstructionIdMemset: | 25994 | case IrInstructionIdMemset: |
| ... | @@ -26244,6 +26325,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -26244,6 +26325,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 26244 | case IrInstructionIdIntType: | 26325 | case IrInstructionIdIntType: |
| 26245 | case IrInstructionIdVectorType: | 26326 | case IrInstructionIdVectorType: |
| 26246 | case IrInstructionIdShuffleVector: | 26327 | case IrInstructionIdShuffleVector: |
| 26328 | case IrInstructionIdSplat: | ||
| 26247 | case IrInstructionIdBoolNot: | 26329 | case IrInstructionIdBoolNot: |
| 26248 | case IrInstructionIdSliceSrc: | 26330 | case IrInstructionIdSliceSrc: |
| 26249 | case IrInstructionIdMemberCount: | 26331 | case IrInstructionIdMemberCount: |
src/ir_print.cpp+13| ... | @@ -44,6 +44,8 @@ static const char* ir_instruction_type_str(IrInstruction* instruction) { | ... | @@ -44,6 +44,8 @@ static const char* ir_instruction_type_str(IrInstruction* instruction) { |
| 44 | return "Invalid"; | 44 | return "Invalid"; |
| 45 | case IrInstructionIdShuffleVector: | 45 | case IrInstructionIdShuffleVector: |
| 46 | return "Shuffle"; | 46 | return "Shuffle"; |
| 47 | case IrInstructionIdSplat: | ||
| 48 | return "Splat"; | ||
| 47 | case IrInstructionIdDeclVarSrc: | 49 | case IrInstructionIdDeclVarSrc: |
| 48 | return "DeclVarSrc"; | 50 | return "DeclVarSrc"; |
| 49 | case IrInstructionIdDeclVarGen: | 51 | case IrInstructionIdDeclVarGen: |
| ... | @@ -1222,6 +1224,14 @@ static void ir_print_shuffle_vector(IrPrint *irp, IrInstructionShuffleVector *in | ... | @@ -1222,6 +1224,14 @@ static void ir_print_shuffle_vector(IrPrint *irp, IrInstructionShuffleVector *in |
| 1222 | fprintf(irp->f, ")"); | 1224 | fprintf(irp->f, ")"); |
| 1223 | } | 1225 | } |
| 1224 | 1226 | ||
| 1227 | static void ir_print_splat(IrPrint *irp, IrInstructionSplat *instruction) { | ||
| 1228 | fprintf(irp->f, "@splat("); | ||
| 1229 | ir_print_other_instruction(irp, instruction->len); | ||
| 1230 | fprintf(irp->f, ", "); | ||
| 1231 | ir_print_other_instruction(irp, instruction->scalar); | ||
| 1232 | fprintf(irp->f, ")"); | ||
| 1233 | } | ||
| 1234 | |||
| 1225 | static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) { | 1235 | static void ir_print_bool_not(IrPrint *irp, IrInstructionBoolNot *instruction) { |
| 1226 | fprintf(irp->f, "! "); | 1236 | fprintf(irp->f, "! "); |
| 1227 | ir_print_other_instruction(irp, instruction->value); | 1237 | ir_print_other_instruction(irp, instruction->value); |
| ... | @@ -2160,6 +2170,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool | ... | @@ -2160,6 +2170,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool |
| 2160 | case IrInstructionIdShuffleVector: | 2170 | case IrInstructionIdShuffleVector: |
| 2161 | ir_print_shuffle_vector(irp, (IrInstructionShuffleVector *)instruction); | 2171 | ir_print_shuffle_vector(irp, (IrInstructionShuffleVector *)instruction); |
| 2162 | break; | 2172 | break; |
| 2173 | case IrInstructionIdSplat: | ||
| 2174 | ir_print_splat(irp, (IrInstructionSplat *)instruction); | ||
| 2175 | break; | ||
| 2163 | case IrInstructionIdBoolNot: | 2176 | case IrInstructionIdBoolNot: |
| 2164 | ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction); | 2177 | ir_print_bool_not(irp, (IrInstructionBoolNot *)instruction); |
| 2165 | break; | 2178 | break; |
test/compile_errors.zig+10| ... | @@ -6507,6 +6507,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -6507,6 +6507,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6507 | "tmp.zig:2:26: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid", | 6507 | "tmp.zig:2:26: error: vector element type must be integer, float, bool, or pointer; '@Vector(4, u8)' is invalid", |
| 6508 | ); | 6508 | ); |
| 6509 | 6509 | ||
| 6510 | cases.addTest( | ||
| 6511 | "bad @splat type", | ||
| 6512 | \\export fn entry() void { | ||
| 6513 | \\ const c = 4; | ||
| 6514 | \\ var v = @splat(4, c); | ||
| 6515 | \\} | ||
| 6516 | , | ||
| 6517 | "tmp.zig:3:20: error: vector element type must be integer, float, bool, or pointer; 'comptime_int' is invalid", | ||
| 6518 | ); | ||
| 6519 | |||
| 6510 | cases.add("compileLog of tagged enum doesn't crash the compiler", | 6520 | cases.add("compileLog of tagged enum doesn't crash the compiler", |
| 6511 | \\const Bar = union(enum(u32)) { | 6521 | \\const Bar = union(enum(u32)) { |
| 6512 | \\ X: i32 = 1 | 6522 | \\ X: i32 = 1 |
test/stage1/behavior/vector.zig+26-10| ... | @@ -35,12 +35,12 @@ test "vector bin compares with mem.eql" { | ... | @@ -35,12 +35,12 @@ test "vector bin compares with mem.eql" { |
| 35 | fn doTheTest() void { | 35 | fn doTheTest() void { |
| 36 | var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | 36 | var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; |
| 37 | var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 }; | 37 | var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 }; |
| 38 | expect(mem.eql(bool, ([4]bool)(v == x), [4]bool{ false, false, true, false})); | 38 | expect(mem.eql(bool, ([4]bool)(v == x), [4]bool{ false, false, true, false })); |
| 39 | expect(mem.eql(bool, ([4]bool)(v != x), [4]bool{ true, true, false, true})); | 39 | expect(mem.eql(bool, ([4]bool)(v != x), [4]bool{ true, true, false, true })); |
| 40 | expect(mem.eql(bool, ([4]bool)(v < x), [4]bool{ false, true, false, false})); | 40 | expect(mem.eql(bool, ([4]bool)(v < x), [4]bool{ false, true, false, false })); |
| 41 | expect(mem.eql(bool, ([4]bool)(v > x), [4]bool{ true, false, false, true})); | 41 | expect(mem.eql(bool, ([4]bool)(v > x), [4]bool{ true, false, false, true })); |
| 42 | expect(mem.eql(bool, ([4]bool)(v <= x), [4]bool{ false, true, true, false})); | 42 | expect(mem.eql(bool, ([4]bool)(v <= x), [4]bool{ false, true, true, false })); |
| 43 | expect(mem.eql(bool, ([4]bool)(v >= x), [4]bool{ true, false, true, true})); | 43 | expect(mem.eql(bool, ([4]bool)(v >= x), [4]bool{ true, false, true, true })); |
| 44 | } | 44 | } |
| 45 | }; | 45 | }; |
| 46 | S.doTheTest(); | 46 | S.doTheTest(); |
| ... | @@ -114,22 +114,22 @@ test "vector casts of sizes not divisable by 8" { | ... | @@ -114,22 +114,22 @@ test "vector casts of sizes not divisable by 8" { |
| 114 | const S = struct { | 114 | const S = struct { |
| 115 | fn doTheTest() void { | 115 | fn doTheTest() void { |
| 116 | { | 116 | { |
| 117 | var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0}; | 117 | var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 }; |
| 118 | var x: [4]u3 = v; | 118 | var x: [4]u3 = v; |
| 119 | expect(mem.eql(u3, x, ([4]u3)(v))); | 119 | expect(mem.eql(u3, x, ([4]u3)(v))); |
| 120 | } | 120 | } |
| 121 | { | 121 | { |
| 122 | var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0}; | 122 | var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 }; |
| 123 | var x: [4]u2 = v; | 123 | var x: [4]u2 = v; |
| 124 | expect(mem.eql(u2, x, ([4]u2)(v))); | 124 | expect(mem.eql(u2, x, ([4]u2)(v))); |
| 125 | } | 125 | } |
| 126 | { | 126 | { |
| 127 | var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0}; | 127 | var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 }; |
| 128 | var x: [4]u1 = v; | 128 | var x: [4]u1 = v; |
| 129 | expect(mem.eql(u1, x, ([4]u1)(v))); | 129 | expect(mem.eql(u1, x, ([4]u1)(v))); |
| 130 | } | 130 | } |
| 131 | { | 131 | { |
| 132 | var v: @Vector(4, bool) = [4]bool{ false, false, true, false}; | 132 | var v: @Vector(4, bool) = [4]bool{ false, false, true, false }; |
| 133 | var x: [4]bool = v; | 133 | var x: [4]bool = v; |
| 134 | expect(mem.eql(bool, x, ([4]bool)(v))); | 134 | expect(mem.eql(bool, x, ([4]bool)(v))); |
| 135 | } | 135 | } |
| ... | @@ -138,3 +138,19 @@ test "vector casts of sizes not divisable by 8" { | ... | @@ -138,3 +138,19 @@ test "vector casts of sizes not divisable by 8" { |
| 138 | S.doTheTest(); | 138 | S.doTheTest(); |
| 139 | comptime S.doTheTest(); | 139 | comptime S.doTheTest(); |
| 140 | } | 140 | } |
| 141 | |||
| 142 | test "vector @splat" { | ||
| 143 | const S = struct { | ||
| 144 | fn doTheTest() void { | ||
| 145 | var v: u32 = 5; | ||
| 146 | var x = @splat(4, v); | ||
| 147 | expect(@typeOf(x) == @Vector(4, u32)); | ||
| 148 | expect(x[0] == 5); | ||
| 149 | expect(x[1] == 5); | ||
| 150 | expect(x[2] == 5); | ||
| 151 | expect(x[3] == 5); | ||
| 152 | } | ||
| 153 | }; | ||
| 154 | S.doTheTest(); | ||
| 155 | comptime S.doTheTest(); | ||
| 156 | } |