| ... | @@ -2030,7 +2030,8 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2030,7 +2030,8 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2030 | defer trash_block.instructions.deinit(sema.gpa); | 2030 | defer trash_block.instructions.deinit(sema.gpa); |
| 2031 | | 2031 | |
| 2032 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); | 2032 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); |
| 2033 | return coerceResultPtr(sema, block, src, ptr, dummy_ptr, pointee_ty, &trash_block); | 2033 | const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value); |
| | 2034 | return coerceResultPtr(sema, block, src, ptr, dummy_ptr, dummy_operand, &trash_block); |
| 2034 | } | 2035 | } |
| 2035 | | 2036 | |
| 2036 | fn coerceResultPtr( | 2037 | fn coerceResultPtr( |
| ... | @@ -2039,13 +2040,14 @@ fn coerceResultPtr( | ... | @@ -2039,13 +2040,14 @@ fn coerceResultPtr( |
| 2039 | src: LazySrcLoc, | 2040 | src: LazySrcLoc, |
| 2040 | ptr: Air.Inst.Ref, | 2041 | ptr: Air.Inst.Ref, |
| 2041 | dummy_ptr: Air.Inst.Ref, | 2042 | dummy_ptr: Air.Inst.Ref, |
| 2042 | pointee_ty: Type, | 2043 | dummy_operand: Air.Inst.Ref, |
| 2043 | trash_block: *Block, | 2044 | trash_block: *Block, |
| 2044 | ) CompileError!Air.Inst.Ref { | 2045 | ) CompileError!Air.Inst.Ref { |
| 2045 | const target = sema.mod.getTarget(); | 2046 | const target = sema.mod.getTarget(); |
| 2046 | const addr_space = target_util.defaultAddressSpace(target, .local); | 2047 | const addr_space = target_util.defaultAddressSpace(target, .local); |
| | 2048 | const pointee_ty = sema.typeOf(dummy_operand); |
| | 2049 | const prev_trash_len = trash_block.instructions.items.len; |
| 2047 | | 2050 | |
| 2048 | const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value); | | |
| 2049 | try sema.storePtr2(trash_block, src, dummy_ptr, src, dummy_operand, src, .bitcast); | 2051 | try sema.storePtr2(trash_block, src, dummy_ptr, src, dummy_operand, src, .bitcast); |
| 2050 | | 2052 | |
| 2051 | { | 2053 | { |
| ... | @@ -2078,21 +2080,24 @@ fn coerceResultPtr( | ... | @@ -2078,21 +2080,24 @@ fn coerceResultPtr( |
| 2078 | while (true) { | 2080 | while (true) { |
| 2079 | const air_tags = sema.air_instructions.items(.tag); | 2081 | const air_tags = sema.air_instructions.items(.tag); |
| 2080 | const air_datas = sema.air_instructions.items(.data); | 2082 | const air_datas = sema.air_instructions.items(.data); |
| | 2083 | |
| | 2084 | if (trash_block.instructions.items.len == prev_trash_len) { |
| | 2085 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| | 2086 | return sema.addConstant(ptr_ty, ptr_val); |
| | 2087 | } |
| | 2088 | if (pointee_ty.eql(Type.@"null", sema.mod)) { |
| | 2089 | const opt_ty = sema.typeOf(new_ptr).childType(); |
| | 2090 | const null_inst = try sema.addConstant(opt_ty, Value.@"null"); |
| | 2091 | _ = try block.addBinOp(.store, new_ptr, null_inst); |
| | 2092 | return Air.Inst.Ref.void_value; |
| | 2093 | } |
| | 2094 | return sema.bitCast(block, ptr_ty, new_ptr, src); |
| | 2095 | } |
| | 2096 | |
| 2081 | const trash_inst = trash_block.instructions.pop(); | 2097 | const trash_inst = trash_block.instructions.pop(); |
| | 2098 | |
| 2082 | switch (air_tags[trash_inst]) { | 2099 | switch (air_tags[trash_inst]) { |
| 2083 | .bitcast => { | 2100 | .bitcast => { |
| 2084 | if (Air.indexToRef(trash_inst) == dummy_operand) { | | |
| 2085 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { | | |
| 2086 | return sema.addConstant(ptr_ty, ptr_val); | | |
| 2087 | } | | |
| 2088 | if (pointee_ty.eql(Type.@"null", sema.mod)) { | | |
| 2089 | const opt_ty = sema.typeOf(new_ptr).childType(); | | |
| 2090 | const null_inst = try sema.addConstant(opt_ty, Value.@"null"); | | |
| 2091 | _ = try block.addBinOp(.store, new_ptr, null_inst); | | |
| 2092 | return Air.Inst.Ref.void_value; | | |
| 2093 | } | | |
| 2094 | return sema.bitCast(block, ptr_ty, new_ptr, src); | | |
| 2095 | } | | |
| 2096 | const ty_op = air_datas[trash_inst].ty_op; | 2101 | const ty_op = air_datas[trash_inst].ty_op; |
| 2097 | const operand_ty = sema.typeOf(ty_op.operand); | 2102 | const operand_ty = sema.typeOf(ty_op.operand); |
| 2098 | const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{ | 2103 | const ptr_operand_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| ... | @@ -3309,8 +3314,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3309,8 +3314,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3309 | defer bitcast_block.instructions.deinit(gpa); | 3314 | defer bitcast_block.instructions.deinit(gpa); |
| 3310 | | 3315 | |
| 3311 | trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); | 3316 | trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); |
| 3312 | const pointee_ty = sema.typeOf(peer_inst_list[i]); | 3317 | const sub_ptr = try coerceResultPtr(sema, &bitcast_block, src, ptr, dummy_ptr, peer_inst_list[i], &trash_block); |
| 3313 | const sub_ptr = try coerceResultPtr(sema, &bitcast_block, src, ptr, dummy_ptr, pointee_ty, &trash_block); | | |
| 3314 | | 3318 | |
| 3315 | assert(bitcast_block.instructions.items.len > 0); | 3319 | assert(bitcast_block.instructions.items.len > 0); |
| 3316 | // If only one instruction is produced then we can replace the bitcast | 3320 | // If only one instruction is produced then we can replace the bitcast |
| ... | @@ -4190,7 +4194,7 @@ fn storeToInferredAlloc( | ... | @@ -4190,7 +4194,7 @@ fn storeToInferredAlloc( |
| 4190 | .stored_inst = operand, | 4194 | .stored_inst = operand, |
| 4191 | .placeholder = Air.refToIndex(bitcasted_ptr).?, | 4195 | .placeholder = Air.refToIndex(bitcasted_ptr).?, |
| 4192 | }); | 4196 | }); |
| 4193 | return sema.storePtr(block, src, bitcasted_ptr, operand); | 4197 | return sema.storePtr2(block, src, bitcasted_ptr, src, operand, src, .bitcast); |
| 4194 | } | 4198 | } |
| 4195 | | 4199 | |
| 4196 | fn storeToInferredAllocComptime( | 4200 | fn storeToInferredAllocComptime( |
| ... | @@ -21707,8 +21711,6 @@ fn storePtr2( | ... | @@ -21707,8 +21711,6 @@ fn storePtr2( |
| 21707 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) | 21711 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) |
| 21708 | return; | 21712 | return; |
| 21709 | | 21713 | |
| 21710 | // TODO handle if the element type requires comptime | | |
| 21711 | | | |
| 21712 | if (air_tag == .bitcast) { | 21714 | if (air_tag == .bitcast) { |
| 21713 | // `air_tag == .bitcast` is used as a special case for `zirCoerceResultPtr` | 21715 | // `air_tag == .bitcast` is used as a special case for `zirCoerceResultPtr` |
| 21714 | // to avoid calling `requireRuntimeBlock` for the dummy block. | 21716 | // to avoid calling `requireRuntimeBlock` for the dummy block. |