aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-07-01 15:52:54 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-07-01 15:52:54 -0700
commitc89dd15e1be4959800dc7092d7dd4375253db7bc (patch)
treeca184ae53592efa21e67128a5f891d642d7f1118 /src/stage1/ir.cpp
parent5466e87fce581f2ef90ac23bb80b1dbc05836fc6 (diff)
parent2360f8c490f3ec684ed64ff28e8c1fade249070b (diff)
downloadzig-c89dd15e1be4959800dc7092d7dd4375253db7bc.tar.gz
zig-c89dd15e1be4959800dc7092d7dd4375253db7bc.zip
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'src/stage1/ir.cpp')
-rw-r--r--src/stage1/ir.cpp266
1 files changed, 224 insertions, 42 deletions
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp
index 5694db22ee..52044e9dce 100644
--- a/src/stage1/ir.cpp
+++ b/src/stage1/ir.cpp
@@ -3338,6 +3338,32 @@ static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
}
}
+// c = a - b * trunc(a / b)
+static float16_t zig_f16_rem(float16_t a, float16_t b) {
+ float16_t c;
+ c = f16_div(a, b);
+ c = f16_roundToInt(c, softfloat_round_minMag, false);
+ c = f16_mul(b, c);
+ c = f16_sub(a, c);
+ return c;
+}
+
+// c = a - b * trunc(a / b)
+static void zig_f128M_rem(const float128_t* a, const float128_t* b, float128_t* c) {
+ f128M_div(a, b, c);
+ f128M_roundToInt(c, softfloat_round_minMag, false, c);
+ f128M_mul(b, c, c);
+ f128M_sub(a, c, c);
+}
+
+// c = a - b * trunc(a / b)
+static void zig_extF80M_rem(const extFloat80_t* a, const extFloat80_t* b, extFloat80_t* c) {
+ extF80M_div(a, b, c);
+ extF80M_roundToInt(c, softfloat_round_minMag, false, c);
+ extF80M_mul(b, c, c);
+ extF80M_sub(a, c, c);
+}
+
static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
assert(op1->type == op2->type);
out_val->type = op1->type;
@@ -3346,7 +3372,7 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
} else if (op1->type->id == ZigTypeIdFloat) {
switch (op1->type->data.floating.bit_count) {
case 16:
- out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16);
+ out_val->data.x_f16 = zig_f16_rem(op1->data.x_f16, op2->data.x_f16);
return;
case 32:
out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32);
@@ -3355,10 +3381,10 @@ static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) {
out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64);
return;
case 80:
- extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
+ zig_extF80M_rem(&op1->data.x_f80, &op2->data.x_f80, &out_val->data.x_f80);
return;
case 128:
- f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
+ zig_f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128);
return;
default:
zig_unreachable();
@@ -4454,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
+ if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) {
+ if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) {
+ return result;
+ }
+ }
+
if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) {
if (actual_type->data.vector.len != wanted_type->data.vector.len) {
result.id = ConstCastResultIdVectorLength;
@@ -7817,7 +7849,7 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
|| !actual_type->data.pointer.is_const);
- if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
+ if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
array_type->data.array.child_type, source_node,
!slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&
(slice_ptr_type->data.pointer.sentinel == nullptr ||
@@ -7825,6 +7857,14 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
const_values_equal(ira->codegen, array_type->data.array.sentinel,
slice_ptr_type->data.pointer.sentinel))))
{
+ if (!const_ok) {
+ ErrorMsg *msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
+ buf_ptr(&wanted_type->name)));
+ add_error_note(ira->codegen, msg, source_node,
+ buf_sprintf("cast discards const qualifier"));
+ return ira->codegen->invalid_inst_gen;
+ }
// If the pointers both have ABI align, it works.
// Or if the array length is 0, alignment doesn't matter.
bool ok_align = array_type->data.array.len == 0 ||
@@ -8182,8 +8222,16 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
ZigType *wanted_child = wanted_type->data.pointer.child_type;
bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
- wanted_child->data.array.len == field_count && (const_ok || field_count == 0))
+ wanted_child->data.array.len == field_count)
{
+ if (!const_ok && field_count != 0) {
+ ErrorMsg *msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("cannot cast pointer to array literal to '%s'",
+ buf_ptr(&wanted_type->name)));
+ add_error_note(ira->codegen, msg, source_node,
+ buf_sprintf("cast discards const qualifier"));
+ return ira->codegen->invalid_inst_gen;
+ }
Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
@@ -8215,6 +8263,13 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr);
+ } else if (!slice_type->data.pointer.is_const && actual_type->data.pointer.is_const && field_count != 0) {
+ ErrorMsg *msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
+ buf_ptr(&wanted_type->name)));
+ add_error_note(ira->codegen, msg, source_node,
+ buf_sprintf("cast discards const qualifier"));
+ return ira->codegen->invalid_inst_gen;
}
}
}
@@ -8242,6 +8297,34 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type);
}
+ // E!T to T
+ if (actual_type->id == ZigTypeIdErrorUnion) {
+ if (types_match_const_cast_only(ira, actual_type->data.error_union.payload_type, wanted_type,
+ source_node, false).id == ConstCastResultIdOk)
+ {
+ ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type '%s', found '%s'",
+ buf_ptr(&wanted_type->name),
+ buf_ptr(&actual_type->name)));
+ report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
+ return ira->codegen->invalid_inst_gen;
+ }
+ }
+
+ //?T to T
+ if (actual_type->id == ZigTypeIdOptional) {
+ if (types_match_const_cast_only(ira, actual_type->data.maybe.child_type, wanted_type,
+ source_node, false).id == ConstCastResultIdOk)
+ {
+ ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '%s', found '%s'",
+ buf_ptr(&wanted_type->name),
+ buf_ptr(&actual_type->name)));
+ report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
+ return ira->codegen->invalid_inst_gen;
+ }
+ }
+
ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
buf_sprintf("expected type '%s', found '%s'",
buf_ptr(&wanted_type->name),
@@ -11666,6 +11749,8 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
case CallingConventionAAPCS:
case CallingConventionAAPCSVFP:
case CallingConventionSysV:
+ case CallingConventionWin64:
+ case CallingConventionPtxKernel:
add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
fn_entry->section_name = section_name;
break;
@@ -15013,7 +15098,7 @@ static Stage1AirInst *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, Stage1ZirI
return ira->codegen->invalid_inst_gen;
if (actual_array_type->id != ZigTypeIdArray) {
ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
- buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",
+ buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
buf_ptr(&actual_array_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -15406,12 +15491,22 @@ static Stage1AirInst *ir_analyze_struct_field_ptr(IrAnalyze *ira, Scope *scope,
assert(struct_ptr->value->type->id == ZigTypeIdPointer);
uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host;
uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes;
+ if (ptr_host_int_bytes > 0) {
+ ptr_bit_offset += field->offset * 8;
+ }
uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
is_const, is_volatile, PtrLenSingle, field->align,
(uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
(uint32_t)host_int_bytes_for_result_type, false);
+
+ if (field == struct_type->data.structure.misaligned_field) {
+ // If field is the last single misaligned field it will be represented as array
+ // of bytes in LLVM but get_pointer_to_type_extra will set its host_int_bytes to 0.
+ // We need it not to be 0 so later stage would generate proper bit casting code.
+ ptr_type->data.pointer.host_int_bytes = host_int_bytes_for_result_type;
+ }
}
if (instr_is_comptime(struct_ptr)) {
ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
@@ -17418,7 +17513,7 @@ static Stage1AirInst *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
if (is_slice(container_type)) {
ir_add_error_node(ira, instruction->init_array_type_source_node,
- buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",
+ buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
buf_ptr(&container_type->name)));
return ira->codegen->invalid_inst_gen;
}
@@ -17893,7 +17988,7 @@ static void ensure_field_index(ZigType *type, const char *field_name, size_t ind
static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) {
Error err;
- ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo");
+ ZigType *type_info_type = get_builtin_type(ira->codegen, "Type");
assert(type_info_type->id == ZigTypeIdUnion);
if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) {
zig_unreachable();
@@ -18325,7 +18420,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
fields[1]->special = ConstValSpecialStatic;
fields[1]->type = g->builtin_types.entry_type;
fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type;
- // fields: []TypeInfo.EnumField
+ // fields: []Type.EnumField
ensure_field_index(result->type, "fields", 2);
ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);
@@ -18351,7 +18446,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
enum_field_val->parent.data.p_array.array_val = enum_field_array;
enum_field_val->parent.data.p_array.elem_index = enum_field_index;
}
- // decls: []TypeInfo.Declaration
+ // decls: []Type.Declaration
ensure_field_index(result->type, "decls", 3);
if ((err = ir_make_type_info_decls(ira, source_node, fields[3],
type_entry->data.enumeration.decls_scope, false)))
@@ -18475,7 +18570,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
} else {
fields[1]->data.x_optional = nullptr;
}
- // fields: []TypeInfo.UnionField
+ // fields: []Type.UnionField
ensure_field_index(result->type, "fields", 2);
ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr);
@@ -18517,7 +18612,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
union_field_val->parent.data.p_array.array_val = union_field_array;
union_field_val->parent.data.p_array.elem_index = union_field_index;
}
- // decls: []TypeInfo.Declaration
+ // decls: []Type.Declaration
ensure_field_index(result->type, "decls", 3);
if ((err = ir_make_type_info_decls(ira, source_node, fields[3],
type_entry->data.unionation.decls_scope, false)))
@@ -18551,7 +18646,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
fields[0]->special = ConstValSpecialStatic;
fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout);
- // fields: []TypeInfo.StructField
+ // fields: []Type.StructField
ensure_field_index(result->type, "fields", 1);
ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr);
@@ -18612,7 +18707,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
struct_field_val->parent.data.p_array.array_val = struct_field_array;
struct_field_val->parent.data.p_array.elem_index = struct_field_index;
}
- // decls: []TypeInfo.Declaration
+ // decls: []Type.Declaration
ensure_field_index(result->type, "decls", 2);
if ((err = ir_make_type_info_decls(ira, source_node, fields[2],
type_entry->data.structure.decls_scope, false)))
@@ -18637,7 +18732,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
ZigValue **fields = alloc_const_vals_ptrs(g, 7);
result->data.x_struct.fields = fields;
- // calling_convention: TypeInfo.CallingConvention
+ // calling_convention: Type.CallingConvention
ensure_field_index(result->type, "calling_convention", 0);
fields[0]->special = ConstValSpecialStatic;
fields[0]->type = get_builtin_type(g, "CallingConvention");
@@ -18672,8 +18767,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
fields[4]->data.x_optional = return_type;
}
- // args: []TypeInfo.FnArg
- ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);
+ // args: []Type.Fn.Param
+ ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "Param", result->type);
if ((err = type_resolve(g, type_info_fn_arg_type, ResolveStatusSizeKnown))) {
zig_unreachable();
}
@@ -18743,7 +18838,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
ZigValue **fields = alloc_const_vals_ptrs(g, 1);
result->data.x_struct.fields = fields;
- // decls: []TypeInfo.Declaration
+ // decls: []Type.Declaration
ensure_field_index(result->type, "decls", 0);
if ((err = ir_make_type_info_decls(ira, source_node, fields[0],
type_entry->data.opaque.decls_scope, false)))
@@ -19116,7 +19211,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
if (decls_len != 0) {
- ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type"));
+ ir_add_error_node(ira, source_node, buf_create_from_str("Type.Struct.decls must be empty for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19233,7 +19328,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
if (decls_len != 0) {
- ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Struct.decls must be empty for @Type"));
+ ir_add_error_node(ira, source_node, buf_create_from_str("Type.Struct.decls must be empty for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19317,7 +19412,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
return ira->codegen->invalid_inst_gen->value->type;
if (tag_type->id != ZigTypeIdInt) {
ir_add_error_node(ira, source_node, buf_sprintf(
- "TypeInfo.Enum.tag_type must be an integer type, not '%s'", buf_ptr(&tag_type->name)));
+ "Type.Enum.tag_type must be an integer type, not '%s'", buf_ptr(&tag_type->name)));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19340,7 +19435,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
if (decls_len != 0) {
- ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Enum.decls must be empty for @Type"));
+ ir_add_error_node(ira, source_node, buf_create_from_str("Type.Enum.decls must be empty for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19427,7 +19522,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigValue *decls_len_value = decls_value->data.x_struct.fields[slice_len_index];
size_t decls_len = bigint_as_usize(&decls_len_value->data.x_bigint);
if (decls_len != 0) {
- ir_add_error_node(ira, source_node, buf_create_from_str("TypeInfo.Union.decls must be empty for @Type"));
+ ir_add_error_node(ira, source_node, buf_create_from_str("Type.Union.decls must be empty for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19493,7 +19588,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 2, &is_generic)))
return ira->codegen->invalid_inst_gen->value->type;
if (is_generic) {
- ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type"));
+ ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.is_generic must be false for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19507,7 +19602,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 4);
if (return_type == nullptr) {
- ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type"));
+ ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.return_type must be non-null for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
@@ -19536,14 +19631,13 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
assert(args_arr->data.x_array.special == ConstArraySpecialNone);
for (size_t i = 0; i < args_len; i++) {
ZigValue *arg_value = &args_arr->data.x_array.data.s_none.elements[i];
- assert(arg_value->type == ir_type_info_get_type(ira, "FnArg", nullptr));
FnTypeParamInfo *info = &fn_type_id.param_info[i];
Error err;
bool is_generic;
if ((err = get_const_field_bool(ira, source_node, arg_value, "is_generic", 0, &is_generic)))
return ira->codegen->invalid_inst_gen->value->type;
if (is_generic) {
- ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.FnArg.is_generic must be false for @Type"));
+ ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.Param.is_generic must be false for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
if ((err = get_const_field_bool(ira, source_node, arg_value, "is_noalias", 1, &info->is_noalias)))
@@ -19551,7 +19645,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
ZigType *type = get_const_field_meta_type_optional(
ira, source_node, arg_value, "arg_type", 2);
if (type == nullptr) {
- ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.FnArg.arg_type must be non-null for @Type"));
+ ir_add_error_node(ira, source_node, buf_sprintf("Type.Fn.Param.arg_type must be non-null for @Type"));
return ira->codegen->invalid_inst_gen->value->type;
}
info->type = type;
@@ -22975,6 +23069,12 @@ static Stage1AirInst *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, Stage1ZirI
if (type_is_invalid(src_type))
return ira->codegen->invalid_inst_gen;
+ // This logic is not quite right; this is just to get stage1 to accept valid code
+ // we use in the self-hosted compiler.
+ if (is_slice(dest_type) && is_slice(src_type)) {
+ return ir_analyze_bit_cast(ira, instruction->base.scope, instruction->base.source_node, ptr, dest_type);
+ }
+
bool keep_bigger_alignment = true;
return ir_analyze_ptr_cast(ira, instruction->base.scope, instruction->base.source_node, ptr,
instruction->ptr->source_node, dest_type, dest_type_value->source_node,
@@ -24039,6 +24139,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
case BuiltinFnIdCos:
out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16)));
break;
+ case BuiltinFnIdTan:
+ out_val->data.x_f16 = zig_double_to_f16(tan(zig_f16_to_double(op->data.x_f16)));
+ break;
case BuiltinFnIdExp:
out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16)));
break;
@@ -24088,6 +24191,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
case BuiltinFnIdCos:
out_val->data.x_f32 = cosf(op->data.x_f32);
break;
+ case BuiltinFnIdTan:
+ out_val->data.x_f32 = tanf(op->data.x_f32);
+ break;
case BuiltinFnIdExp:
out_val->data.x_f32 = expf(op->data.x_f32);
break;
@@ -24137,6 +24243,9 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
case BuiltinFnIdCos:
out_val->data.x_f64 = cos(op->data.x_f64);
break;
+ case BuiltinFnIdTan:
+ out_val->data.x_f64 = tan(op->data.x_f64);
+ break;
case BuiltinFnIdExp:
out_val->data.x_f64 = exp(op->data.x_f64);
break;
@@ -24200,6 +24309,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
case BuiltinFnIdNearbyInt:
case BuiltinFnIdSin:
case BuiltinFnIdCos:
+ case BuiltinFnIdTan:
case BuiltinFnIdExp:
case BuiltinFnIdExp2:
case BuiltinFnIdLog:
@@ -24207,7 +24317,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
case BuiltinFnIdLog2:
return ir_add_error_node(ira, source_node,
buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
- float_op_to_name(fop), buf_ptr(&float_type->name)));
+ float_un_op_to_name(fop), buf_ptr(&float_type->name)));
default:
zig_unreachable();
}
@@ -24234,24 +24344,94 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
break;
case BuiltinFnIdCeil:
f128M_roundToInt(in, softfloat_round_max, false, out);
- break;
+ break;
case BuiltinFnIdTrunc:
f128M_trunc(in, out);
break;
case BuiltinFnIdRound:
f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
break;
- case BuiltinFnIdNearbyInt:
- case BuiltinFnIdSin:
- case BuiltinFnIdCos:
- case BuiltinFnIdExp:
- case BuiltinFnIdExp2:
- case BuiltinFnIdLog:
- case BuiltinFnIdLog10:
- case BuiltinFnIdLog2:
- return ir_add_error_node(ira, source_node,
- buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
- float_op_to_name(fop), buf_ptr(&float_type->name)));
+ case BuiltinFnIdNearbyInt: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = nearbyint(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdSin: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = sin(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdCos: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = cos(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdTan: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = tan(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdExp: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = exp(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdExp2: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = exp2(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdLog: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = log(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdLog10: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = log10(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
+ case BuiltinFnIdLog2: {
+ float64_t f64_value = f128M_to_f64(in);
+ double double_value;
+ memcpy(&double_value, &f64_value, sizeof(double));
+ double_value = log2(double_value);
+ memcpy(&f64_value, &double_value, sizeof(double));
+ f64_to_f128M(f64_value, out);
+ break;
+ }
default:
zig_unreachable();
}
@@ -24601,7 +24781,9 @@ static Stage1AirInst *ir_analyze_instruction_end_expr(IrAnalyze *ira, Stage1ZirI
if (type_is_invalid(store_ptr->value->type)) {
if (instruction->result_loc->id == ResultLocIdReturn &&
(value->value->type->id == ZigTypeIdErrorUnion || value->value->type->id == ZigTypeIdErrorSet) &&
- ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet)
+ ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet &&
+ // Only add error note if we have a node to attach it to
+ ira->explicit_return_type_source_node)
{
add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg,
ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error"));