| ... | ... | @@ -11049,6 +11049,19 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 11049 | 11049 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); |
| 11050 | 11050 | } |
| 11051 | 11051 | |
| 11052 | static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstruction *elem_type_value) { |
| 11053 | ZigType *elem_type = ir_resolve_type(ira, elem_type_value); |
| 11054 | if (type_is_invalid(elem_type)) |
| 11055 | return ira->codegen->builtin_types.entry_invalid; |
| 11056 | if (!is_valid_vector_elem_type(elem_type)) { |
| 11057 | ir_add_error(ira, elem_type_value, |
| 11058 | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", |
| 11059 | buf_ptr(&elem_type->name))); |
| 11060 | return ira->codegen->builtin_types.entry_invalid; |
| 11061 | } |
| 11062 | return elem_type; |
| 11063 | } |
| 11064 | |
| 11052 | 11065 | static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 11053 | 11066 | ZigType *ty = ir_resolve_type(ira, type_value); |
| 11054 | 11067 | if (type_is_invalid(ty)) |
| ... | ... | @@ -22096,242 +22109,212 @@ static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstr |
| 22096 | 22109 | if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) |
| 22097 | 22110 | return ira->codegen->invalid_instruction; |
| 22098 | 22111 | |
| 22099 | | ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child); |
| 22112 | ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); |
| 22100 | 22113 | if (type_is_invalid(elem_type)) |
| 22101 | 22114 | return ira->codegen->invalid_instruction; |
| 22102 | 22115 | |
| 22103 | | if (!is_valid_vector_elem_type(elem_type)) { |
| 22104 | | ir_add_error(ira, instruction->elem_type, |
| 22105 | | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", |
| 22106 | | buf_ptr(&elem_type->name))); |
| 22107 | | return ira->codegen->invalid_instruction; |
| 22108 | | } |
| 22109 | | |
| 22110 | 22116 | ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); |
| 22111 | 22117 | |
| 22112 | 22118 | return ir_const_type(ira, &instruction->base, vector_type); |
| 22113 | 22119 | } |
| 22114 | 22120 | |
| 22115 | 22121 | static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *source_instr, |
| 22116 | | ZigType *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) { |
| 22117 | | assert(source_instr && scalar_type && a && b && mask); |
| 22118 | | assert(scalar_type->id == ZigTypeIdBool || |
| 22119 | | scalar_type->id == ZigTypeIdInt || |
| 22120 | | scalar_type->id == ZigTypeIdFloat || |
| 22121 | | scalar_type->id == ZigTypeIdPointer); |
| 22122 | | |
| 22123 | | ZigType *mask_type = mask->value.type; |
| 22124 | | if (type_is_invalid(mask_type)) |
| 22122 | ZigType *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) |
| 22123 | { |
| 22124 | ir_assert(source_instr && scalar_type && a && b && mask, source_instr); |
| 22125 | ir_assert(is_valid_vector_elem_type(scalar_type), source_instr); |
| 22126 | |
| 22127 | uint32_t len_mask; |
| 22128 | if (mask->value.type->id == ZigTypeIdVector) { |
| 22129 | len_mask = mask->value.type->data.vector.len; |
| 22130 | } else if (mask->value.type->id == ZigTypeIdArray) { |
| 22131 | len_mask = mask->value.type->data.array.len; |
| 22132 | } else { |
| 22133 | ir_add_error(ira, mask, |
| 22134 | buf_sprintf("expected vector or array, found '%s'", |
| 22135 | buf_ptr(&mask->value.type->name))); |
| 22125 | 22136 | return ira->codegen->invalid_instruction; |
| 22126 | | |
| 22127 | | const char *shuffle_mask_fail_fmt = "@shuffle mask operand must be a vector of signed 32-bit integers, got '%s'"; |
| 22128 | | |
| 22129 | | if (mask_type->id == ZigTypeIdArray) { |
| 22130 | | ZigType *vector_type = get_vector_type(ira->codegen, mask_type->data.array.len, mask_type->data.array.child_type); |
| 22131 | | mask = ir_analyze_array_to_vector(ira, mask, mask, vector_type); |
| 22132 | | if (!mask) |
| 22133 | | return ira->codegen->invalid_instruction; |
| 22134 | | mask_type = vector_type; |
| 22135 | 22137 | } |
| 22138 | mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, |
| 22139 | ira->codegen->builtin_types.entry_i32)); |
| 22140 | if (type_is_invalid(mask->value.type)) |
| 22141 | return ira->codegen->invalid_instruction; |
| 22136 | 22142 | |
| 22137 | | if (mask_type->id != ZigTypeIdVector) { |
| 22138 | | ir_add_error(ira, mask, |
| 22139 | | buf_sprintf(shuffle_mask_fail_fmt, buf_ptr(&mask->value.type->name))); |
| 22143 | uint32_t len_a; |
| 22144 | if (a->value.type->id == ZigTypeIdVector) { |
| 22145 | len_a = a->value.type->data.vector.len; |
| 22146 | } else if (a->value.type->id == ZigTypeIdArray) { |
| 22147 | len_a = a->value.type->data.array.len; |
| 22148 | } else if (a->value.type->id == ZigTypeIdUndefined) { |
| 22149 | len_a = UINT32_MAX; |
| 22150 | } else { |
| 22151 | ir_add_error(ira, a, |
| 22152 | buf_sprintf("expected vector or array with element type '%s', found '%s'", |
| 22153 | buf_ptr(&scalar_type->name), |
| 22154 | buf_ptr(&a->value.type->name))); |
| 22140 | 22155 | return ira->codegen->invalid_instruction; |
| 22141 | 22156 | } |
| 22142 | 22157 | |
| 22143 | | ZigType *mask_scalar_type = mask_type->data.array.child_type; |
| 22144 | | if (mask_scalar_type->id != ZigTypeIdInt) { |
| 22145 | | ir_add_error(ira, mask, |
| 22146 | | buf_sprintf(shuffle_mask_fail_fmt, buf_ptr(&mask->value.type->name))); |
| 22158 | uint32_t len_b; |
| 22159 | if (b->value.type->id == ZigTypeIdVector) { |
| 22160 | len_b = b->value.type->data.vector.len; |
| 22161 | } else if (b->value.type->id == ZigTypeIdArray) { |
| 22162 | len_b = b->value.type->data.array.len; |
| 22163 | } else if (b->value.type->id == ZigTypeIdUndefined) { |
| 22164 | len_b = UINT32_MAX; |
| 22165 | } else { |
| 22166 | ir_add_error(ira, b, |
| 22167 | buf_sprintf("expected vector or array with element type '%s', found '%s'", |
| 22168 | buf_ptr(&scalar_type->name), |
| 22169 | buf_ptr(&b->value.type->name))); |
| 22147 | 22170 | return ira->codegen->invalid_instruction; |
| 22148 | 22171 | } |
| 22149 | 22172 | |
| 22150 | | if (mask_scalar_type->data.integral.bit_count != 32 || |
| 22151 | | mask_scalar_type->data.integral.is_signed == false) { |
| 22152 | | ir_add_error(ira, mask, |
| 22153 | | buf_sprintf(shuffle_mask_fail_fmt, buf_ptr(&mask->value.type->name))); |
| 22154 | | return ira->codegen->invalid_instruction; |
| 22173 | if (len_a == UINT32_MAX && len_b == UINT32_MAX) { |
| 22174 | return ir_const_undef(ira, a, get_vector_type(ira->codegen, len_mask, scalar_type)); |
| 22155 | 22175 | } |
| 22156 | 22176 | |
| 22157 | | uint64_t len_a, len_b, len_c = mask->value.type->data.vector.len; |
| 22158 | | if (a->value.type->id != ZigTypeIdVector) { |
| 22159 | | if (a->value.type->id != ZigTypeIdUndefined) { |
| 22160 | | ir_add_error(ira, a, |
| 22161 | | buf_sprintf("expected vector of element type '%s' got '%s'", |
| 22162 | | buf_ptr(&scalar_type->name), |
| 22163 | | buf_ptr(&a->value.type->name))); |
| 22177 | if (len_a == UINT32_MAX) { |
| 22178 | len_a = len_b; |
| 22179 | a = ir_const_undef(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); |
| 22180 | } else { |
| 22181 | a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); |
| 22182 | if (type_is_invalid(a->value.type)) |
| 22164 | 22183 | return ira->codegen->invalid_instruction; |
| 22165 | | } |
| 22184 | } |
| 22185 | |
| 22186 | if (len_b == UINT32_MAX) { |
| 22187 | len_b = len_a; |
| 22188 | b = ir_const_undef(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); |
| 22166 | 22189 | } else { |
| 22167 | | len_a = a->value.type->data.vector.len; |
| 22190 | b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); |
| 22191 | if (type_is_invalid(b->value.type)) |
| 22192 | return ira->codegen->invalid_instruction; |
| 22168 | 22193 | } |
| 22169 | 22194 | |
| 22170 | | if (b->value.type->id != ZigTypeIdVector) { |
| 22171 | | if (b->value.type->id != ZigTypeIdUndefined) { |
| 22172 | | ir_add_error(ira, b, |
| 22173 | | buf_sprintf("expected vector of element type '%s' got '%s'", |
| 22174 | | buf_ptr(&scalar_type->name), |
| 22175 | | buf_ptr(&b->value.type->name))); |
| 22195 | ConstExprValue *mask_val = ir_resolve_const(ira, mask, UndefOk); |
| 22196 | if (mask_val == nullptr) |
| 22197 | return ira->codegen->invalid_instruction; |
| 22198 | |
| 22199 | expand_undef_array(ira->codegen, mask_val); |
| 22200 | |
| 22201 | for (uint32_t i = 0; i < len_mask; i += 1) { |
| 22202 | ConstExprValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; |
| 22203 | if (mask_elem_val->special == ConstValSpecialUndef) |
| 22204 | continue; |
| 22205 | int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); |
| 22206 | uint32_t v; |
| 22207 | IrInstruction *chosen_operand; |
| 22208 | if (v_i32 >= 0) { |
| 22209 | v = (uint32_t)v_i32; |
| 22210 | chosen_operand = a; |
| 22211 | } else { |
| 22212 | v = (uint32_t)~v_i32; |
| 22213 | chosen_operand = b; |
| 22214 | } |
| 22215 | if (v >= chosen_operand->value.type->data.vector.len) { |
| 22216 | ErrorMsg *msg = ir_add_error(ira, mask, |
| 22217 | buf_sprintf("mask index '%u' has out-of-bounds selection", i)); |
| 22218 | add_error_note(ira->codegen, msg, chosen_operand->source_node, |
| 22219 | buf_sprintf("selected index '%u' out of bounds of %s", v, |
| 22220 | buf_ptr(&chosen_operand->value.type->name))); |
| 22221 | if (chosen_operand == a && v < len_a + len_b) { |
| 22222 | add_error_note(ira->codegen, msg, b->source_node, |
| 22223 | buf_create_from_str("selections from the second vector are specified with negative numbers")); |
| 22224 | } |
| 22176 | 22225 | return ira->codegen->invalid_instruction; |
| 22177 | 22226 | } |
| 22178 | | } else { |
| 22179 | | len_b = b->value.type->data.vector.len; |
| 22180 | 22227 | } |
| 22181 | 22228 | |
| 22182 | | if (a->value.type->id == ZigTypeIdUndefined && b->value.type->id == ZigTypeIdUndefined) { |
| 22183 | | return ir_const_undef(ira, a, get_vector_type(ira->codegen, len_c, scalar_type)); |
| 22184 | | } |
| 22229 | ZigType *result_type = get_vector_type(ira->codegen, len_mask, scalar_type); |
| 22230 | if (instr_is_comptime(a) && instr_is_comptime(b)) { |
| 22231 | ConstExprValue *a_val = ir_resolve_const(ira, a, UndefOk); |
| 22232 | if (a_val == nullptr) |
| 22233 | return ira->codegen->invalid_instruction; |
| 22185 | 22234 | |
| 22186 | | // undefined is a vector up to length of the other vector. |
| 22187 | | if (a->value.type->id == ZigTypeIdUndefined) { |
| 22188 | | a = ir_const_undef(ira, a, b->value.type); |
| 22189 | | len_a = b->value.type->data.vector.len; |
| 22190 | | } else if (b->value.type->id == ZigTypeIdUndefined) { |
| 22191 | | b = ir_const_undef(ira, b, a->value.type); |
| 22192 | | len_b = a->value.type->data.vector.len; |
| 22193 | | } |
| 22235 | ConstExprValue *b_val = ir_resolve_const(ira, b, UndefOk); |
| 22236 | if (b_val == nullptr) |
| 22237 | return ira->codegen->invalid_instruction; |
| 22194 | 22238 | |
| 22195 | | // FIXME I think this needs to be more sophisticated |
| 22196 | | if (a->value.type->data.vector.elem_type != scalar_type) { |
| 22197 | | ir_add_error(ira, a, |
| 22198 | | buf_sprintf("element type '%s' does not match '%s'", |
| 22199 | | buf_ptr(&a->value.type->data.vector.elem_type->name), |
| 22200 | | buf_ptr(&scalar_type->name))); |
| 22201 | | return ira->codegen->invalid_instruction; |
| 22202 | | } |
| 22203 | | if (b->value.type->data.vector.elem_type != scalar_type) { |
| 22204 | | ir_add_error(ira, b, |
| 22205 | | buf_sprintf("element type '%s' does not match '%s'", |
| 22206 | | buf_ptr(&b->value.type->data.vector.elem_type->name), |
| 22207 | | buf_ptr(&scalar_type->name))); |
| 22208 | | return ira->codegen->invalid_instruction; |
| 22239 | expand_undef_array(ira->codegen, a_val); |
| 22240 | expand_undef_array(ira->codegen, b_val); |
| 22241 | |
| 22242 | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 22243 | result->value.data.x_array.data.s_none.elements = create_const_vals(len_mask); |
| 22244 | for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { |
| 22245 | ConstExprValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; |
| 22246 | ConstExprValue *result_elem_val = &result->value.data.x_array.data.s_none.elements[i]; |
| 22247 | if (mask_elem_val->special == ConstValSpecialUndef) { |
| 22248 | result_elem_val->special = ConstValSpecialUndef; |
| 22249 | continue; |
| 22250 | } |
| 22251 | int32_t v = bigint_as_signed(&mask_elem_val->data.x_bigint); |
| 22252 | // We've already checked for and emitted compile errors for index out of bounds here. |
| 22253 | ConstExprValue *src_elem_val = (v >= 0) ? |
| 22254 | &a->value.data.x_array.data.s_none.elements[v] : |
| 22255 | &b->value.data.x_array.data.s_none.elements[~v]; |
| 22256 | copy_const_val(result_elem_val, src_elem_val, false); |
| 22257 | |
| 22258 | ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); |
| 22259 | } |
| 22260 | result->value.special = ConstValSpecialStatic; |
| 22261 | return result; |
| 22209 | 22262 | } |
| 22210 | 22263 | |
| 22211 | | if (a->value.type != b->value.type) { |
| 22212 | | assert(len_a != len_b); |
| 22213 | | uint32_t len_max = max(len_a, len_b), len_min = min(len_a, len_b); |
| 22214 | | bool expand_b = len_b < len_a; |
| 22264 | // All static analysis passed, and not comptime. |
| 22265 | // For runtime codegen, vectors a and b must be the same length. Here we |
| 22266 | // recursively @shuffle the smaller vector to append undefined elements |
| 22267 | // to it up to the length of the longer vector. This recursion terminates |
| 22268 | // in 1 call because these calls to ir_analyze_shuffle_vector guarantee |
| 22269 | // len_a == len_b. |
| 22270 | if (len_a != len_b) { |
| 22271 | uint32_t len_min = min(len_a, len_b); |
| 22272 | uint32_t len_max = max(len_a, len_b); |
| 22273 | |
| 22215 | 22274 | IrInstruction *expand_mask = ir_const(ira, mask, |
| 22216 | 22275 | get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); |
| 22217 | 22276 | expand_mask->value.data.x_array.data.s_none.elements = create_const_vals(len_max); |
| 22218 | 22277 | uint32_t i = 0; |
| 22219 | | for (; i < len_min; i++) |
| 22278 | for (; i < len_min; i += 1) |
| 22220 | 22279 | bigint_init_unsigned(&expand_mask->value.data.x_array.data.s_none.elements[i].data.x_bigint, i); |
| 22221 | | for (; i < len_max; i++) |
| 22280 | for (; i < len_max; i += 1) |
| 22222 | 22281 | bigint_init_signed(&expand_mask->value.data.x_array.data.s_none.elements[i].data.x_bigint, -1); |
| 22282 | |
| 22223 | 22283 | IrInstruction *undef = ir_const_undef(ira, source_instr, |
| 22224 | 22284 | get_vector_type(ira->codegen, len_min, scalar_type)); |
| 22225 | | if (expand_b) { |
| 22226 | | if (instr_is_comptime(b)) { |
| 22227 | | ConstExprValue *old = b->value.data.x_array.data.s_none.elements; |
| 22228 | | b->value.data.x_array.data.s_none.elements = |
| 22229 | | allocate<ConstExprValue>(len_a); |
| 22230 | | memcpy(b->value.data.x_array.data.s_none.elements, old, |
| 22231 | | b->value.type->data.vector.len * sizeof(ConstExprValue)); |
| 22232 | | } else { |
| 22233 | | b = ir_build_shuffle_vector(&ira->new_irb, |
| 22234 | | source_instr->scope, source_instr->source_node, |
| 22235 | | nullptr, b, undef, expand_mask); |
| 22236 | | b->value.special = ConstValSpecialRuntime; |
| 22237 | | } |
| 22238 | | b->value.type = get_vector_type(ira->codegen, len_max, scalar_type); |
| 22239 | | } else { |
| 22240 | | if (instr_is_comptime(a)) { |
| 22241 | | ConstExprValue *old = a->value.data.x_array.data.s_none.elements; |
| 22242 | | a->value.data.x_array.data.s_none.elements = |
| 22243 | | allocate<ConstExprValue>(len_b); |
| 22244 | | memcpy(a->value.data.x_array.data.s_none.elements, old, |
| 22245 | | a->value.type->data.vector.len * sizeof(ConstExprValue)); |
| 22246 | | } else { |
| 22247 | | a = ir_build_shuffle_vector(&ira->new_irb, |
| 22248 | | source_instr->scope, source_instr->source_node, |
| 22249 | | nullptr, a, undef, expand_mask); |
| 22250 | | a->value.special = ConstValSpecialRuntime; |
| 22251 | | } |
| 22252 | | a->value.type = get_vector_type(ira->codegen, len_max, scalar_type); |
| 22253 | | } |
| 22254 | | } |
| 22255 | | ConstExprValue *mask_val = ir_resolve_const(ira, mask, UndefOk); |
| 22256 | | if (!mask_val) { |
| 22257 | | ir_add_error(ira, mask, |
| 22258 | | buf_sprintf("mask must be comptime")); |
| 22259 | | return ira->codegen->invalid_instruction; |
| 22260 | | } |
| 22261 | | for (uint32_t i = 0;i < mask->value.type->data.vector.len;i++) { |
| 22262 | | if (mask->value.data.x_array.data.s_none.elements[i].special == ConstValSpecialUndef) |
| 22263 | | continue; |
| 22264 | | int64_t v = bigint_as_signed(&mask->value.data.x_array.data.s_none.elements[i].data.x_bigint); |
| 22265 | | if (v >= 0 && (uint64_t)v + 1 > len_a) { |
| 22266 | | ErrorMsg *msg = ir_add_error(ira, mask, |
| 22267 | | buf_sprintf("mask index out of bounds")); |
| 22268 | | add_error_note(ira->codegen, msg, mask->source_node, |
| 22269 | | buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, (uintptr_t)i)); |
| 22270 | | if ((uint64_t)v <= len_a + len_b) |
| 22271 | | add_error_note(ira->codegen, msg, mask->source_node, |
| 22272 | | buf_sprintf("selections from the second vector are specified with negative numbers")); |
| 22273 | | } else if (v < 0 && (uint64_t)~v + 1 > len_b) { |
| 22274 | | ErrorMsg *msg = ir_add_error(ira, mask, |
| 22275 | | buf_sprintf("mask index out of bounds")); |
| 22276 | | add_error_note(ira->codegen, msg, mask->source_node, |
| 22277 | | buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, (uintptr_t)i)); |
| 22278 | | } |
| 22279 | | else |
| 22280 | | continue; |
| 22281 | | return ira->codegen->invalid_instruction; |
| 22282 | | } |
| 22283 | 22285 | |
| 22284 | | ZigType *result_type = get_vector_type(ira->codegen, len_c, scalar_type); |
| 22285 | | if (instr_is_comptime(a) && |
| 22286 | | instr_is_comptime(b)) { |
| 22287 | | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 22288 | | result->value.data.x_array.data.s_none.elements = create_const_vals(len_c); |
| 22289 | | for (uint32_t i = 0;i < mask->value.type->data.vector.len;i++) { |
| 22290 | | if (mask->value.data.x_array.data.s_none.elements[i].special == ConstValSpecialUndef) |
| 22291 | | result->value.data.x_array.data.s_none.elements[i].special = |
| 22292 | | ConstValSpecialUndef; |
| 22293 | | int64_t v = bigint_as_signed(&mask->value.data.x_array.data.s_none.elements[i].data.x_bigint); |
| 22294 | | if (v >= 0) |
| 22295 | | result->value.data.x_array.data.s_none.elements[i] = |
| 22296 | | a->value.data.x_array.data.s_none.elements[v]; |
| 22297 | | else if (v < 0) |
| 22298 | | result->value.data.x_array.data.s_none.elements[i] = |
| 22299 | | b->value.data.x_array.data.s_none.elements[~v]; |
| 22300 | | else |
| 22301 | | zig_unreachable(); |
| 22302 | | result->value.data.x_array.data.s_none.elements[i].special = |
| 22303 | | ConstValSpecialStatic; |
| 22286 | if (len_b < len_a) { |
| 22287 | b = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, b, undef, expand_mask); |
| 22288 | } else { |
| 22289 | a = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, a, undef, expand_mask); |
| 22304 | 22290 | } |
| 22305 | | result->value.special = ConstValSpecialStatic; |
| 22306 | | return result; |
| 22307 | 22291 | } |
| 22308 | 22292 | |
| 22309 | | // All static analysis passed, and not comptime |
| 22310 | 22293 | IrInstruction *result = ir_build_shuffle_vector(&ira->new_irb, |
| 22311 | 22294 | source_instr->scope, source_instr->source_node, |
| 22312 | 22295 | nullptr, a, b, mask); |
| 22313 | 22296 | result->value.type = result_type; |
| 22314 | | result->value.special = ConstValSpecialRuntime; |
| 22315 | 22297 | return result; |
| 22316 | 22298 | } |
| 22317 | 22299 | |
| 22318 | 22300 | static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstructionShuffleVector *instruction) { |
| 22319 | | ZigType *scalar_type = ir_resolve_type(ira, instruction->scalar_type); |
| 22320 | | assert(scalar_type); |
| 22301 | ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type); |
| 22321 | 22302 | if (type_is_invalid(scalar_type)) |
| 22322 | 22303 | return ira->codegen->invalid_instruction; |
| 22323 | 22304 | |
| 22324 | | if (scalar_type->id != ZigTypeIdBool && |
| 22325 | | scalar_type->id != ZigTypeIdInt && |
| 22326 | | scalar_type->id != ZigTypeIdFloat && |
| 22327 | | scalar_type->id != ZigTypeIdPointer) { |
| 22328 | | ir_add_error(ira, instruction->scalar_type, |
| 22329 | | buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", |
| 22330 | | buf_ptr(&scalar_type->name))); |
| 22305 | IrInstruction *a = instruction->a->child; |
| 22306 | if (type_is_invalid(a->value.type)) |
| 22307 | return ira->codegen->invalid_instruction; |
| 22308 | |
| 22309 | IrInstruction *b = instruction->b->child; |
| 22310 | if (type_is_invalid(b->value.type)) |
| 22311 | return ira->codegen->invalid_instruction; |
| 22312 | |
| 22313 | IrInstruction *mask = instruction->mask->child; |
| 22314 | if (type_is_invalid(mask->value.type)) |
| 22331 | 22315 | return ira->codegen->invalid_instruction; |
| 22332 | | } |
| 22333 | 22316 | |
| 22334 | | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, instruction->a->child, instruction->b->child, instruction->mask->child); |
| 22317 | return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); |
| 22335 | 22318 | } |
| 22336 | 22319 | |
| 22337 | 22320 | static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { |