| ... | @@ -9997,20 +9997,21 @@ pub const FuncGen = struct { | ... | @@ -9997,20 +9997,21 @@ pub const FuncGen = struct { |
| 9997 | return self.wip.conv(.unsigned, small_int_val, int_llvm_ty, ""); | 9997 | return self.wip.conv(.unsigned, small_int_val, int_llvm_ty, ""); |
| 9998 | } | 9998 | } |
| 9999 | | 9999 | |
| 10000 | const tag_int = blk: { | 10000 | const tag_int_val = blk: { |
| 10001 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); | 10001 | const tag_ty = union_ty.unionTagTypeHypothetical(mod); |
| 10002 | const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; | 10002 | const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index]; |
| 10003 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?; | 10003 | const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?; |
| 10004 | const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index); | 10004 | const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index); |
| 10005 | const tag_int_val = try tag_val.intFromEnum(tag_ty, mod); | 10005 | break :blk try tag_val.intFromEnum(tag_ty, mod); |
| 10006 | break :blk tag_int_val.toUnsignedInt(mod); | | |
| 10007 | }; | 10006 | }; |
| 10008 | if (layout.payload_size == 0) { | 10007 | if (layout.payload_size == 0) { |
| 10009 | if (layout.tag_size == 0) { | 10008 | if (layout.tag_size == 0) { |
| 10010 | return .none; | 10009 | return .none; |
| 10011 | } | 10010 | } |
| 10012 | assert(!isByRef(union_ty, mod)); | 10011 | assert(!isByRef(union_ty, mod)); |
| 10013 | return o.builder.intValue(union_llvm_ty, tag_int); | 10012 | var big_int_space: Value.BigIntSpace = undefined; |
| | 10013 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod); |
| | 10014 | return try o.builder.bigIntValue(union_llvm_ty, tag_big_int); |
| 10014 | } | 10015 | } |
| 10015 | assert(isByRef(union_ty, mod)); | 10016 | assert(isByRef(union_ty, mod)); |
| 10016 | // The llvm type of the alloca will be the named LLVM union type, and will not | 10017 | // The llvm type of the alloca will be the named LLVM union type, and will not |
| ... | @@ -10084,7 +10085,9 @@ pub const FuncGen = struct { | ... | @@ -10084,7 +10085,9 @@ pub const FuncGen = struct { |
| 10084 | const indices: [2]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, tag_index) }; | 10085 | const indices: [2]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, tag_index) }; |
| 10085 | const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, ""); | 10086 | const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, ""); |
| 10086 | const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); | 10087 | const tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); |
| 10087 | const llvm_tag = try o.builder.intValue(tag_ty, tag_int); | 10088 | var big_int_space: Value.BigIntSpace = undefined; |
| | 10089 | const tag_big_int = tag_int_val.toBigInt(&big_int_space, mod); |
| | 10090 | const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int); |
| 10088 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(mod).toLlvm(); | 10091 | const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(mod).toLlvm(); |
| 10089 | _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment); | 10092 | _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment); |
| 10090 | } | 10093 | } |