| ... | @@ -2537,10 +2537,22 @@ pub const DeclGen = struct { | ... | @@ -2537,10 +2537,22 @@ pub const DeclGen = struct { |
| 2537 | return payload_llvm_ty; | 2537 | return payload_llvm_ty; |
| 2538 | } | 2538 | } |
| 2539 | | 2539 | |
| | 2540 | comptime assert(optional_layout_version == 1); |
| 2540 | const fields: [2]*const llvm.Type = .{ | 2541 | const fields: [2]*const llvm.Type = .{ |
| 2541 | payload_llvm_ty, dg.context.intType(1), | 2542 | payload_llvm_ty, |
| | 2543 | dg.context.intType(1), |
| 2542 | }; | 2544 | }; |
| 2543 | return dg.context.structType(&fields, fields.len, .False); | 2545 | const llvm_ty = dg.context.structType(&fields, fields.len, .False); |
| | 2546 | const llvm_size = dg.object.target_data.abiSizeOfType(llvm_ty); |
| | 2547 | const zig_size = t.abiSize(target); |
| | 2548 | const padding = @intCast(c_uint, zig_size - llvm_size); |
| | 2549 | if (padding == 0) return llvm_ty; |
| | 2550 | const padded_fields: [3]*const llvm.Type = .{ |
| | 2551 | payload_llvm_ty, |
| | 2552 | dg.context.intType(1), |
| | 2553 | dg.context.intType(8).arrayType(padding), |
| | 2554 | }; |
| | 2555 | return dg.context.structType(&padded_fields, padded_fields.len, .False); |
| 2544 | }, | 2556 | }, |
| 2545 | .ErrorUnion => { | 2557 | .ErrorUnion => { |
| 2546 | const payload_ty = t.errorUnionPayload(); | 2558 | const payload_ty = t.errorUnionPayload(); |
| ... | @@ -3101,6 +3113,7 @@ pub const DeclGen = struct { | ... | @@ -3101,6 +3113,7 @@ pub const DeclGen = struct { |
| 3101 | else => unreachable, | 3113 | else => unreachable, |
| 3102 | }, | 3114 | }, |
| 3103 | .Optional => { | 3115 | .Optional => { |
| | 3116 | comptime assert(optional_layout_version == 1); |
| 3104 | var buf: Type.Payload.ElemType = undefined; | 3117 | var buf: Type.Payload.ElemType = undefined; |
| 3105 | const payload_ty = tv.ty.optionalChild(&buf); | 3118 | const payload_ty = tv.ty.optionalChild(&buf); |
| 3106 | const llvm_i1 = dg.context.intType(1); | 3119 | const llvm_i1 = dg.context.intType(1); |
| ... | @@ -3109,25 +3122,30 @@ pub const DeclGen = struct { | ... | @@ -3109,25 +3122,30 @@ pub const DeclGen = struct { |
| 3109 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3122 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3110 | return non_null_bit; | 3123 | return non_null_bit; |
| 3111 | } | 3124 | } |
| | 3125 | const llvm_ty = try dg.lowerType(tv.ty); |
| 3112 | if (tv.ty.optionalReprIsPayload()) { | 3126 | if (tv.ty.optionalReprIsPayload()) { |
| 3113 | if (tv.val.castTag(.opt_payload)) |payload| { | 3127 | if (tv.val.castTag(.opt_payload)) |payload| { |
| 3114 | return dg.lowerValue(.{ .ty = payload_ty, .val = payload.data }); | 3128 | return dg.lowerValue(.{ .ty = payload_ty, .val = payload.data }); |
| 3115 | } else if (is_pl) { | 3129 | } else if (is_pl) { |
| 3116 | return dg.lowerValue(.{ .ty = payload_ty, .val = tv.val }); | 3130 | return dg.lowerValue(.{ .ty = payload_ty, .val = tv.val }); |
| 3117 | } else { | 3131 | } else { |
| 3118 | const llvm_ty = try dg.lowerType(tv.ty); | | |
| 3119 | return llvm_ty.constNull(); | 3132 | return llvm_ty.constNull(); |
| 3120 | } | 3133 | } |
| 3121 | } | 3134 | } |
| 3122 | assert(payload_ty.zigTypeTag() != .Fn); | 3135 | assert(payload_ty.zigTypeTag() != .Fn); |
| 3123 | const fields: [2]*const llvm.Value = .{ | 3136 | |
| 3124 | try dg.lowerValue(.{ | 3137 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| 3125 | .ty = payload_ty, | 3138 | var fields_buf: [3]*const llvm.Value = undefined; |
| 3126 | .val = if (tv.val.castTag(.opt_payload)) |pl| pl.data else Value.initTag(.undef), | 3139 | fields_buf[0] = try dg.lowerValue(.{ |
| 3127 | }), | 3140 | .ty = payload_ty, |
| 3128 | non_null_bit, | 3141 | .val = if (tv.val.castTag(.opt_payload)) |pl| pl.data else Value.initTag(.undef), |
| 3129 | }; | 3142 | }); |
| 3130 | return dg.context.constStruct(&fields, fields.len, .False); | 3143 | fields_buf[1] = non_null_bit; |
| | 3144 | if (llvm_field_count > 2) { |
| | 3145 | assert(llvm_field_count == 3); |
| | 3146 | fields_buf[2] = llvm_ty.structGetTypeAtIndex(2).getUndef(); |
| | 3147 | } |
| | 3148 | return dg.context.constStruct(&fields_buf, llvm_field_count, .False); |
| 3131 | }, | 3149 | }, |
| 3132 | .Fn => { | 3150 | .Fn => { |
| 3133 | const fn_decl_index = switch (tv.val.tag()) { | 3151 | const fn_decl_index = switch (tv.val.tag()) { |
| ... | @@ -5865,6 +5883,7 @@ pub const FuncGen = struct { | ... | @@ -5865,6 +5883,7 @@ pub const FuncGen = struct { |
| 5865 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5883 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5866 | const payload_ty = self.air.typeOf(ty_op.operand); | 5884 | const payload_ty = self.air.typeOf(ty_op.operand); |
| 5867 | const non_null_bit = self.context.intType(1).constAllOnes(); | 5885 | const non_null_bit = self.context.intType(1).constAllOnes(); |
| | 5886 | comptime assert(optional_layout_version == 1); |
| 5868 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return non_null_bit; | 5887 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return non_null_bit; |
| 5869 | const operand = try self.resolveInst(ty_op.operand); | 5888 | const operand = try self.resolveInst(ty_op.operand); |
| 5870 | const optional_ty = self.air.typeOfIndex(inst); | 5889 | const optional_ty = self.air.typeOfIndex(inst); |
| ... | @@ -9318,6 +9337,7 @@ fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool { | ... | @@ -9318,6 +9337,7 @@ fn intrinsicsAllowed(scalar_ty: Type, target: std.Target) bool { |
| 9318 | /// We can do this because for all types, Zig ABI alignment >= LLVM ABI | 9337 | /// We can do this because for all types, Zig ABI alignment >= LLVM ABI |
| 9319 | /// alignment. | 9338 | /// alignment. |
| 9320 | const struct_layout_version = 2; | 9339 | const struct_layout_version = 2; |
| | 9340 | const optional_layout_version = 1; |
| 9321 | | 9341 | |
| 9322 | /// We use the least significant bit of the pointer address to tell us | 9342 | /// We use the least significant bit of the pointer address to tell us |
| 9323 | /// whether the type is fully resolved. Types that are only fwd declared | 9343 | /// whether the type is fully resolved. Types that are only fwd declared |