| ... | @@ -4732,10 +4732,11 @@ pub const FuncGen = struct { | ... | @@ -4732,10 +4732,11 @@ pub const FuncGen = struct { |
| 4732 | var buf: Type.Payload.ElemType = undefined; | 4732 | var buf: Type.Payload.ElemType = undefined; |
| 4733 | const payload_ty = optional_ty.optionalChild(&buf); | 4733 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4734 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4734 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| | 4735 | const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; |
| 4735 | if (invert) { | 4736 | if (invert) { |
| 4736 | return self.builder.buildNot(operand, ""); | 4737 | return self.builder.buildNot(loaded, ""); |
| 4737 | } else { | 4738 | } else { |
| 4738 | return operand; | 4739 | return loaded; |
| 4739 | } | 4740 | } |
| 4740 | } | 4741 | } |
| 4741 | | 4742 | |
| ... | @@ -4784,12 +4785,16 @@ pub const FuncGen = struct { | ... | @@ -4784,12 +4785,16 @@ pub const FuncGen = struct { |
| 4784 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4785 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4785 | const operand = try self.resolveInst(ty_op.operand); | 4786 | const operand = try self.resolveInst(ty_op.operand); |
| 4786 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 4787 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| | 4788 | const result_ty = self.air.getRefType(ty_op.ty); |
| 4787 | var buf: Type.Payload.ElemType = undefined; | 4789 | var buf: Type.Payload.ElemType = undefined; |
| 4788 | const payload_ty = optional_ty.optionalChild(&buf); | 4790 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4789 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4791 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4790 | // We have a pointer to a zero-bit value and we need to return | 4792 | // We have a pointer to a zero-bit value and we need to return |
| 4791 | // a pointer to a zero-bit value. | 4793 | // a pointer to a zero-bit value. |
| 4792 | return operand; | 4794 | |
| | 4795 | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| | 4796 | const res_ptr_ty = try self.dg.llvmType(result_ty); |
| | 4797 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| 4793 | } | 4798 | } |
| 4794 | if (optional_ty.isPtrLikeOptional()) { | 4799 | if (optional_ty.isPtrLikeOptional()) { |
| 4795 | // The payload and the optional are the same value. | 4800 | // The payload and the optional are the same value. |
| ... | @@ -4807,13 +4812,17 @@ pub const FuncGen = struct { | ... | @@ -4807,13 +4812,17 @@ pub const FuncGen = struct { |
| 4807 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4812 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4808 | const operand = try self.resolveInst(ty_op.operand); | 4813 | const operand = try self.resolveInst(ty_op.operand); |
| 4809 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 4814 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| | 4815 | const result_ty = self.air.getRefType(ty_op.ty); |
| 4810 | var buf: Type.Payload.ElemType = undefined; | 4816 | var buf: Type.Payload.ElemType = undefined; |
| 4811 | const payload_ty = optional_ty.optionalChild(&buf); | 4817 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4812 | const non_null_bit = self.context.intType(1).constAllOnes(); | 4818 | const non_null_bit = self.context.intType(1).constAllOnes(); |
| 4813 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4819 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4814 | // We have a pointer to a i1. We need to set it to 1 and then return the same pointer. | 4820 | // We have a pointer to a i1. We need to set it to 1 and then return the same pointer. |
| 4815 | _ = self.builder.buildStore(non_null_bit, operand); | 4821 | _ = self.builder.buildStore(non_null_bit, operand); |
| 4816 | return operand; | 4822 | |
| | 4823 | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| | 4824 | const res_ptr_ty = try self.dg.llvmType(result_ty); |
| | 4825 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| 4817 | } | 4826 | } |
| 4818 | if (optional_ty.isPtrLikeOptional()) { | 4827 | if (optional_ty.isPtrLikeOptional()) { |
| 4819 | // The payload and the optional are the same value. | 4828 | // The payload and the optional are the same value. |
| ... | @@ -4872,7 +4881,13 @@ pub const FuncGen = struct { | ... | @@ -4872,7 +4881,13 @@ pub const FuncGen = struct { |
| 4872 | const target = self.dg.module.getTarget(); | 4881 | const target = self.dg.module.getTarget(); |
| 4873 | const offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; | 4882 | const offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 4874 | | 4883 | |
| 4875 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null; | 4884 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| | 4885 | if (!operand_is_ptr) return null; |
| | 4886 | |
| | 4887 | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| | 4888 | const res_ptr_ty = try self.dg.llvmType(result_ty); |
| | 4889 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| | 4890 | } |
| 4876 | if (operand_is_ptr or isByRef(payload_ty)) { | 4891 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4877 | return self.builder.buildStructGEP(operand, offset, ""); | 4892 | return self.builder.buildStructGEP(operand, offset, ""); |
| 4878 | } | 4893 | } |