| ... | ... | @@ -5730,12 +5730,7 @@ pub const FuncGen = struct { |
| 5730 | 5730 | // The payload and the optional are the same value. |
| 5731 | 5731 | return operand; |
| 5732 | 5732 | } |
| 5733 | | const index_type = self.context.intType(32); |
| 5734 | | const indices: [2]*const llvm.Value = .{ |
| 5735 | | index_type.constNull(), // dereference the pointer |
| 5736 | | index_type.constNull(), // first field is the payload |
| 5737 | | }; |
| 5738 | | return self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5733 | return self.builder.buildStructGEP(operand, 0, ""); |
| 5739 | 5734 | } |
| 5740 | 5735 | |
| 5741 | 5736 | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5761,24 +5756,17 @@ pub const FuncGen = struct { |
| 5761 | 5756 | // Setting to non-null will be done when the payload is set. |
| 5762 | 5757 | return operand; |
| 5763 | 5758 | } |
| 5764 | | const index_type = self.context.intType(32); |
| 5765 | | { |
| 5766 | | // First set the non-null bit. |
| 5767 | | const indices: [2]*const llvm.Value = .{ |
| 5768 | | index_type.constNull(), // dereference the pointer |
| 5769 | | index_type.constInt(1, .False), // second field is the non-null bit |
| 5770 | | }; |
| 5771 | | const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5772 | | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| 5773 | | } |
| 5759 | |
| 5760 | // First set the non-null bit. |
| 5761 | const non_null_ptr = self.builder.buildStructGEP(operand, 1, ""); |
| 5762 | // TODO set alignment on this store |
| 5763 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| 5764 | |
| 5774 | 5765 | // Then return the payload pointer (only if it's used). |
| 5775 | 5766 | if (self.liveness.isUnused(inst)) |
| 5776 | 5767 | return null; |
| 5777 | | const indices: [2]*const llvm.Value = .{ |
| 5778 | | index_type.constNull(), // dereference the pointer |
| 5779 | | index_type.constNull(), // first field is the payload |
| 5780 | | }; |
| 5781 | | return self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5768 | |
| 5769 | return self.builder.buildStructGEP(operand, 0, ""); |
| 5782 | 5770 | } |
| 5783 | 5771 | |
| 5784 | 5772 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5874,16 +5862,11 @@ pub const FuncGen = struct { |
| 5874 | 5862 | _ = self.builder.buildStore(non_error_val, operand); |
| 5875 | 5863 | return operand; |
| 5876 | 5864 | } |
| 5877 | | const index_type = self.context.intType(32); |
| 5878 | 5865 | const target = self.dg.module.getTarget(); |
| 5879 | 5866 | { |
| 5880 | 5867 | const error_offset = errUnionErrorOffset(payload_ty, target); |
| 5881 | 5868 | // First set the non-error value. |
| 5882 | | const indices: [2]*const llvm.Value = .{ |
| 5883 | | index_type.constNull(), // dereference the pointer |
| 5884 | | index_type.constInt(error_offset, .False), |
| 5885 | | }; |
| 5886 | | const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5869 | const non_null_ptr = self.builder.buildStructGEP(operand, error_offset, ""); |
| 5887 | 5870 | const store_inst = self.builder.buildStore(non_error_val, non_null_ptr); |
| 5888 | 5871 | store_inst.setAlignment(Type.anyerror.abiAlignment(target)); |
| 5889 | 5872 | } |
| ... | ... | @@ -5892,11 +5875,7 @@ pub const FuncGen = struct { |
| 5892 | 5875 | return null; |
| 5893 | 5876 | |
| 5894 | 5877 | const payload_offset = errUnionPayloadOffset(payload_ty, target); |
| 5895 | | const indices: [2]*const llvm.Value = .{ |
| 5896 | | index_type.constNull(), // dereference the pointer |
| 5897 | | index_type.constInt(payload_offset, .False), |
| 5898 | | }; |
| 5899 | | return self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 5878 | return self.builder.buildStructGEP(operand, payload_offset, ""); |
| 5900 | 5879 | } |
| 5901 | 5880 | |
| 5902 | 5881 | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -6391,8 +6370,30 @@ pub const FuncGen = struct { |
| 6391 | 6370 | const overflow_bit = self.builder.buildExtractValue(result_struct, 1, ""); |
| 6392 | 6371 | |
| 6393 | 6372 | var ty_buf: Type.Payload.Pointer = undefined; |
| 6394 | | const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, ""); |
| 6395 | | return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, ""); |
| 6373 | const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?; |
| 6374 | const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?; |
| 6375 | |
| 6376 | if (isByRef(dest_ty)) { |
| 6377 | const target = self.dg.module.getTarget(); |
| 6378 | const alloca_inst = self.buildAlloca(llvm_dest_ty); |
| 6379 | const result_alignment = dest_ty.abiAlignment(target); |
| 6380 | alloca_inst.setAlignment(result_alignment); |
| 6381 | { |
| 6382 | const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, ""); |
| 6383 | const store_inst = self.builder.buildStore(result, field_ptr); |
| 6384 | store_inst.setAlignment(result_alignment); |
| 6385 | } |
| 6386 | { |
| 6387 | const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, ""); |
| 6388 | const store_inst = self.builder.buildStore(overflow_bit, field_ptr); |
| 6389 | store_inst.setAlignment(1); |
| 6390 | } |
| 6391 | |
| 6392 | return alloca_inst; |
| 6393 | } |
| 6394 | |
| 6395 | const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, ""); |
| 6396 | return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, ""); |
| 6396 | 6397 | } |
| 6397 | 6398 | |
| 6398 | 6399 | fn buildElementwiseCall( |
| ... | ... | @@ -6721,8 +6722,30 @@ pub const FuncGen = struct { |
| 6721 | 6722 | const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, ""); |
| 6722 | 6723 | |
| 6723 | 6724 | var ty_buf: Type.Payload.Pointer = undefined; |
| 6724 | | const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, ""); |
| 6725 | | return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, ""); |
| 6725 | const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?; |
| 6726 | const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?; |
| 6727 | |
| 6728 | if (isByRef(dest_ty)) { |
| 6729 | const target = self.dg.module.getTarget(); |
| 6730 | const alloca_inst = self.buildAlloca(llvm_dest_ty); |
| 6731 | const result_alignment = dest_ty.abiAlignment(target); |
| 6732 | alloca_inst.setAlignment(result_alignment); |
| 6733 | { |
| 6734 | const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, ""); |
| 6735 | const store_inst = self.builder.buildStore(result, field_ptr); |
| 6736 | store_inst.setAlignment(result_alignment); |
| 6737 | } |
| 6738 | { |
| 6739 | const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, ""); |
| 6740 | const store_inst = self.builder.buildStore(overflow_bit, field_ptr); |
| 6741 | store_inst.setAlignment(1); |
| 6742 | } |
| 6743 | |
| 6744 | return alloca_inst; |
| 6745 | } |
| 6746 | |
| 6747 | const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, ""); |
| 6748 | return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, ""); |
| 6726 | 6749 | } |
| 6727 | 6750 | |
| 6728 | 6751 | fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -8336,17 +8359,9 @@ pub const FuncGen = struct { |
| 8336 | 8359 | fn optIsNonNull(self: *FuncGen, opt_handle: *const llvm.Value, is_by_ref: bool) *const llvm.Value { |
| 8337 | 8360 | const field = b: { |
| 8338 | 8361 | if (is_by_ref) { |
| 8339 | | const index_type = self.context.intType(32); |
| 8340 | | |
| 8341 | | const indices: [2]*const llvm.Value = .{ |
| 8342 | | index_type.constNull(), |
| 8343 | | index_type.constInt(1, .False), |
| 8344 | | }; |
| 8345 | | |
| 8346 | | const field_ptr = self.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, ""); |
| 8362 | const field_ptr = self.builder.buildStructGEP(opt_handle, 1, ""); |
| 8347 | 8363 | break :b self.builder.buildLoad(field_ptr, ""); |
| 8348 | 8364 | } |
| 8349 | | |
| 8350 | 8365 | break :b self.builder.buildExtractValue(opt_handle, 1, ""); |
| 8351 | 8366 | }; |
| 8352 | 8367 | comptime assert(optional_layout_version == 3); |
| ... | ... | @@ -8365,12 +8380,7 @@ pub const FuncGen = struct { |
| 8365 | 8380 | |
| 8366 | 8381 | if (isByRef(opt_ty)) { |
| 8367 | 8382 | // We have a pointer and we need to return a pointer to the first field. |
| 8368 | | const index_type = fg.context.intType(32); |
| 8369 | | const indices: [2]*const llvm.Value = .{ |
| 8370 | | index_type.constNull(), // dereference the pointer |
| 8371 | | index_type.constNull(), // first field is the payload |
| 8372 | | }; |
| 8373 | | const payload_ptr = fg.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, ""); |
| 8383 | const payload_ptr = fg.builder.buildStructGEP(opt_handle, 0, ""); |
| 8374 | 8384 | |
| 8375 | 8385 | if (isByRef(payload_ty)) { |
| 8376 | 8386 | return payload_ptr; |
| ... | ... | @@ -8401,22 +8411,13 @@ pub const FuncGen = struct { |
| 8401 | 8411 | const payload_alignment = optional_ty.abiAlignment(target); |
| 8402 | 8412 | alloca_inst.setAlignment(payload_alignment); |
| 8403 | 8413 | |
| 8404 | | const index_type = self.context.intType(32); |
| 8405 | 8414 | { |
| 8406 | | const indices: [2]*const llvm.Value = .{ |
| 8407 | | index_type.constNull(), // dereference the pointer |
| 8408 | | index_type.constNull(), // first field is the payload |
| 8409 | | }; |
| 8410 | | const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 8415 | const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, ""); |
| 8411 | 8416 | const store_inst = self.builder.buildStore(payload, field_ptr); |
| 8412 | 8417 | store_inst.setAlignment(payload_alignment); |
| 8413 | 8418 | } |
| 8414 | 8419 | { |
| 8415 | | const indices: [2]*const llvm.Value = .{ |
| 8416 | | index_type.constNull(), // dereference the pointer |
| 8417 | | index_type.constInt(1, .False), // second field is the non-null bit |
| 8418 | | }; |
| 8419 | | const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 8420 | const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, ""); |
| 8420 | 8421 | const store_inst = self.builder.buildStore(non_null_field, field_ptr); |
| 8421 | 8422 | store_inst.setAlignment(1); |
| 8422 | 8423 | } |
| ... | ... | @@ -9337,7 +9338,7 @@ fn ccAbiPromoteInt( |
| 9337 | 9338 | fn isByRef(ty: Type) bool { |
| 9338 | 9339 | // For tuples and structs, if there are more than this many non-void |
| 9339 | 9340 | // fields, then we make it byref, otherwise byval. |
| 9340 | | const max_fields_byval = 2; |
| 9341 | const max_fields_byval = 0; |
| 9341 | 9342 | |
| 9342 | 9343 | switch (ty.zigTypeTag()) { |
| 9343 | 9344 | .Type, |