| ... | ... | @@ -4740,12 +4740,14 @@ pub const FuncGen = struct { |
| 4740 | 4740 | const err_set_ty = try fg.dg.lowerType(Type.anyerror); |
| 4741 | 4741 | const zero = err_set_ty.constNull(); |
| 4742 | 4742 | if (!payload_has_bits) { |
| 4743 | // TODO add alignment to this load |
| 4743 | 4744 | const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union; |
| 4744 | 4745 | break :err fg.builder.buildICmp(.NE, loaded, zero, ""); |
| 4745 | 4746 | } |
| 4746 | 4747 | const err_field_index = errUnionErrorOffset(payload_ty, target); |
| 4747 | 4748 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| 4748 | 4749 | const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, ""); |
| 4750 | // TODO add alignment to this load |
| 4749 | 4751 | const loaded = fg.builder.buildLoad(err_field_ptr, ""); |
| 4750 | 4752 | break :err fg.builder.buildICmp(.NE, loaded, zero, ""); |
| 4751 | 4753 | } |
| ... | ... | @@ -4765,13 +4767,22 @@ pub const FuncGen = struct { |
| 4765 | 4767 | if (!payload_has_bits) { |
| 4766 | 4768 | if (!operand_is_ptr) return null; |
| 4767 | 4769 | |
| 4768 | | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| 4770 | // TODO once we update to an LLVM version with opaque pointers |
| 4771 | // this bitcast won't be necessary. |
| 4769 | 4772 | const res_ptr_ty = try fg.dg.lowerType(result_ty); |
| 4770 | 4773 | return fg.builder.buildBitCast(err_union, res_ptr_ty, ""); |
| 4771 | 4774 | } |
| 4772 | 4775 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 4773 | 4776 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4774 | 4777 | return fg.builder.buildStructGEP(err_union, offset, ""); |
| 4778 | } else if (isByRef(err_union_ty)) { |
| 4779 | const payload_ptr = fg.builder.buildStructGEP(err_union, offset, ""); |
| 4780 | if (isByRef(payload_ty)) { |
| 4781 | return payload_ptr; |
| 4782 | } |
| 4783 | const load_inst = fg.builder.buildLoad(payload_ptr, ""); |
| 4784 | load_inst.setAlignment(payload_ty.abiAlignment(target)); |
| 4785 | return load_inst; |
| 4775 | 4786 | } |
| 4776 | 4787 | return fg.builder.buildExtractValue(err_union, offset, ""); |
| 4777 | 4788 | } |
| ... | ... | @@ -5795,6 +5806,8 @@ pub const FuncGen = struct { |
| 5795 | 5806 | |
| 5796 | 5807 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5797 | 5808 | const operand = try self.resolveInst(ty_op.operand); |
| 5809 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 5810 | const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5798 | 5811 | const result_ty = self.air.typeOfIndex(inst); |
| 5799 | 5812 | const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty; |
| 5800 | 5813 | const target = self.dg.module.getTarget(); |
| ... | ... | @@ -5809,6 +5822,14 @@ pub const FuncGen = struct { |
| 5809 | 5822 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 5810 | 5823 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 5811 | 5824 | return self.builder.buildStructGEP(operand, offset, ""); |
| 5825 | } else if (isByRef(err_union_ty)) { |
| 5826 | const payload_ptr = self.builder.buildStructGEP(operand, offset, ""); |
| 5827 | if (isByRef(payload_ty)) { |
| 5828 | return payload_ptr; |
| 5829 | } |
| 5830 | const load_inst = self.builder.buildLoad(payload_ptr, ""); |
| 5831 | load_inst.setAlignment(payload_ty.abiAlignment(target)); |
| 5832 | return load_inst; |
| 5812 | 5833 | } |
| 5813 | 5834 | return self.builder.buildExtractValue(operand, offset, ""); |
| 5814 | 5835 | } |
| ... | ... | @@ -9338,6 +9359,8 @@ fn ccAbiPromoteInt( |
| 9338 | 9359 | fn isByRef(ty: Type) bool { |
| 9339 | 9360 | // For tuples and structs, if there are more than this many non-void |
| 9340 | 9361 | // fields, then we make it byref, otherwise byval. |
| 9362 | // TODO we actually want to set this to 2, however it is tripping an LLVM 14 regression: |
| 9363 | // https://github.com/llvm/llvm-project/issues/56585 |
| 9341 | 9364 | const max_fields_byval = 0; |
| 9342 | 9365 | |
| 9343 | 9366 | switch (ty.zigTypeTag()) { |
| ... | ... | @@ -9392,7 +9415,17 @@ fn isByRef(ty: Type) bool { |
| 9392 | 9415 | return false; |
| 9393 | 9416 | }, |
| 9394 | 9417 | .Union => return ty.hasRuntimeBits(), |
| 9395 | | .ErrorUnion => return isByRef(ty.errorUnionPayload()), |
| 9418 | .ErrorUnion => { |
| 9419 | const payload_ty = ty.errorUnionPayload(); |
| 9420 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 9421 | return false; |
| 9422 | } |
| 9423 | return true; |
| 9424 | // TODO we actually want this logic: |
| 9425 | // however it is tripping an LLVM 14 regression: |
| 9426 | // https://github.com/llvm/llvm-project/issues/56585 |
| 9427 | //return isByRef(payload_ty); |
| 9428 | }, |
| 9396 | 9429 | .Optional => { |
| 9397 | 9430 | var buf: Type.Payload.ElemType = undefined; |
| 9398 | 9431 | const payload_ty = ty.optionalChild(&buf); |