| ... | @@ -721,8 +721,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionShuffleVector *) | ... | @@ -721,8 +721,12 @@ 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 *) { | 724 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatSrc *) { |
| 725 | return IrInstructionIdSplat; | 725 | return IrInstructionIdSplatSrc; |
| | 726 | } |
| | 727 | |
| | 728 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatGen *) { |
| | 729 | return IrInstructionIdSplatGen; |
| 726 | } | 730 | } |
| 727 | | 731 | |
| 728 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { | 732 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { |
| ... | @@ -2304,10 +2308,10 @@ static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstN | ... | @@ -2304,10 +2308,10 @@ static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstN |
| 2304 | return &instruction->base; | 2308 | return &instruction->base; |
| 2305 | } | 2309 | } |
| 2306 | | 2310 | |
| 2307 | static IrInstruction *ir_build_splat(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2311 | static IrInstruction *ir_build_splat_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2308 | IrInstruction *len, IrInstruction *scalar) | 2312 | IrInstruction *len, IrInstruction *scalar) |
| 2309 | { | 2313 | { |
| 2310 | IrInstructionSplat *instruction = ir_build_instruction<IrInstructionSplat>(irb, scope, source_node); | 2314 | IrInstructionSplatSrc *instruction = ir_build_instruction<IrInstructionSplatSrc>(irb, scope, source_node); |
| 2311 | instruction->len = len; | 2315 | instruction->len = len; |
| 2312 | instruction->scalar = scalar; | 2316 | instruction->scalar = scalar; |
| 2313 | | 2317 | |
| ... | @@ -2373,6 +2377,19 @@ static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2373,6 +2377,19 @@ static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode * |
| 2373 | return &instruction->base; | 2377 | return &instruction->base; |
| 2374 | } | 2378 | } |
| 2375 | | 2379 | |
| | 2380 | static IrInstruction *ir_build_splat_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, |
| | 2381 | IrInstruction *scalar) |
| | 2382 | { |
| | 2383 | IrInstructionSplatGen *instruction = ir_build_instruction<IrInstructionSplatGen>( |
| | 2384 | &ira->new_irb, source_instruction->scope, source_instruction->source_node); |
| | 2385 | instruction->base.value.type = result_type; |
| | 2386 | instruction->scalar = scalar; |
| | 2387 | |
| | 2388 | ir_ref_instruction(scalar, ira->new_irb.current_basic_block); |
| | 2389 | |
| | 2390 | return &instruction->base; |
| | 2391 | } |
| | 2392 | |
| 2376 | static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, | 2393 | static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, |
| 2377 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) | 2394 | IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) |
| 2378 | { | 2395 | { |
| ... | @@ -5014,7 +5031,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5014,7 +5031,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5014 | if (arg1_value == irb->codegen->invalid_instruction) | 5031 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5015 | return arg1_value; | 5032 | return arg1_value; |
| 5016 | | 5033 | |
| 5017 | IrInstruction *splat = ir_build_splat(irb, scope, node, | 5034 | IrInstruction *splat = ir_build_splat_src(irb, scope, node, |
| 5018 | arg0_value, arg1_value); | 5035 | arg0_value, arg1_value); |
| 5019 | return ir_lval_wrap(irb, scope, splat, lval, result_loc); | 5036 | return ir_lval_wrap(irb, scope, splat, lval, result_loc); |
| 5020 | } | 5037 | } |
| ... | @@ -11082,16 +11099,23 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { | ... | @@ -11082,16 +11099,23 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 11082 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); | 11099 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); |
| 11083 | } | 11100 | } |
| 11084 | | 11101 | |
| | 11102 | static Error ir_validate_vector_elem_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *elem_type) { |
| | 11103 | if (!is_valid_vector_elem_type(elem_type)) { |
| | 11104 | ir_add_error(ira, source_instr, |
| | 11105 | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", |
| | 11106 | buf_ptr(&elem_type->name))); |
| | 11107 | return ErrorSemanticAnalyzeFail; |
| | 11108 | } |
| | 11109 | return ErrorNone; |
| | 11110 | } |
| | 11111 | |
| 11085 | static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstruction *elem_type_value) { | 11112 | static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstruction *elem_type_value) { |
| | 11113 | Error err; |
| 11086 | ZigType *elem_type = ir_resolve_type(ira, elem_type_value); | 11114 | ZigType *elem_type = ir_resolve_type(ira, elem_type_value); |
| 11087 | if (type_is_invalid(elem_type)) | 11115 | if (type_is_invalid(elem_type)) |
| 11088 | return ira->codegen->builtin_types.entry_invalid; | 11116 | return ira->codegen->builtin_types.entry_invalid; |
| 11089 | if (!is_valid_vector_elem_type(elem_type)) { | 11117 | if ((err = ir_validate_vector_elem_type(ira, elem_type_value, elem_type))) |
| 11090 | ir_add_error(ira, elem_type_value, | | |
| 11091 | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", | | |
| 11092 | buf_ptr(&elem_type->name))); | | |
| 11093 | return ira->codegen->builtin_types.entry_invalid; | 11118 | return ira->codegen->builtin_types.entry_invalid; |
| 11094 | } | | |
| 11095 | return elem_type; | 11119 | return elem_type; |
| 11096 | } | 11120 | } |
| 11097 | | 11121 | |
| ... | @@ -22357,7 +22381,9 @@ static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrIn | ... | @@ -22357,7 +22381,9 @@ static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrIn |
| 22357 | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); | 22381 | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); |
| 22358 | } | 22382 | } |
| 22359 | | 22383 | |
| 22360 | static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstructionSplat *instruction) { | 22384 | static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstructionSplatSrc *instruction) { |
| | 22385 | Error err; |
| | 22386 | |
| 22361 | IrInstruction *len = instruction->len->child; | 22387 | IrInstruction *len = instruction->len->child; |
| 22362 | if (type_is_invalid(len->value.type)) | 22388 | if (type_is_invalid(len->value.type)) |
| 22363 | return ira->codegen->invalid_instruction; | 22389 | return ira->codegen->invalid_instruction; |
| ... | @@ -22366,41 +22392,32 @@ static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstruction | ... | @@ -22366,41 +22392,32 @@ static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstruction |
| 22366 | if (type_is_invalid(scalar->value.type)) | 22392 | if (type_is_invalid(scalar->value.type)) |
| 22367 | return ira->codegen->invalid_instruction; | 22393 | return ira->codegen->invalid_instruction; |
| 22368 | | 22394 | |
| 22369 | uint64_t len_int; | 22395 | uint64_t len_u64; |
| 22370 | if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_int)) { | 22396 | if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) |
| 22371 | ir_add_error(ira, len, | | |
| 22372 | buf_sprintf("splat length must be comptime")); | | |
| 22373 | return ira->codegen->invalid_instruction; | 22397 | return ira->codegen->invalid_instruction; |
| 22374 | } | 22398 | uint32_t len_int = len_u64; |
| 22375 | | 22399 | |
| 22376 | if (!is_valid_vector_elem_type(scalar->value.type)) { | 22400 | if ((err = ir_validate_vector_elem_type(ira, scalar, 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; | 22401 | return ira->codegen->invalid_instruction; |
| 22381 | } | | |
| 22382 | | 22402 | |
| 22383 | ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value.type); | 22403 | ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value.type); |
| 22384 | | 22404 | |
| 22385 | if (instr_is_comptime(scalar)) { | 22405 | if (instr_is_comptime(scalar)) { |
| 22386 | IrInstruction *result = ir_const_undef(ira, scalar, return_type); | 22406 | ConstExprValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); |
| 22387 | result->value.data.x_array.data.s_none.elements = | 22407 | if (scalar_val == nullptr) |
| 22388 | allocate<ConstExprValue>(len_int); | 22408 | return ira->codegen->invalid_instruction; |
| 22389 | for (uint32_t i = 0; i < len_int; i++) { | 22409 | if (scalar_val->special == ConstValSpecialUndef) |
| 22390 | result->value.data.x_array.data.s_none.elements[i] = | 22410 | return ir_const_undef(ira, &instruction->base, return_type); |
| 22391 | scalar->value; | 22411 | |
| | 22412 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); |
| | 22413 | result->value.data.x_array.data.s_none.elements = create_const_vals(len_int); |
| | 22414 | for (uint32_t i = 0; i < len_int; i += 1) { |
| | 22415 | copy_const_val(&result->value.data.x_array.data.s_none.elements[i], scalar_val, false); |
| 22392 | } | 22416 | } |
| 22393 | result->value.type = return_type; | | |
| 22394 | result->value.special = ConstValSpecialStatic; | | |
| 22395 | return result; | 22417 | return result; |
| 22396 | } | 22418 | } |
| 22397 | | 22419 | |
| 22398 | IrInstruction *result = ir_build_splat(&ira->new_irb, | 22420 | return ir_build_splat_gen(ira, &instruction->base, return_type, scalar); |
| 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 | } | 22421 | } |
| 22405 | | 22422 | |
| 22406 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { | 22423 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { |
| ... | @@ -25857,6 +25874,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction | ... | @@ -25857,6 +25874,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25857 | case IrInstructionIdTestErrGen: | 25874 | case IrInstructionIdTestErrGen: |
| 25858 | case IrInstructionIdFrameSizeGen: | 25875 | case IrInstructionIdFrameSizeGen: |
| 25859 | case IrInstructionIdAwaitGen: | 25876 | case IrInstructionIdAwaitGen: |
| | 25877 | case IrInstructionIdSplatGen: |
| 25860 | zig_unreachable(); | 25878 | zig_unreachable(); |
| 25861 | | 25879 | |
| 25862 | case IrInstructionIdReturn: | 25880 | case IrInstructionIdReturn: |
| ... | @@ -25987,8 +26005,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction | ... | @@ -25987,8 +26005,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25987 | return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); | 26005 | return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); |
| 25988 | case IrInstructionIdShuffleVector: | 26006 | case IrInstructionIdShuffleVector: |
| 25989 | return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); | 26007 | return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); |
| 25990 | case IrInstructionIdSplat: | 26008 | case IrInstructionIdSplatSrc: |
| 25991 | return ir_analyze_instruction_splat(ira, (IrInstructionSplat *)instruction); | 26009 | return ir_analyze_instruction_splat(ira, (IrInstructionSplatSrc *)instruction); |
| 25992 | case IrInstructionIdBoolNot: | 26010 | case IrInstructionIdBoolNot: |
| 25993 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); | 26011 | return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); |
| 25994 | case IrInstructionIdMemset: | 26012 | case IrInstructionIdMemset: |
| ... | @@ -26325,7 +26343,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -26325,7 +26343,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 26325 | case IrInstructionIdIntType: | 26343 | case IrInstructionIdIntType: |
| 26326 | case IrInstructionIdVectorType: | 26344 | case IrInstructionIdVectorType: |
| 26327 | case IrInstructionIdShuffleVector: | 26345 | case IrInstructionIdShuffleVector: |
| 26328 | case IrInstructionIdSplat: | 26346 | case IrInstructionIdSplatSrc: |
| | 26347 | case IrInstructionIdSplatGen: |
| 26329 | case IrInstructionIdBoolNot: | 26348 | case IrInstructionIdBoolNot: |
| 26330 | case IrInstructionIdSliceSrc: | 26349 | case IrInstructionIdSliceSrc: |
| 26331 | case IrInstructionIdMemberCount: | 26350 | case IrInstructionIdMemberCount: |