authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 19:11:34-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 19:11:34-04:00
log9a324ecb42f69791d49bc8e62e935aec75b5e920
treefca70ea0a58b6795c775f414e0f3b778c1be7d06
parent65f6ea66f4a86c45004547bb5ac079b8286f980e
signature Commit is signed but in an unrecognized format.

result loc semantics for loading packed struct pointer to packed struct

```zig export fn entry() void { var x = foo(); var ptr = &x.b; var y = ptr.*; } const Foo = packed struct { a: u24 = 1, b: Bar = Bar{}, }; const Bar = packed struct { a: u4 = 2, b: u4 = 3, }; ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %x = alloca %Foo, align 1 %ptr = alloca i32*, align 8 %y = alloca %Bar, align 1 call fastcc void @foo(%Foo* sret %x), !dbg !55 call void @llvm.dbg.declare(metadata %Foo* %x, metadata !39, metadata !DIExpression()), !dbg !56 %0 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0, !dbg !57 store i32* %0, i32** %ptr, align 8, !dbg !57 call void @llvm.dbg.declare(metadata i32** %ptr, metadata !51, metadata !DIExpression()), !dbg !58 %1 = load i32*, i32** %ptr, align 8, !dbg !59 %2 = load i32, i32* %1, align 1, !dbg !60 %3 = lshr i32 %2, 24, !dbg !60 %4 = trunc i32 %3 to i8, !dbg !60 %5 = bitcast %Bar* %y to i8*, !dbg !60 store i8 %4, i8* %5, !dbg !60 call void @llvm.dbg.declare(metadata %Bar* %y, metadata !54, metadata !DIExpression()), !dbg !61 ret void, !dbg !62 } ```

4 files changed, 90 insertions(+), 73 deletions(-)

src/all_types.hpp+3-2
...@@ -2449,8 +2449,9 @@ struct IrInstructionUnOp {...@@ -2449,8 +2449,9 @@ struct IrInstructionUnOp {
2449 IrInstruction base;2449 IrInstruction base;
24502450
2451 IrUnOp op_id;2451 IrUnOp op_id;
2452 IrInstruction *value;
2453 LVal lval;2452 LVal lval;
2453 IrInstruction *value;
2454 ResultLoc *result_loc;
2454};2455};
24552456
2456enum IrBinOp {2457enum IrBinOp {
...@@ -2507,7 +2508,7 @@ struct IrInstructionLoadPtrGen {...@@ -2507,7 +2508,7 @@ struct IrInstructionLoadPtrGen {
2507 IrInstruction base;2508 IrInstruction base;
25082509
2509 IrInstruction *ptr;2510 IrInstruction *ptr;
2510 LLVMValueRef tmp_ptr;2511 IrInstruction *result_loc;
2511};2512};
25122513
2513struct IrInstructionStorePtr {2514struct IrInstructionStorePtr {
src/codegen.cpp+3-6
...@@ -3376,13 +3376,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3376,13 +3376,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
3376 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");3376 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
33773377
3378 if (handle_is_ptr(child_type)) {3378 if (handle_is_ptr(child_type)) {
3379 assert(instruction->tmp_ptr != nullptr);3379 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3380 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);3380 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
3381 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");3381 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
3382 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,3382 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, result_loc,
3383 LLVMPointerType(same_size_int, 0), "");3383 LLVMPointerType(same_size_int, 0), "");
3384 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);3384 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);
3385 return instruction->tmp_ptr;3385 return result_loc;
3386 }3386 }
33873387
3388 if (child_type->id == ZigTypeIdFloat) {3388 if (child_type->id == ZigTypeIdFloat) {
...@@ -6838,9 +6838,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6838,9 +6838,6 @@ static void do_code_gen(CodeGen *g) {
6838 slot = &ref_instruction->tmp_ptr;6838 slot = &ref_instruction->tmp_ptr;
6839 assert(instruction->value.type->id == ZigTypeIdPointer);6839 assert(instruction->value.type->id == ZigTypeIdPointer);
6840 slot_type = instruction->value.type->data.pointer.child_type;6840 slot_type = instruction->value.type->data.pointer.child_type;
6841 } else if (instruction->id == IrInstructionIdLoadPtrGen) {
6842 IrInstructionLoadPtrGen *load_ptr_inst = (IrInstructionLoadPtrGen *)instruction;
6843 slot = &load_ptr_inst->tmp_ptr;
6844 } else if (instruction->id == IrInstructionIdVectorToArray) {6841 } else if (instruction->id == IrInstructionIdVectorToArray) {
6845 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;6842 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
6846 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);6843 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
src/ir.cpp+81-64
...@@ -161,7 +161,8 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);...@@ -161,7 +161,8 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
161static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,161static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
162 ResultLoc *result_loc);162 ResultLoc *result_loc);
163static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);163static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);
164static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr);164static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
165 ResultLoc *result_loc);
165static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);166static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
166static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,167static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
167 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing);168 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing);
...@@ -1467,12 +1468,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s...@@ -1467,12 +1468,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s
1467}1468}
14681469
1469static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,1470static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
1470 IrInstruction *value, LVal lval)1471 IrInstruction *value, LVal lval, ResultLoc *result_loc)
1471{1472{
1472 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);1473 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);
1473 instruction->op_id = op_id;1474 instruction->op_id = op_id;
1474 instruction->value = value;1475 instruction->value = value;
1475 instruction->lval = lval;1476 instruction->lval = lval;
1477 instruction->result_loc = result_loc;
14761478
1477 ir_ref_instruction(value, irb->current_basic_block);1479 ir_ref_instruction(value, irb->current_basic_block);
14781480
...@@ -1482,7 +1484,7 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode...@@ -1482,7 +1484,7 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode
1482static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,1484static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
1483 IrInstruction *value)1485 IrInstruction *value)
1484{1486{
1485 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone);1487 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);
1486}1488}
14871489
1488static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,1490static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
...@@ -2471,14 +2473,16 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc...@@ -2471,14 +2473,16 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc
2471}2473}
24722474
2473static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction,2475static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction,
2474 IrInstruction *ptr, ZigType *ty)2476 IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc)
2475{2477{
2476 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>(2478 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>(
2477 &ira->new_irb, source_instruction->scope, source_instruction->source_node);2479 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2478 instruction->base.value.type = ty;2480 instruction->base.value.type = ty;
2479 instruction->ptr = ptr;2481 instruction->ptr = ptr;
2482 instruction->result_loc = result_loc;
24802483
2481 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);2484 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2485 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
24822486
2483 return &instruction->base;2487 return &instruction->base;
2484}2488}
...@@ -8028,7 +8032,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -8028,7 +8032,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
8028 // We essentially just converted any lvalue from &(x.*) to (&x).*;8032 // We essentially just converted any lvalue from &(x.*) to (&x).*;
8029 // this inhibits checking that x is a pointer later, so we directly8033 // this inhibits checking that x is a pointer later, so we directly
8030 // record whether the pointer check is needed8034 // record whether the pointer check is needed
8031 return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval);8035 IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc);
8036 return ir_expr_wrap(irb, scope, un_op, result_loc);
8032 }8037 }
8033 case NodeTypeUnwrapOptional: {8038 case NodeTypeUnwrapOptional: {
8034 AstNode *expr_node = node->data.unwrap_optional.expr;8039 AstNode *expr_node = node->data.unwrap_optional.expr;
...@@ -11312,7 +11317,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s...@@ -11312,7 +11317,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
11312 IrInstruction *array_ptr = nullptr;11317 IrInstruction *array_ptr = nullptr;
11313 IrInstruction *array;11318 IrInstruction *array;
11314 if (array_arg->value.type->id == ZigTypeIdPointer) {11319 if (array_arg->value.type->id == ZigTypeIdPointer) {
11315 array = ir_get_deref(ira, source_instr, array_arg);11320 array = ir_get_deref(ira, source_instr, array_arg, nullptr);
11316 array_ptr = array_arg;11321 array_ptr = array_arg;
11317 } else {11322 } else {
11318 array = array_arg;11323 array = array_arg;
...@@ -12512,60 +12517,71 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig...@@ -12512,60 +12517,71 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
12512 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);12517 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
12513}12518}
1251412519
12515static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {12520static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
12521 ResultLoc *result_loc)
12522{
12516 Error err;12523 Error err;
12517 ZigType *type_entry = ptr->value.type;12524 ZigType *type_entry = ptr->value.type;
12518 if (type_is_invalid(type_entry)) {12525 if (type_is_invalid(type_entry))
12519 return ira->codegen->invalid_instruction;12526 return ira->codegen->invalid_instruction;
12520 } else if (type_entry->id == ZigTypeIdPointer) {12527
12521 ZigType *child_type = type_entry->data.pointer.child_type;12528 if (type_entry->id != ZigTypeIdPointer) {
12522 // if the child type has one possible value, the deref is comptime12529 ir_add_error_node(ira, source_instruction->source_node,
12523 switch (type_has_one_possible_value(ira->codegen, child_type)) {12530 buf_sprintf("attempt to dereference non-pointer type '%s'",
12524 case OnePossibleValueInvalid:12531 buf_ptr(&type_entry->name)));
12525 return ira->codegen->invalid_instruction;12532 return ira->codegen->invalid_instruction;
12526 case OnePossibleValueYes:12533 }
12527 return ir_const(ira, source_instruction, child_type);12534
12528 case OnePossibleValueNo:12535 ZigType *child_type = type_entry->data.pointer.child_type;
12529 break;12536 // if the child type has one possible value, the deref is comptime
12537 switch (type_has_one_possible_value(ira->codegen, child_type)) {
12538 case OnePossibleValueInvalid:
12539 return ira->codegen->invalid_instruction;
12540 case OnePossibleValueYes:
12541 return ir_const(ira, source_instruction, child_type);
12542 case OnePossibleValueNo:
12543 break;
12544 }
12545 if (instr_is_comptime(ptr)) {
12546 if (ptr->value.special == ConstValSpecialUndef) {
12547 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value"));
12548 return ira->codegen->invalid_instruction;
12530 }12549 }
12531 if (instr_is_comptime(ptr)) {12550 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||
12532 if (ptr->value.special == ConstValSpecialUndef) {12551 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
12533 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value"));12552 {
12534 return ira->codegen->invalid_instruction;12553 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
12535 }12554 if (pointee->special != ConstValSpecialRuntime) {
12536 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||12555 IrInstruction *result = ir_const(ira, source_instruction, child_type);
12537 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
12538 {
12539 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
12540 if (pointee->special != ConstValSpecialRuntime) {
12541 IrInstruction *result = ir_const(ira, source_instruction, child_type);
1254212556
12543 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value,12557 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value,
12544 &ptr->value)))12558 &ptr->value)))
12545 {12559 {
12546 return ira->codegen->invalid_instruction;12560 return ira->codegen->invalid_instruction;
12547 }
12548 result->value.type = child_type;
12549 return result;
12550 }12561 }
12562 result->value.type = child_type;
12563 return result;
12551 }12564 }
12552 }12565 }
12553 // if the instruction is a const ref instruction we can skip it12566 }
12554 if (ptr->id == IrInstructionIdRef) {12567 // if the instruction is a const ref instruction we can skip it
12555 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);12568 if (ptr->id == IrInstructionIdRef) {
12556 return ref_inst->value;12569 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);
12557 }12570 return ref_inst->value;
12558 IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type);12571 }
12559 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {12572
12560 ir_add_alloca(ira, result, child_type);12573 IrInstruction *result_loc_inst;
12574 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
12575 if (result_loc == nullptr) result_loc = no_result_loc();
12576 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr);
12577 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
12578 return result_loc_inst;
12561 }12579 }
12562 return result;
12563 } else {12580 } else {
12564 ir_add_error_node(ira, source_instruction->source_node,12581 result_loc_inst = nullptr;
12565 buf_sprintf("attempt to dereference non-pointer type '%s'",
12566 buf_ptr(&type_entry->name)));
12567 return ira->codegen->invalid_instruction;
12568 }12582 }
12583
12584 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
12569}12585}
1257012586
12571static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {12587static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {
...@@ -14585,7 +14601,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i...@@ -14585,7 +14601,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
14585 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;14601 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;
14586 assert(coro_allocator_var != nullptr);14602 assert(coro_allocator_var != nullptr);
14587 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);14603 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);
14588 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst);14604 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr);
14589 assert(result->value.type != nullptr);14605 assert(result->value.type != nullptr);
14590 return result;14606 return result;
14591 }14607 }
...@@ -15313,7 +15329,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15313,7 +15329,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15313 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {15329 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
15314 first_arg = first_arg_ptr;15330 first_arg = first_arg_ptr;
15315 } else {15331 } else {
15316 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);15332 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
15317 if (type_is_invalid(first_arg->value.type))15333 if (type_is_invalid(first_arg->value.type))
15318 return ira->codegen->invalid_instruction;15334 return ira->codegen->invalid_instruction;
15319 }15335 }
...@@ -15472,7 +15488,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15472,7 +15488,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15472 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {15488 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
15473 first_arg = first_arg_ptr;15489 first_arg = first_arg_ptr;
15474 } else {15490 } else {
15475 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);15491 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
15476 if (type_is_invalid(first_arg->value.type))15492 if (type_is_invalid(first_arg->value.type))
15477 return ira->codegen->invalid_instruction;15493 return ira->codegen->invalid_instruction;
15478 }15494 }
...@@ -15516,7 +15532,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15516,7 +15532,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15516 if (type_is_invalid(arg_var_ptr_inst->value.type))15532 if (type_is_invalid(arg_var_ptr_inst->value.type))
15517 return ira->codegen->invalid_instruction;15533 return ira->codegen->invalid_instruction;
1551815534
15519 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst);15535 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr);
15520 if (type_is_invalid(arg_tuple_arg->value.type))15536 if (type_is_invalid(arg_tuple_arg->value.type))
15521 return ira->codegen->invalid_instruction;15537 return ira->codegen->invalid_instruction;
1552215538
...@@ -15702,7 +15718,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15702,7 +15718,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15702 {15718 {
15703 first_arg = first_arg_ptr;15719 first_arg = first_arg_ptr;
15704 } else {15720 } else {
15705 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);15721 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
15706 if (type_is_invalid(first_arg->value.type))15722 if (type_is_invalid(first_arg->value.type))
15707 return ira->codegen->invalid_instruction;15723 return ira->codegen->invalid_instruction;
15708 }15724 }
...@@ -16113,7 +16129,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction...@@ -16113,7 +16129,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
16113 return ira->codegen->invalid_instruction;16129 return ira->codegen->invalid_instruction;
16114 }16130 }
1611516131
16116 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr);16132 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc);
16117 if (result == ira->codegen->invalid_instruction)16133 if (result == ira->codegen->invalid_instruction)
16118 return ira->codegen->invalid_instruction;16134 return ira->codegen->invalid_instruction;
1611916135
...@@ -16994,7 +17010,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16994,7 +17010,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
16994 assert(container_ptr->value.type->id == ZigTypeIdPointer);17010 assert(container_ptr->value.type->id == ZigTypeIdPointer);
16995 if (container_type->id == ZigTypeIdPointer) {17011 if (container_type->id == ZigTypeIdPointer) {
16996 ZigType *bare_type = container_ref_type(container_type);17012 ZigType *bare_type = container_ref_type(container_type);
16997 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr);17013 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr);
16998 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing);17014 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing);
16999 return result;17015 return result;
17000 } else {17016 } else {
...@@ -17339,7 +17355,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct...@@ -17339,7 +17355,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct
17339 IrInstruction *ptr = instruction->ptr->child;17355 IrInstruction *ptr = instruction->ptr->child;
17340 if (type_is_invalid(ptr->value.type))17356 if (type_is_invalid(ptr->value.type))
17341 return ira->codegen->invalid_instruction;17357 return ira->codegen->invalid_instruction;
17342 return ir_get_deref(ira, &instruction->base, ptr);17358 return ir_get_deref(ira, &instruction->base, ptr, nullptr);
17343}17359}
1734417360
17345static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) {17361static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) {
...@@ -17807,7 +17823,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr...@@ -17807,7 +17823,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
17807 }17823 }
17808 if (!safety_check_on)17824 if (!safety_check_on)
17809 return base_ptr;17825 return base_ptr;
17810 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr);17826 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr);
17811 ir_build_assert_non_null(ira, source_instr, c_ptr_val);17827 ir_build_assert_non_null(ira, source_instr, c_ptr_val);
17812 return base_ptr;17828 return base_ptr;
17813 }17829 }
...@@ -18162,7 +18178,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -18162,7 +18178,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
18162 return result;18178 return result;
18163 }18179 }
1816418180
18165 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);18181 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
18166 result->value.type = target_type;18182 result->value.type = target_type;
18167 return result;18183 return result;
18168 }18184 }
...@@ -18192,7 +18208,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -18192,7 +18208,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
18192 return result;18208 return result;
18193 }18209 }
1819418210
18195 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);18211 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
18196 union_value->value.type = target_type;18212 union_value->value.type = target_type;
1819718213
18198 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,18214 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,
...@@ -18216,7 +18232,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -18216,7 +18232,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
18216 return result;18232 return result;
18217 }18233 }
1821818234
18219 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);18235 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
18220 enum_value->value.type = target_type;18236 enum_value->value.type = target_type;
18221 return enum_value;18237 return enum_value;
18222 }18238 }
...@@ -23105,7 +23121,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,...@@ -23105,7 +23121,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
23105 if (lval == LValPtr) {23121 if (lval == LValPtr) {
23106 return var_ptr;23122 return var_ptr;
23107 } else {23123 } else {
23108 return ir_get_deref(ira, &instruction->base, var_ptr);23124 return ir_get_deref(ira, &instruction->base, var_ptr, nullptr);
23109 }23125 }
23110 }23126 }
23111 case TldIdFn: {23127 case TldIdFn: {
...@@ -23640,7 +23656,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr...@@ -23640,7 +23656,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
23640 }23656 }
2364123657
23642 if (instr_is_comptime(casted_ptr)) {23658 if (instr_is_comptime(casted_ptr)) {
23643 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr);23659 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr);
23644 ir_assert(result->value.type != nullptr, &instruction->base);23660 ir_assert(result->value.type != nullptr, &instruction->base);
23645 return result;23661 return result;
23646 }23662 }
...@@ -24474,7 +24490,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24474,7 +24490,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24474 case IrInstructionIdUnOp:24490 case IrInstructionIdUnOp:
24475 case IrInstructionIdBinOp:24491 case IrInstructionIdBinOp:
24476 case IrInstructionIdLoadPtr:24492 case IrInstructionIdLoadPtr:
24477 case IrInstructionIdLoadPtrGen:
24478 case IrInstructionIdConst:24493 case IrInstructionIdConst:
24479 case IrInstructionIdCast:24494 case IrInstructionIdCast:
24480 case IrInstructionIdContainerInitList:24495 case IrInstructionIdContainerInitList:
...@@ -24585,6 +24600,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24585,6 +24600,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24585 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;24600 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
24586 case IrInstructionIdErrWrapCode:24601 case IrInstructionIdErrWrapCode:
24587 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;24602 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
24603 case IrInstructionIdLoadPtrGen:
24604 return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr;
24588 }24605 }
24589 zig_unreachable();24606 zig_unreachable();
24590}24607}
src/ir_print.cpp+3-1
...@@ -397,8 +397,10 @@ static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {...@@ -397,8 +397,10 @@ static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
397}397}
398398
399static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {399static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {
400 fprintf(irp->f, "loadptr(");
400 ir_print_other_instruction(irp, instruction->ptr);401 ir_print_other_instruction(irp, instruction->ptr);
401 fprintf(irp->f, ".*");402 fprintf(irp->f, ")result=");
403 ir_print_other_instruction(irp, instruction->result_loc);
402}404}
403405
404static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {406static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {