authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-08 07:02:53-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
log65fd401c063ed5214fd6d38b04278571df24f962
treec1cffc353ebcb12c8cbfc878358f61249562704a
parentd167bd4b568e2d5808fc37a8c683e4c06317a434

llvm: remove more usages of `llvm.Type`


2 files changed, 415 insertions(+), 433 deletions(-)

src/codegen/llvm.zig+386-422
...@@ -569,7 +569,7 @@ pub const Object = struct {...@@ -569,7 +569,7 @@ pub const Object = struct {
569 /// Therefore, this table keeps track of the mapping.569 /// Therefore, this table keeps track of the mapping.
570 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Global.Index),570 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Global.Index),
571 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.571 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.
572 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),572 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Function.Index),
573 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of573 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
574 /// the compiler.574 /// the compiler.
575 /// TODO when InternPool garbage collection is implemented, this map needs575 /// TODO when InternPool garbage collection is implemented, this map needs
...@@ -1210,7 +1210,7 @@ pub const Object = struct {...@@ -1210,7 +1210,7 @@ pub const Object = struct {
1210 if (isByRef(param_ty, mod)) {1210 if (isByRef(param_ty, mod)) {
1211 const alignment = param_ty.abiAlignment(mod);1211 const alignment = param_ty.abiAlignment(mod);
1212 const param_llvm_ty = param.typeOf();1212 const param_llvm_ty = param.typeOf();
1213 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1213 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1214 const store_inst = builder.buildStore(param, arg_ptr);1214 const store_inst = builder.buildStore(param, arg_ptr);
1215 store_inst.setAlignment(alignment);1215 store_inst.setAlignment(alignment);
1216 args.appendAssumeCapacity(arg_ptr);1216 args.appendAssumeCapacity(arg_ptr);
...@@ -1267,12 +1267,12 @@ pub const Object = struct {...@@ -1267,12 +1267,12 @@ pub const Object = struct {
12671267
1268 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);1268 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
1269 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));1269 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));
1270 const int_llvm_ty = o.context.intType(abi_size * 8);1270 const int_llvm_ty = (try o.builder.intType(@intCast(abi_size * 8))).toLlvm(&o.builder);
1271 const alignment = @max(1271 const alignment = @max(
1272 param_ty.abiAlignment(mod),1272 param_ty.abiAlignment(mod),
1273 o.target_data.abiAlignmentOfType(int_llvm_ty),1273 o.target_data.abiAlignmentOfType(int_llvm_ty),
1274 );1274 );
1275 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1275 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1276 const store_inst = builder.buildStore(param, arg_ptr);1276 const store_inst = builder.buildStore(param, arg_ptr);
1277 store_inst.setAlignment(alignment);1277 store_inst.setAlignment(alignment);
12781278
...@@ -1317,13 +1317,13 @@ pub const Object = struct {...@@ -1317,13 +1317,13 @@ pub const Object = struct {
1317 },1317 },
1318 .multiple_llvm_types => {1318 .multiple_llvm_types => {
1319 assert(!it.byval_attr);1319 assert(!it.byval_attr);
1320 const field_types = it.llvm_types_buffer[0..it.types_len];1320 const field_types = it.types_buffer[0..it.types_len];
1321 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();1321 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
1322 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);1322 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
1323 const param_alignment = param_ty.abiAlignment(mod);1323 const param_alignment = param_ty.abiAlignment(mod);
1324 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);1324 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1325 const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False);1325 const llvm_ty = (try o.builder.structType(.normal, field_types)).toLlvm(&o.builder);
1326 for (field_types, 0..) |_, field_i_usize| {1326 for (0..field_types.len) |field_i_usize| {
1327 const field_i = @as(c_uint, @intCast(field_i_usize));1327 const field_i = @as(c_uint, @intCast(field_i_usize));
1328 const param = llvm_func.getParam(llvm_arg_i);1328 const param = llvm_func.getParam(llvm_arg_i);
1329 llvm_arg_i += 1;1329 llvm_arg_i += 1;
...@@ -1344,7 +1344,7 @@ pub const Object = struct {...@@ -1344,7 +1344,7 @@ pub const Object = struct {
1344 assert(!it.byval_attr);1344 assert(!it.byval_attr);
1345 const param = llvm_func.getParam(llvm_arg_i);1345 const param = llvm_func.getParam(llvm_arg_i);
1346 llvm_arg_i += 1;1346 llvm_arg_i += 1;
1347 const casted = builder.buildBitCast(param, o.context.halfType(), "");1347 const casted = builder.buildBitCast(param, Builder.Type.half.toLlvm(&o.builder), "");
1348 try args.ensureUnusedCapacity(1);1348 try args.ensureUnusedCapacity(1);
1349 args.appendAssumeCapacity(casted);1349 args.appendAssumeCapacity(casted);
1350 },1350 },
...@@ -1355,7 +1355,7 @@ pub const Object = struct {...@@ -1355,7 +1355,7 @@ pub const Object = struct {
1355 llvm_arg_i += 1;1355 llvm_arg_i += 1;
13561356
1357 const alignment = param_ty.abiAlignment(mod);1357 const alignment = param_ty.abiAlignment(mod);
1358 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1358 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1359 _ = builder.buildStore(param, arg_ptr);1359 _ = builder.buildStore(param, arg_ptr);
13601360
1361 if (isByRef(param_ty, mod)) {1361 if (isByRef(param_ty, mod)) {
...@@ -1373,7 +1373,7 @@ pub const Object = struct {...@@ -1373,7 +1373,7 @@ pub const Object = struct {
1373 llvm_arg_i += 1;1373 llvm_arg_i += 1;
13741374
1375 const alignment = param_ty.abiAlignment(mod);1375 const alignment = param_ty.abiAlignment(mod);
1376 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, alignment, target);1376 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1377 _ = builder.buildStore(param, arg_ptr);1377 _ = builder.buildStore(param, arg_ptr);
13781378
1379 if (isByRef(param_ty, mod)) {1379 if (isByRef(param_ty, mod)) {
...@@ -3563,7 +3563,7 @@ pub const Object = struct {...@@ -3563,7 +3563,7 @@ pub const Object = struct {
3563 const bigint = int_val.toBigInt(&bigint_space, mod);3563 const bigint = int_val.toBigInt(&bigint_space, mod);
35643564
3565 const int_info = tv.ty.intInfo(mod);3565 const int_info = tv.ty.intInfo(mod);
3566 const llvm_type = o.context.intType(int_info.bits);3566 const llvm_type = (try o.builder.intType(@intCast(int_info.bits))).toLlvm(&o.builder);
35673567
3568 const unsigned_val = v: {3568 const unsigned_val = v: {
3569 if (bigint.limbs.len == 1) {3569 if (bigint.limbs.len == 1) {
...@@ -3587,26 +3587,26 @@ pub const Object = struct {...@@ -3587,26 +3587,26 @@ pub const Object = struct {
3587 switch (tv.ty.floatBits(target)) {3587 switch (tv.ty.floatBits(target)) {
3588 16 => {3588 16 => {
3589 const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod)));3589 const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod)));
3590 const llvm_i16 = o.context.intType(16);3590 const llvm_i16 = Builder.Type.i16.toLlvm(&o.builder);
3591 const int = llvm_i16.constInt(repr, .False);3591 const int = llvm_i16.constInt(repr, .False);
3592 return int.constBitCast(llvm_ty);3592 return int.constBitCast(llvm_ty);
3593 },3593 },
3594 32 => {3594 32 => {
3595 const repr = @as(u32, @bitCast(tv.val.toFloat(f32, mod)));3595 const repr = @as(u32, @bitCast(tv.val.toFloat(f32, mod)));
3596 const llvm_i32 = o.context.intType(32);3596 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
3597 const int = llvm_i32.constInt(repr, .False);3597 const int = llvm_i32.constInt(repr, .False);
3598 return int.constBitCast(llvm_ty);3598 return int.constBitCast(llvm_ty);
3599 },3599 },
3600 64 => {3600 64 => {
3601 const repr = @as(u64, @bitCast(tv.val.toFloat(f64, mod)));3601 const repr = @as(u64, @bitCast(tv.val.toFloat(f64, mod)));
3602 const llvm_i64 = o.context.intType(64);3602 const llvm_i64 = Builder.Type.i64.toLlvm(&o.builder);
3603 const int = llvm_i64.constInt(repr, .False);3603 const int = llvm_i64.constInt(repr, .False);
3604 return int.constBitCast(llvm_ty);3604 return int.constBitCast(llvm_ty);
3605 },3605 },
3606 80 => {3606 80 => {
3607 const float = tv.val.toFloat(f80, mod);3607 const float = tv.val.toFloat(f80, mod);
3608 const repr = std.math.break_f80(float);3608 const repr = std.math.break_f80(float);
3609 const llvm_i80 = o.context.intType(80);3609 const llvm_i80 = Builder.Type.i80.toLlvm(&o.builder);
3610 var x = llvm_i80.constInt(repr.exp, .False);3610 var x = llvm_i80.constInt(repr.exp, .False);
3611 x = x.constShl(llvm_i80.constInt(64, .False));3611 x = x.constShl(llvm_i80.constInt(64, .False));
3612 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));3612 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));
...@@ -3623,7 +3623,7 @@ pub const Object = struct {...@@ -3623,7 +3623,7 @@ pub const Object = struct {
3623 if (native_endian == .Big) {3623 if (native_endian == .Big) {
3624 std.mem.swap(u64, &buf[0], &buf[1]);3624 std.mem.swap(u64, &buf[0], &buf[1]);
3625 }3625 }
3626 const int = o.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);3626 const int = Builder.Type.i128.toLlvm(&o.builder).constIntOfArbitraryPrecision(buf.len, &buf);
3627 return int.constBitCast(llvm_ty);3627 return int.constBitCast(llvm_ty);
3628 },3628 },
3629 else => unreachable,3629 else => unreachable,
...@@ -3660,7 +3660,7 @@ pub const Object = struct {...@@ -3660,7 +3660,7 @@ pub const Object = struct {
3660 comptime assert(optional_layout_version == 3);3660 comptime assert(optional_layout_version == 3);
3661 const payload_ty = tv.ty.optionalChild(mod);3661 const payload_ty = tv.ty.optionalChild(mod);
36623662
3663 const llvm_i8 = o.context.intType(8);3663 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
3664 const non_null_bit = switch (opt.val) {3664 const non_null_bit = switch (opt.val) {
3665 .none => llvm_i8.constNull(),3665 .none => llvm_i8.constNull(),
3666 else => llvm_i8.constInt(1, .False),3666 else => llvm_i8.constInt(1, .False),
...@@ -3761,7 +3761,7 @@ pub const Object = struct {...@@ -3761,7 +3761,7 @@ pub const Object = struct {
3761 const elem_ty = vector_type.child.toType();3761 const elem_ty = vector_type.child.toType();
3762 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);3762 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);
3763 defer gpa.free(llvm_elems);3763 defer gpa.free(llvm_elems);
3764 const llvm_i8 = o.context.intType(8);3764 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
3765 for (llvm_elems, 0..) |*llvm_elem, i| {3765 for (llvm_elems, 0..) |*llvm_elem, i| {
3766 llvm_elem.* = switch (aggregate.storage) {3766 llvm_elem.* = switch (aggregate.storage) {
3767 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),3767 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),
...@@ -3802,7 +3802,7 @@ pub const Object = struct {...@@ -3802,7 +3802,7 @@ pub const Object = struct {
38023802
3803 const padding_len = offset - prev_offset;3803 const padding_len = offset - prev_offset;
3804 if (padding_len > 0) {3804 if (padding_len > 0) {
3805 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));3805 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));
3806 // TODO make this and all other padding elsewhere in debug3806 // TODO make this and all other padding elsewhere in debug
3807 // builds be 0xaa not undef.3807 // builds be 0xaa not undef.
3808 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3808 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
...@@ -3824,7 +3824,7 @@ pub const Object = struct {...@@ -3824,7 +3824,7 @@ pub const Object = struct {
3824 offset = std.mem.alignForward(u64, offset, big_align);3824 offset = std.mem.alignForward(u64, offset, big_align);
3825 const padding_len = offset - prev_offset;3825 const padding_len = offset - prev_offset;
3826 if (padding_len > 0) {3826 if (padding_len > 0) {
3827 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));3827 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));
3828 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3828 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3829 }3829 }
3830 }3830 }
...@@ -3850,7 +3850,7 @@ pub const Object = struct {...@@ -3850,7 +3850,7 @@ pub const Object = struct {
3850 if (struct_obj.layout == .Packed) {3850 if (struct_obj.layout == .Packed) {
3851 assert(struct_obj.haveLayout());3851 assert(struct_obj.haveLayout());
3852 const big_bits = struct_obj.backing_int_ty.bitSize(mod);3852 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
3853 const int_llvm_ty = o.context.intType(@as(c_uint, @intCast(big_bits)));3853 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);
3854 const fields = struct_obj.fields.values();3854 const fields = struct_obj.fields.values();
3855 comptime assert(Type.packed_struct_layout_version == 2);3855 comptime assert(Type.packed_struct_layout_version == 2);
3856 var running_int: *llvm.Value = int_llvm_ty.constNull();3856 var running_int: *llvm.Value = int_llvm_ty.constNull();
...@@ -3863,7 +3863,7 @@ pub const Object = struct {...@@ -3863,7 +3863,7 @@ pub const Object = struct {
3863 .val = try tv.val.fieldValue(mod, i),3863 .val = try tv.val.fieldValue(mod, i),
3864 });3864 });
3865 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));3865 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));
3866 const small_int_ty = o.context.intType(ty_bit_size);3866 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);
3867 const small_int_val = if (field.ty.isPtrAtRuntime(mod))3867 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
3868 non_int_val.constPtrToInt(small_int_ty)3868 non_int_val.constPtrToInt(small_int_ty)
3869 else3869 else
...@@ -3899,7 +3899,7 @@ pub const Object = struct {...@@ -3899,7 +3899,7 @@ pub const Object = struct {
38993899
3900 const padding_len = offset - prev_offset;3900 const padding_len = offset - prev_offset;
3901 if (padding_len > 0) {3901 if (padding_len > 0) {
3902 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));3902 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));
3903 // TODO make this and all other padding elsewhere in debug3903 // TODO make this and all other padding elsewhere in debug
3904 // builds be 0xaa not undef.3904 // builds be 0xaa not undef.
3905 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3905 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
...@@ -3921,7 +3921,7 @@ pub const Object = struct {...@@ -3921,7 +3921,7 @@ pub const Object = struct {
3921 offset = std.mem.alignForward(u64, offset, big_align);3921 offset = std.mem.alignForward(u64, offset, big_align);
3922 const padding_len = offset - prev_offset;3922 const padding_len = offset - prev_offset;
3923 if (padding_len > 0) {3923 if (padding_len > 0) {
3924 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));3924 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));
3925 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3925 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
3926 }3926 }
3927 }3927 }
...@@ -3969,7 +3969,7 @@ pub const Object = struct {...@@ -3969,7 +3969,7 @@ pub const Object = struct {
3969 return llvm_union_ty.constNull();3969 return llvm_union_ty.constNull();
3970 const non_int_val = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });3970 const non_int_val = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
3971 const ty_bit_size = @as(u16, @intCast(field_ty.bitSize(mod)));3971 const ty_bit_size = @as(u16, @intCast(field_ty.bitSize(mod)));
3972 const small_int_ty = o.context.intType(ty_bit_size);3972 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);
3973 const small_int_val = if (field_ty.isPtrAtRuntime(mod))3973 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
3974 non_int_val.constPtrToInt(small_int_ty)3974 non_int_val.constPtrToInt(small_int_ty)
3975 else3975 else
...@@ -3985,7 +3985,7 @@ pub const Object = struct {...@@ -3985,7 +3985,7 @@ pub const Object = struct {
3985 const payload = p: {3985 const payload = p: {
3986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {3986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3987 const padding_len = @as(c_uint, @intCast(layout.payload_size));3987 const padding_len = @as(c_uint, @intCast(layout.payload_size));
3988 break :p o.context.intType(8).arrayType(padding_len).getUndef();3988 break :p Builder.Type.i8.toLlvm(&o.builder).arrayType(padding_len).getUndef();
3989 }3989 }
3990 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });3990 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
3991 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);3991 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);
...@@ -3995,7 +3995,7 @@ pub const Object = struct {...@@ -3995,7 +3995,7 @@ pub const Object = struct {
3995 }3995 }
3996 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));3996 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));
3997 const fields: [2]*llvm.Value = .{3997 const fields: [2]*llvm.Value = .{
3998 field, o.context.intType(8).arrayType(padding_len).getUndef(),3998 field, Builder.Type.i8.toLlvm(&o.builder).arrayType(padding_len).getUndef(),
3999 };3999 };
4000 break :p o.context.constStruct(&fields, fields.len, .True);4000 break :p o.context.constStruct(&fields, fields.len, .True);
4001 };4001 };
...@@ -4020,7 +4020,7 @@ pub const Object = struct {...@@ -4020,7 +4020,7 @@ pub const Object = struct {
4020 fields = .{ payload, llvm_tag_value, undefined };4020 fields = .{ payload, llvm_tag_value, undefined };
4021 }4021 }
4022 if (layout.padding != 0) {4022 if (layout.padding != 0) {
4023 fields[2] = o.context.intType(8).arrayType(layout.padding).getUndef();4023 fields[2] = Builder.Type.i8.toLlvm(&o.builder).arrayType(layout.padding).getUndef();
4024 fields_len = 3;4024 fields_len = 3;
4025 }4025 }
4026 if (need_unnamed) {4026 if (need_unnamed) {
...@@ -4033,25 +4033,25 @@ pub const Object = struct {...@@ -4033,25 +4033,25 @@ pub const Object = struct {
4033 }4033 }
4034 }4034 }
40354035
4036 fn lowerIntAsPtr(o: *Object, val: Value) Error!*llvm.Value {4036 fn lowerIntAsPtr(o: *Object, val: Value) Allocator.Error!*llvm.Value {
4037 const mod = o.module;4037 const mod = o.module;
4038 switch (mod.intern_pool.indexToKey(val.toIntern())) {4038 switch (mod.intern_pool.indexToKey(val.toIntern())) {
4039 .undef => return o.context.pointerType(0).getUndef(),4039 .undef => return o.context.pointerType(0).getUndef(),
4040 .int => {4040 .int => {
4041 var bigint_space: Value.BigIntSpace = undefined;4041 var bigint_space: Value.BigIntSpace = undefined;
4042 const bigint = val.toBigInt(&bigint_space, mod);4042 const bigint = val.toBigInt(&bigint_space, mod);
4043 const llvm_int = lowerBigInt(o, Type.usize, bigint);4043 const llvm_int = try lowerBigInt(o, Type.usize, bigint);
4044 return llvm_int.constIntToPtr(o.context.pointerType(0));4044 return llvm_int.constIntToPtr(o.context.pointerType(0));
4045 },4045 },
4046 else => unreachable,4046 else => unreachable,
4047 }4047 }
4048 }4048 }
40494049
4050 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {4050 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) Allocator.Error!*llvm.Value {
4051 const mod = o.module;4051 const mod = o.module;
4052 const int_info = ty.intInfo(mod);4052 const int_info = ty.intInfo(mod);
4053 assert(int_info.bits != 0);4053 assert(int_info.bits != 0);
4054 const llvm_type = o.context.intType(int_info.bits);4054 const llvm_type = (try o.builder.intType(@intCast(int_info.bits))).toLlvm(&o.builder);
40554055
4056 const unsigned_val = v: {4056 const unsigned_val = v: {
4057 if (bigint.limbs.len == 1) {4057 if (bigint.limbs.len == 1) {
...@@ -4090,7 +4090,6 @@ pub const Object = struct {...@@ -4090,7 +4090,6 @@ pub const Object = struct {
40904090
4091 fn lowerParentPtr(o: *Object, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {4091 fn lowerParentPtr(o: *Object, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
4092 const mod = o.module;4092 const mod = o.module;
4093 const target = mod.getTarget();
4094 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {4093 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
4095 .decl => |decl| o.lowerParentPtrDecl(ptr_val, decl),4094 .decl => |decl| o.lowerParentPtrDecl(ptr_val, decl),
4096 .mut_decl => |mut_decl| o.lowerParentPtrDecl(ptr_val, mut_decl.decl),4095 .mut_decl => |mut_decl| o.lowerParentPtrDecl(ptr_val, mut_decl.decl),
...@@ -4107,7 +4106,7 @@ pub const Object = struct {...@@ -4107,7 +4106,7 @@ pub const Object = struct {
4107 }4106 }
41084107
4109 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;4108 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
4110 const llvm_u32 = o.context.intType(32);4109 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4111 const indices: [2]*llvm.Value = .{4110 const indices: [2]*llvm.Value = .{
4112 llvm_u32.constInt(0, .False),4111 llvm_u32.constInt(0, .False),
4113 llvm_u32.constInt(payload_offset, .False),4112 llvm_u32.constInt(payload_offset, .False),
...@@ -4128,7 +4127,7 @@ pub const Object = struct {...@@ -4128,7 +4127,7 @@ pub const Object = struct {
4128 return parent_llvm_ptr;4127 return parent_llvm_ptr;
4129 }4128 }
41304129
4131 const llvm_u32 = o.context.intType(32);4130 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4132 const indices: [2]*llvm.Value = .{4131 const indices: [2]*llvm.Value = .{
4133 llvm_u32.constInt(0, .False),4132 llvm_u32.constInt(0, .False),
4134 llvm_u32.constInt(0, .False),4133 llvm_u32.constInt(0, .False),
...@@ -4153,7 +4152,7 @@ pub const Object = struct {...@@ -4153,7 +4152,7 @@ pub const Object = struct {
4153 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);4152 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
41544153
4155 const field_index = @as(u32, @intCast(field_ptr.index));4154 const field_index = @as(u32, @intCast(field_ptr.index));
4156 const llvm_u32 = o.context.intType(32);4155 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4157 switch (parent_ty.zigTypeTag(mod)) {4156 switch (parent_ty.zigTypeTag(mod)) {
4158 .Union => {4157 .Union => {
4159 if (parent_ty.containerLayout(mod) == .Packed) {4158 if (parent_ty.containerLayout(mod) == .Packed) {
...@@ -4180,7 +4179,7 @@ pub const Object = struct {...@@ -4180,7 +4179,7 @@ pub const Object = struct {
4180 .Struct => {4179 .Struct => {
4181 if (parent_ty.containerLayout(mod) == .Packed) {4180 if (parent_ty.containerLayout(mod) == .Packed) {
4182 if (!byte_aligned) return parent_llvm_ptr;4181 if (!byte_aligned) return parent_llvm_ptr;
4183 const llvm_usize = o.context.intType(target.ptrBitWidth());4182 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
4184 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);4183 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
4185 // count bits of fields before this one4184 // count bits of fields before this one
4186 const prev_bits = b: {4185 const prev_bits = b: {
...@@ -4438,6 +4437,51 @@ pub const Object = struct {...@@ -4438,6 +4437,51 @@ pub const Object = struct {
4438 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty.toLlvm(&o.builder));4437 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty.toLlvm(&o.builder));
4439 }4438 }
4440 }4439 }
4440
4441 fn buildAllocaInner(
4442 o: *Object,
4443 builder: *llvm.Builder,
4444 llvm_func: *llvm.Value,
4445 di_scope_non_null: bool,
4446 llvm_ty: *llvm.Type,
4447 maybe_alignment: ?c_uint,
4448 target: std.Target,
4449 ) Allocator.Error!*llvm.Value {
4450 const address_space = llvmAllocaAddressSpace(target);
4451
4452 const alloca = blk: {
4453 const prev_block = builder.getInsertBlock();
4454 const prev_debug_location = builder.getCurrentDebugLocation2();
4455 defer {
4456 builder.positionBuilderAtEnd(prev_block);
4457 if (di_scope_non_null) {
4458 builder.setCurrentDebugLocation2(prev_debug_location);
4459 }
4460 }
4461
4462 const entry_block = llvm_func.getFirstBasicBlock().?;
4463 if (entry_block.getFirstInstruction()) |first_inst| {
4464 builder.positionBuilder(entry_block, first_inst);
4465 } else {
4466 builder.positionBuilderAtEnd(entry_block);
4467 }
4468 builder.clearCurrentDebugLocation();
4469
4470 break :blk builder.buildAllocaInAddressSpace(llvm_ty, @intFromEnum(address_space), "");
4471 };
4472
4473 if (maybe_alignment) |alignment| {
4474 alloca.setAlignment(alignment);
4475 }
4476
4477 // The pointer returned from this function should have the generic address space,
4478 // if this isn't the case then cast it to the generic address space.
4479 if (address_space != .default) {
4480 return builder.buildAddrSpaceCast(alloca, Builder.Type.ptr.toLlvm(&o.builder), "");
4481 }
4482
4483 return alloca;
4484 }
4441};4485};
44424486
4443pub const DeclGen = struct {4487pub const DeclGen = struct {
...@@ -4934,7 +4978,7 @@ pub const FuncGen = struct {...@@ -4934,7 +4978,7 @@ pub const FuncGen = struct {
49344978
4935 const ret_ptr = if (!sret) null else blk: {4979 const ret_ptr = if (!sret) null else blk: {
4936 const llvm_ret_ty = (try o.lowerType(return_type)).toLlvm(&o.builder);4980 const llvm_ret_ty = (try o.lowerType(return_type)).toLlvm(&o.builder);
4937 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));4981 const ret_ptr = try self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));
4938 try llvm_args.append(ret_ptr);4982 try llvm_args.append(ret_ptr);
4939 break :blk ret_ptr;4983 break :blk ret_ptr;
4940 };4984 };
...@@ -4971,7 +5015,7 @@ pub const FuncGen = struct {...@@ -4971,7 +5015,7 @@ pub const FuncGen = struct {
4971 } else {5015 } else {
4972 const alignment = param_ty.abiAlignment(mod);5016 const alignment = param_ty.abiAlignment(mod);
4973 const param_llvm_ty = llvm_arg.typeOf();5017 const param_llvm_ty = llvm_arg.typeOf();
4974 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);5018 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);
4975 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);5019 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);
4976 store_inst.setAlignment(alignment);5020 store_inst.setAlignment(alignment);
4977 try llvm_args.append(arg_ptr);5021 try llvm_args.append(arg_ptr);
...@@ -4984,7 +5028,7 @@ pub const FuncGen = struct {...@@ -4984,7 +5028,7 @@ pub const FuncGen = struct {
49845028
4985 const alignment = param_ty.abiAlignment(mod);5029 const alignment = param_ty.abiAlignment(mod);
4986 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);5030 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
4987 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);5031 const arg_ptr = try self.buildAlloca(param_llvm_ty, alignment);
4988 if (isByRef(param_ty, mod)) {5032 if (isByRef(param_ty, mod)) {
4989 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");5033 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
4990 load_inst.setAlignment(alignment);5034 load_inst.setAlignment(alignment);
...@@ -5003,7 +5047,7 @@ pub const FuncGen = struct {...@@ -5003,7 +5047,7 @@ pub const FuncGen = struct {
5003 const param_ty = self.typeOf(arg);5047 const param_ty = self.typeOf(arg);
5004 const llvm_arg = try self.resolveInst(arg);5048 const llvm_arg = try self.resolveInst(arg);
5005 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));5049 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));
5006 const int_llvm_ty = self.context.intType(abi_size * 8);5050 const int_llvm_ty = (try o.builder.intType(@intCast(abi_size * 8))).toLlvm(&o.builder);
50075051
5008 if (isByRef(param_ty, mod)) {5052 if (isByRef(param_ty, mod)) {
5009 const alignment = param_ty.abiAlignment(mod);5053 const alignment = param_ty.abiAlignment(mod);
...@@ -5017,7 +5061,7 @@ pub const FuncGen = struct {...@@ -5017,7 +5061,7 @@ pub const FuncGen = struct {
5017 param_ty.abiAlignment(mod),5061 param_ty.abiAlignment(mod),
5018 o.target_data.abiAlignmentOfType(int_llvm_ty),5062 o.target_data.abiAlignmentOfType(int_llvm_ty),
5019 );5063 );
5020 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);5064 const int_ptr = try self.buildAlloca(int_llvm_ty, alignment);
5021 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);5065 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
5022 store_inst.setAlignment(alignment);5066 store_inst.setAlignment(alignment);
5023 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");5067 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
...@@ -5037,22 +5081,22 @@ pub const FuncGen = struct {...@@ -5037,22 +5081,22 @@ pub const FuncGen = struct {
5037 .multiple_llvm_types => {5081 .multiple_llvm_types => {
5038 const arg = args[it.zig_index - 1];5082 const arg = args[it.zig_index - 1];
5039 const param_ty = self.typeOf(arg);5083 const param_ty = self.typeOf(arg);
5040 const llvm_types = it.llvm_types_buffer[0..it.types_len];5084 const llvm_types = it.types_buffer[0..it.types_len];
5041 const llvm_arg = try self.resolveInst(arg);5085 const llvm_arg = try self.resolveInst(arg);
5042 const is_by_ref = isByRef(param_ty, mod);5086 const is_by_ref = isByRef(param_ty, mod);
5043 const arg_ptr = if (is_by_ref) llvm_arg else p: {5087 const arg_ptr = if (is_by_ref) llvm_arg else p: {
5044 const p = self.buildAlloca(llvm_arg.typeOf(), null);5088 const p = try self.buildAlloca(llvm_arg.typeOf(), null);
5045 const store_inst = self.builder.buildStore(llvm_arg, p);5089 const store_inst = self.builder.buildStore(llvm_arg, p);
5046 store_inst.setAlignment(param_ty.abiAlignment(mod));5090 store_inst.setAlignment(param_ty.abiAlignment(mod));
5047 break :p p;5091 break :p p;
5048 };5092 };
50495093
5050 const llvm_ty = self.context.structType(llvm_types.ptr, @as(c_uint, @intCast(llvm_types.len)), .False);5094 const llvm_ty = (try o.builder.structType(.normal, llvm_types)).toLlvm(&o.builder);
5051 try llvm_args.ensureUnusedCapacity(it.types_len);5095 try llvm_args.ensureUnusedCapacity(it.types_len);
5052 for (llvm_types, 0..) |field_ty, i_usize| {5096 for (llvm_types, 0..) |field_ty, i_usize| {
5053 const i = @as(c_uint, @intCast(i_usize));5097 const i = @as(c_uint, @intCast(i_usize));
5054 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");5098 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");
5055 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");5099 const load_inst = self.builder.buildLoad(field_ty.toLlvm(&o.builder), field_ptr, "");
5056 load_inst.setAlignment(target.ptrBitWidth() / 8);5100 load_inst.setAlignment(target.ptrBitWidth() / 8);
5057 llvm_args.appendAssumeCapacity(load_inst);5101 llvm_args.appendAssumeCapacity(load_inst);
5058 }5102 }
...@@ -5060,7 +5104,7 @@ pub const FuncGen = struct {...@@ -5060,7 +5104,7 @@ pub const FuncGen = struct {
5060 .as_u16 => {5104 .as_u16 => {
5061 const arg = args[it.zig_index - 1];5105 const arg = args[it.zig_index - 1];
5062 const llvm_arg = try self.resolveInst(arg);5106 const llvm_arg = try self.resolveInst(arg);
5063 const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), "");5107 const casted = self.builder.buildBitCast(llvm_arg, Builder.Type.i16.toLlvm(&o.builder), "");
5064 try llvm_args.append(casted);5108 try llvm_args.append(casted);
5065 },5109 },
5066 .float_array => |count| {5110 .float_array => |count| {
...@@ -5068,7 +5112,7 @@ pub const FuncGen = struct {...@@ -5068,7 +5112,7 @@ pub const FuncGen = struct {
5068 const arg_ty = self.typeOf(arg);5112 const arg_ty = self.typeOf(arg);
5069 var llvm_arg = try self.resolveInst(arg);5113 var llvm_arg = try self.resolveInst(arg);
5070 if (!isByRef(arg_ty, mod)) {5114 if (!isByRef(arg_ty, mod)) {
5071 const p = self.buildAlloca(llvm_arg.typeOf(), null);5115 const p = try self.buildAlloca(llvm_arg.typeOf(), null);
5072 const store_inst = self.builder.buildStore(llvm_arg, p);5116 const store_inst = self.builder.buildStore(llvm_arg, p);
5073 store_inst.setAlignment(arg_ty.abiAlignment(mod));5117 store_inst.setAlignment(arg_ty.abiAlignment(mod));
5074 llvm_arg = store_inst;5118 llvm_arg = store_inst;
...@@ -5088,13 +5132,13 @@ pub const FuncGen = struct {...@@ -5088,13 +5132,13 @@ pub const FuncGen = struct {
5088 const arg_ty = self.typeOf(arg);5132 const arg_ty = self.typeOf(arg);
5089 var llvm_arg = try self.resolveInst(arg);5133 var llvm_arg = try self.resolveInst(arg);
5090 if (!isByRef(arg_ty, mod)) {5134 if (!isByRef(arg_ty, mod)) {
5091 const p = self.buildAlloca(llvm_arg.typeOf(), null);5135 const p = try self.buildAlloca(llvm_arg.typeOf(), null);
5092 const store_inst = self.builder.buildStore(llvm_arg, p);5136 const store_inst = self.builder.buildStore(llvm_arg, p);
5093 store_inst.setAlignment(arg_ty.abiAlignment(mod));5137 store_inst.setAlignment(arg_ty.abiAlignment(mod));
5094 llvm_arg = store_inst;5138 llvm_arg = store_inst;
5095 }5139 }
50965140
5097 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);5141 const array_llvm_ty = (try o.builder.intType(@intCast(elem_size))).toLlvm(&o.builder).arrayType(arr_len);
5098 const alignment = arg_ty.abiAlignment(mod);5142 const alignment = arg_ty.abiAlignment(mod);
5099 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");5143 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
5100 load_inst.setAlignment(alignment);5144 load_inst.setAlignment(alignment);
...@@ -5198,7 +5242,7 @@ pub const FuncGen = struct {...@@ -5198,7 +5242,7 @@ pub const FuncGen = struct {
5198 // a different LLVM type than the usual one. We solve this here at the callsite5242 // a different LLVM type than the usual one. We solve this here at the callsite
5199 // by using our canonical type, then loading it if necessary.5243 // by using our canonical type, then loading it if necessary.
5200 const alignment = o.target_data.abiAlignmentOfType(abi_ret_ty);5244 const alignment = o.target_data.abiAlignmentOfType(abi_ret_ty);
5201 const rp = self.buildAlloca(llvm_ret_ty, alignment);5245 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5202 const store_inst = self.builder.buildStore(call, rp);5246 const store_inst = self.builder.buildStore(call, rp);
5203 store_inst.setAlignment(alignment);5247 store_inst.setAlignment(alignment);
5204 if (isByRef(return_type, mod)) {5248 if (isByRef(return_type, mod)) {
...@@ -5214,7 +5258,7 @@ pub const FuncGen = struct {...@@ -5214,7 +5258,7 @@ pub const FuncGen = struct {
5214 // our by-ref status disagrees with sret so we must allocate, store,5258 // our by-ref status disagrees with sret so we must allocate, store,
5215 // and return the allocation pointer.5259 // and return the allocation pointer.
5216 const alignment = return_type.abiAlignment(mod);5260 const alignment = return_type.abiAlignment(mod);
5217 const rp = self.buildAlloca(llvm_ret_ty, alignment);5261 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5218 const store_inst = self.builder.buildStore(call, rp);5262 const store_inst = self.builder.buildStore(call, rp);
5219 store_inst.setAlignment(alignment);5263 store_inst.setAlignment(alignment);
5220 return rp;5264 return rp;
...@@ -5235,7 +5279,7 @@ pub const FuncGen = struct {...@@ -5235,7 +5279,7 @@ pub const FuncGen = struct {
5235 });5279 });
5236 const null_opt_addr_global = try o.getNullOptAddr();5280 const null_opt_addr_global = try o.getNullOptAddr();
5237 const target = mod.getTarget();5281 const target = mod.getTarget();
5238 const llvm_usize = fg.context.intType(target.ptrBitWidth());5282 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
5239 // example:5283 // example:
5240 // call fastcc void @test2.panic(5284 // call fastcc void @test2.panic(
5241 // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr5285 // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
...@@ -5310,7 +5354,7 @@ pub const FuncGen = struct {...@@ -5310,7 +5354,7 @@ pub const FuncGen = struct {
5310 return null;5354 return null;
5311 }5355 }
53125356
5313 const rp = self.buildAlloca(llvm_ret_ty, alignment);5357 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
5314 const store_inst = self.builder.buildStore(operand, rp);5358 const store_inst = self.builder.buildStore(operand, rp);
5315 store_inst.setAlignment(alignment);5359 store_inst.setAlignment(alignment);
5316 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");5360 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");
...@@ -5369,16 +5413,12 @@ pub const FuncGen = struct {...@@ -5369,16 +5413,12 @@ pub const FuncGen = struct {
5369 const mod = o.module;5413 const mod = o.module;
53705414
5371 const result_alignment = va_list_ty.abiAlignment(mod);5415 const result_alignment = va_list_ty.abiAlignment(mod);
5372 const dest_list = self.buildAlloca(llvm_va_list_ty, result_alignment);5416 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
53735417
5374 const llvm_fn_name = "llvm.va_copy";5418 const llvm_fn_name = "llvm.va_copy";
5375 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5419 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5376 const param_types = [_]*llvm.Type{5420 const fn_type = try o.builder.fnType(.void, &.{ .ptr, .ptr }, .normal);
5377 self.context.pointerType(0),5421 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
5378 self.context.pointerType(0),
5379 };
5380 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5381 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
5382 };5422 };
53835423
5384 const args: [2]*llvm.Value = .{ dest_list, src_list };5424 const args: [2]*llvm.Value = .{ dest_list, src_list };
...@@ -5400,9 +5440,8 @@ pub const FuncGen = struct {...@@ -5400,9 +5440,8 @@ pub const FuncGen = struct {
54005440
5401 const llvm_fn_name = "llvm.va_end";5441 const llvm_fn_name = "llvm.va_end";
5402 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5442 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5403 const param_types = [_]*llvm.Type{self.context.pointerType(0)};5443 const fn_type = try o.builder.fnType(.void, &.{.ptr}, .normal);
5404 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5444 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
5405 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
5406 };5445 };
5407 const args: [1]*llvm.Value = .{list};5446 const args: [1]*llvm.Value = .{list};
5408 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5447 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
...@@ -5416,13 +5455,12 @@ pub const FuncGen = struct {...@@ -5416,13 +5455,12 @@ pub const FuncGen = struct {
5416 const llvm_va_list_ty = (try o.lowerType(va_list_ty)).toLlvm(&o.builder);5455 const llvm_va_list_ty = (try o.lowerType(va_list_ty)).toLlvm(&o.builder);
54175456
5418 const result_alignment = va_list_ty.abiAlignment(mod);5457 const result_alignment = va_list_ty.abiAlignment(mod);
5419 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);5458 const list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
54205459
5421 const llvm_fn_name = "llvm.va_start";5460 const llvm_fn_name = "llvm.va_start";
5422 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5461 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5423 const param_types = [_]*llvm.Type{self.context.pointerType(0)};5462 const fn_type = try o.builder.fnType(.void, &.{.ptr}, .normal);
5424 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5463 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
5425 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
5426 };5464 };
5427 const args: [1]*llvm.Value = .{list};5465 const args: [1]*llvm.Value = .{list};
5428 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");5466 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
...@@ -5495,7 +5533,7 @@ pub const FuncGen = struct {...@@ -5495,7 +5533,7 @@ pub const FuncGen = struct {
5495 const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);5533 const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
5496 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);5534 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
5497 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);5535 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
5498 const llvm_i2 = self.context.intType(2);5536 const llvm_i2 = (try o.builder.intType(2)).toLlvm(&o.builder);
5499 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");5537 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");
5500 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");5538 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");
5501 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, llvm_i2.constInt(1, .False), "");5539 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, llvm_i2.constInt(1, .False), "");
...@@ -5529,7 +5567,7 @@ pub const FuncGen = struct {...@@ -5529,7 +5567,7 @@ pub const FuncGen = struct {
5529 mixed_block,5567 mixed_block,
5530 both_pl_block_end,5568 both_pl_block_end,
5531 };5569 };
5532 const llvm_i1 = self.context.intType(1);5570 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);
5533 const llvm_i1_0 = llvm_i1.constInt(0, .False);5571 const llvm_i1_0 = llvm_i1.constInt(0, .False);
5534 const llvm_i1_1 = llvm_i1.constInt(1, .False);5572 const llvm_i1_1 = llvm_i1.constInt(1, .False);
5535 const incoming_values: [3]*llvm.Value = .{5573 const incoming_values: [3]*llvm.Value = .{
...@@ -5767,13 +5805,11 @@ pub const FuncGen = struct {...@@ -5767,13 +5805,11 @@ pub const FuncGen = struct {
57675805
5768 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5806 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
5769 const o = self.dg.object;5807 const o = self.dg.object;
5770 const mod = o.module;
5771 const pl_op = self.air.instructions.items(.data)[inst].pl_op;5808 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
5772 const cond = try self.resolveInst(pl_op.operand);5809 const cond = try self.resolveInst(pl_op.operand);
5773 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);5810 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
5774 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");5811 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");
5775 const target = mod.getTarget();5812 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
5776 const llvm_usize = self.context.intType(target.ptrBitWidth());
5777 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)5813 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)
5778 self.builder.buildPtrToInt(cond, llvm_usize, "")5814 self.builder.buildPtrToInt(cond, llvm_usize, "")
5779 else5815 else
...@@ -5874,48 +5910,46 @@ pub const FuncGen = struct {...@@ -5874,48 +5910,46 @@ pub const FuncGen = struct {
58745910
5875 const dest_ty = self.typeOfIndex(inst);5911 const dest_ty = self.typeOfIndex(inst);
5876 const dest_scalar_ty = dest_ty.scalarType(mod);5912 const dest_scalar_ty = dest_ty.scalarType(mod);
5877 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);5913 const dest_llvm_ty = try o.lowerType(dest_ty);
5878 const target = mod.getTarget();5914 const target = mod.getTarget();
58795915
5880 if (intrinsicsAllowed(dest_scalar_ty, target)) {5916 if (intrinsicsAllowed(dest_scalar_ty, target)) {
5881 if (operand_scalar_ty.isSignedInt(mod)) {5917 if (operand_scalar_ty.isSignedInt(mod)) {
5882 return self.builder.buildSIToFP(operand, dest_llvm_ty, "");5918 return self.builder.buildSIToFP(operand, dest_llvm_ty.toLlvm(&o.builder), "");
5883 } else {5919 } else {
5884 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");5920 return self.builder.buildUIToFP(operand, dest_llvm_ty.toLlvm(&o.builder), "");
5885 }5921 }
5886 }5922 }
58875923
5888 const operand_bits = @as(u16, @intCast(operand_scalar_ty.bitSize(mod)));5924 const operand_bits = @as(u16, @intCast(operand_scalar_ty.bitSize(mod)));
5889 const rt_int_bits = compilerRtIntBits(operand_bits);5925 const rt_int_bits = compilerRtIntBits(operand_bits);
5890 const rt_int_ty = self.context.intType(rt_int_bits);5926 const rt_int_ty = try o.builder.intType(rt_int_bits);
5891 var extended = e: {5927 var extended = e: {
5892 if (operand_scalar_ty.isSignedInt(mod)) {5928 if (operand_scalar_ty.isSignedInt(mod)) {
5893 break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, "");5929 break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty.toLlvm(&o.builder), "");
5894 } else {5930 } else {
5895 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, "");5931 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty.toLlvm(&o.builder), "");
5896 }5932 }
5897 };5933 };
5898 const dest_bits = dest_scalar_ty.floatBits(target);5934 const dest_bits = dest_scalar_ty.floatBits(target);
5899 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);5935 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);
5900 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);5936 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);
5901 const sign_prefix = if (operand_scalar_ty.isSignedInt(mod)) "" else "un";5937 const sign_prefix = if (operand_scalar_ty.isSignedInt(mod)) "" else "un";
5902 var fn_name_buf: [64]u8 = undefined;5938 const fn_name = try o.builder.fmt("__float{s}{s}i{s}f", .{
5903 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{
5904 sign_prefix,5939 sign_prefix,
5905 compiler_rt_operand_abbrev,5940 compiler_rt_operand_abbrev,
5906 compiler_rt_dest_abbrev,5941 compiler_rt_dest_abbrev,
5907 }) catch unreachable;5942 });
59085943
5909 var param_types = [1]*llvm.Type{rt_int_ty};5944 var param_type = rt_int_ty;
5910 if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) {5945 if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) {
5911 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard5946 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
5912 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.5947 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
5913 const v2i64 = self.context.intType(64).vectorType(2);5948 param_type = try o.builder.vectorType(.normal, 2, .i64);
5914 extended = self.builder.buildBitCast(extended, v2i64, "");5949 extended = self.builder.buildBitCast(extended, param_type.toLlvm(&o.builder), "");
5915 param_types = [1]*llvm.Type{v2i64};
5916 }5950 }
59175951
5918 const libc_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);5952 const libc_fn = try self.getLibcFunction(fn_name, &.{param_type}, dest_llvm_ty);
5919 const params = [1]*llvm.Value{extended};5953 const params = [1]*llvm.Value{extended};
59205954
5921 return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");5955 return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
...@@ -5935,23 +5969,23 @@ pub const FuncGen = struct {...@@ -5935,23 +5969,23 @@ pub const FuncGen = struct {
59355969
5936 const dest_ty = self.typeOfIndex(inst);5970 const dest_ty = self.typeOfIndex(inst);
5937 const dest_scalar_ty = dest_ty.scalarType(mod);5971 const dest_scalar_ty = dest_ty.scalarType(mod);
5938 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);5972 const dest_llvm_ty = try o.lowerType(dest_ty);
59395973
5940 if (intrinsicsAllowed(operand_scalar_ty, target)) {5974 if (intrinsicsAllowed(operand_scalar_ty, target)) {
5941 // TODO set fast math flag5975 // TODO set fast math flag
5942 if (dest_scalar_ty.isSignedInt(mod)) {5976 if (dest_scalar_ty.isSignedInt(mod)) {
5943 return self.builder.buildFPToSI(operand, dest_llvm_ty, "");5977 return self.builder.buildFPToSI(operand, dest_llvm_ty.toLlvm(&o.builder), "");
5944 } else {5978 } else {
5945 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");5979 return self.builder.buildFPToUI(operand, dest_llvm_ty.toLlvm(&o.builder), "");
5946 }5980 }
5947 }5981 }
59485982
5949 const rt_int_bits = compilerRtIntBits(@as(u16, @intCast(dest_scalar_ty.bitSize(mod))));5983 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(mod)));
5950 const ret_ty = self.context.intType(rt_int_bits);5984 const ret_ty = try o.builder.intType(rt_int_bits);
5951 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {5985 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
5952 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard5986 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
5953 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.5987 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
5954 break :b self.context.intType(64).vectorType(2);5988 break :b try o.builder.vectorType(.normal, 2, .i64);
5955 } else ret_ty;5989 } else ret_ty;
59565990
5957 const operand_bits = operand_scalar_ty.floatBits(target);5991 const operand_bits = operand_scalar_ty.floatBits(target);
...@@ -5960,22 +5994,20 @@ pub const FuncGen = struct {...@@ -5960,22 +5994,20 @@ pub const FuncGen = struct {
5960 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);5994 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
5961 const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns";5995 const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns";
59625996
5963 var fn_name_buf: [64]u8 = undefined;5997 const fn_name = try o.builder.fmt("__fix{s}{s}f{s}i", .{
5964 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
5965 sign_prefix,5998 sign_prefix,
5966 compiler_rt_operand_abbrev,5999 compiler_rt_operand_abbrev,
5967 compiler_rt_dest_abbrev,6000 compiler_rt_dest_abbrev,
5968 }) catch unreachable;6001 });
59696002
5970 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);6003 const operand_llvm_ty = try o.lowerType(operand_ty);
5971 const param_types = [1]*llvm.Type{operand_llvm_ty};6004 const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty);
5972 const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
5973 const params = [1]*llvm.Value{operand};6005 const params = [1]*llvm.Value{operand};
59746006
5975 var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");6007 var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
59766008
5977 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, "");6009 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty.toLlvm(&o.builder), "");
5978 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");6010 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty.toLlvm(&o.builder), "");
5979 return result;6011 return result;
5980 }6012 }
59816013
...@@ -5989,11 +6021,10 @@ pub const FuncGen = struct {...@@ -5989,11 +6021,10 @@ pub const FuncGen = struct {
5989 }6021 }
5990 }6022 }
59916023
5992 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) *llvm.Value {6024 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) Allocator.Error!*llvm.Value {
5993 const o = fg.dg.object;6025 const o = fg.dg.object;
5994 const mod = o.module;6026 const mod = o.module;
5995 const target = mod.getTarget();6027 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
5996 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
5997 switch (ty.ptrSize(mod)) {6028 switch (ty.ptrSize(mod)) {
5998 .Slice => {6029 .Slice => {
5999 const len = fg.builder.buildExtractValue(ptr, 1, "");6030 const len = fg.builder.buildExtractValue(ptr, 1, "");
...@@ -6080,7 +6111,7 @@ pub const FuncGen = struct {...@@ -6080,7 +6111,7 @@ pub const FuncGen = struct {
6080 const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder);6111 const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder);
6081 const elem_ty = array_ty.childType(mod);6112 const elem_ty = array_ty.childType(mod);
6082 if (isByRef(array_ty, mod)) {6113 if (isByRef(array_ty, mod)) {
6083 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };6114 const indices: [2]*llvm.Value = .{ Builder.Type.i32.toLlvm(&o.builder).constNull(), rhs };
6084 if (isByRef(elem_ty, mod)) {6115 if (isByRef(elem_ty, mod)) {
6085 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");6116 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
6086 if (canElideLoad(self, body_tail))6117 if (canElideLoad(self, body_tail))
...@@ -6128,7 +6159,7 @@ pub const FuncGen = struct {...@@ -6128,7 +6159,7 @@ pub const FuncGen = struct {
6128 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch6159 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
6129 const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {6160 const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {
6130 // If this is a single-item pointer to an array, we need another index in the GEP.6161 // If this is a single-item pointer to an array, we need another index in the GEP.
6131 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };6162 const indices: [2]*llvm.Value = .{ Builder.Type.i32.toLlvm(&o.builder).constNull(), rhs };
6132 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");6163 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
6133 } else ptr: {6164 } else ptr: {
6134 const indices: [1]*llvm.Value = .{rhs};6165 const indices: [1]*llvm.Value = .{rhs};
...@@ -6162,7 +6193,7 @@ pub const FuncGen = struct {...@@ -6162,7 +6193,7 @@ pub const FuncGen = struct {
6162 const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder);6193 const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder);
6163 if (ptr_ty.isSinglePointer(mod)) {6194 if (ptr_ty.isSinglePointer(mod)) {
6164 // If this is a single-item pointer to an array, we need another index in the GEP.6195 // If this is a single-item pointer to an array, we need another index in the GEP.
6165 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };6196 const indices: [2]*llvm.Value = .{ Builder.Type.i32.toLlvm(&o.builder).constNull(), rhs };
6166 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");6197 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
6167 } else {6198 } else {
6168 const indices: [1]*llvm.Value = .{rhs};6199 const indices: [1]*llvm.Value = .{rhs};
...@@ -6216,12 +6247,12 @@ pub const FuncGen = struct {...@@ -6216,12 +6247,12 @@ pub const FuncGen = struct {
6216 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);6247 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
6217 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6248 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6218 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6249 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
6219 const same_size_int = self.context.intType(elem_bits);6250 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6220 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6251 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6221 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6252 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6222 } else if (field_ty.isPtrAtRuntime(mod)) {6253 } else if (field_ty.isPtrAtRuntime(mod)) {
6223 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6254 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
6224 const same_size_int = self.context.intType(elem_bits);6255 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6225 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");6256 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
6226 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6257 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
6227 }6258 }
...@@ -6238,12 +6269,12 @@ pub const FuncGen = struct {...@@ -6238,12 +6269,12 @@ pub const FuncGen = struct {
6238 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);6269 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
6239 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {6270 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
6240 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6271 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
6241 const same_size_int = self.context.intType(elem_bits);6272 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6242 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6273 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6243 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");6274 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
6244 } else if (field_ty.isPtrAtRuntime(mod)) {6275 } else if (field_ty.isPtrAtRuntime(mod)) {
6245 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));6276 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
6246 const same_size_int = self.context.intType(elem_bits);6277 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
6247 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");6278 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
6248 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");6279 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
6249 }6280 }
...@@ -6302,7 +6333,6 @@ pub const FuncGen = struct {...@@ -6302,7 +6333,6 @@ pub const FuncGen = struct {
63026333
6303 const field_ptr = try self.resolveInst(extra.field_ptr);6334 const field_ptr = try self.resolveInst(extra.field_ptr);
63046335
6305 const target = o.module.getTarget();
6306 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);6336 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
6307 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);6337 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
63086338
...@@ -6310,7 +6340,7 @@ pub const FuncGen = struct {...@@ -6310,7 +6340,7 @@ pub const FuncGen = struct {
6310 if (field_offset == 0) {6340 if (field_offset == 0) {
6311 return field_ptr;6341 return field_ptr;
6312 }6342 }
6313 const llvm_usize_ty = self.context.intType(target.ptrBitWidth());6343 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
63146344
6315 const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize_ty, "");6345 const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize_ty, "");
6316 const base_ptr_int = self.builder.buildNUWSub(field_ptr_int, llvm_usize_ty.constInt(field_offset, .False), "");6346 const base_ptr_int = self.builder.buildNUWSub(field_ptr_int, llvm_usize_ty.constInt(field_offset, .False), "");
...@@ -6493,7 +6523,7 @@ pub const FuncGen = struct {...@@ -6493,7 +6523,7 @@ pub const FuncGen = struct {
6493 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);6523 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
6494 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {6524 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
6495 const alignment = operand_ty.abiAlignment(mod);6525 const alignment = operand_ty.abiAlignment(mod);
6496 const alloca = self.buildAlloca(operand.typeOf(), alignment);6526 const alloca = try self.buildAlloca(operand.typeOf(), alignment);
6497 const store_inst = self.builder.buildStore(operand, alloca);6527 const store_inst = self.builder.buildStore(operand, alloca);
6498 store_inst.setAlignment(alignment);6528 store_inst.setAlignment(alignment);
6499 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);6529 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);
...@@ -6532,7 +6562,7 @@ pub const FuncGen = struct {...@@ -6532,7 +6562,7 @@ pub const FuncGen = struct {
6532 // The exact number of return / parameter values depends on which output values6562 // The exact number of return / parameter values depends on which output values
6533 // are passed by reference as indirect outputs (determined below).6563 // are passed by reference as indirect outputs (determined below).
6534 const max_return_count = outputs.len;6564 const max_return_count = outputs.len;
6535 const llvm_ret_types = try arena.alloc(*llvm.Type, max_return_count);6565 const llvm_ret_types = try arena.alloc(Builder.Type, max_return_count);
6536 const llvm_ret_indirect = try arena.alloc(bool, max_return_count);6566 const llvm_ret_indirect = try arena.alloc(bool, max_return_count);
65376567
6538 const max_param_count = inputs.len + outputs.len;6568 const max_param_count = inputs.len + outputs.len;
...@@ -6571,7 +6601,7 @@ pub const FuncGen = struct {...@@ -6571,7 +6601,7 @@ pub const FuncGen = struct {
6571 const output_inst = try self.resolveInst(output);6601 const output_inst = try self.resolveInst(output);
6572 const output_ty = self.typeOf(output);6602 const output_ty = self.typeOf(output);
6573 assert(output_ty.zigTypeTag(mod) == .Pointer);6603 assert(output_ty.zigTypeTag(mod) == .Pointer);
6574 const elem_llvm_ty = (try o.lowerPtrElemTy(output_ty.childType(mod))).toLlvm(&o.builder);6604 const elem_llvm_ty = try o.lowerPtrElemTy(output_ty.childType(mod));
65756605
6576 if (llvm_ret_indirect[i]) {6606 if (llvm_ret_indirect[i]) {
6577 // Pass the result by reference as an indirect output (e.g. "=*m")6607 // Pass the result by reference as an indirect output (e.g. "=*m")
...@@ -6579,7 +6609,7 @@ pub const FuncGen = struct {...@@ -6579,7 +6609,7 @@ pub const FuncGen = struct {
65796609
6580 llvm_param_values[llvm_param_i] = output_inst;6610 llvm_param_values[llvm_param_i] = output_inst;
6581 llvm_param_types[llvm_param_i] = output_inst.typeOf();6611 llvm_param_types[llvm_param_i] = output_inst.typeOf();
6582 llvm_param_attrs[llvm_param_i] = elem_llvm_ty;6612 llvm_param_attrs[llvm_param_i] = elem_llvm_ty.toLlvm(&o.builder);
6583 llvm_param_i += 1;6613 llvm_param_i += 1;
6584 } else {6614 } else {
6585 // Pass the result directly (e.g. "=r")6615 // Pass the result directly (e.g. "=r")
...@@ -6588,7 +6618,7 @@ pub const FuncGen = struct {...@@ -6588,7 +6618,7 @@ pub const FuncGen = struct {
6588 }6618 }
6589 } else {6619 } else {
6590 const ret_ty = self.typeOfIndex(inst);6620 const ret_ty = self.typeOfIndex(inst);
6591 llvm_ret_types[llvm_ret_i] = (try o.lowerType(ret_ty)).toLlvm(&o.builder);6621 llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty);
6592 llvm_ret_i += 1;6622 llvm_ret_i += 1;
6593 }6623 }
65946624
...@@ -6623,9 +6653,9 @@ pub const FuncGen = struct {...@@ -6623,9 +6653,9 @@ pub const FuncGen = struct {
66236653
6624 const arg_llvm_value = try self.resolveInst(input);6654 const arg_llvm_value = try self.resolveInst(input);
6625 const arg_ty = self.typeOf(input);6655 const arg_ty = self.typeOf(input);
6626 var llvm_elem_ty: ?*llvm.Type = null;6656 var llvm_elem_ty: Builder.Type = .none;
6627 if (isByRef(arg_ty, mod)) {6657 if (isByRef(arg_ty, mod)) {
6628 llvm_elem_ty = (try o.lowerPtrElemTy(arg_ty)).toLlvm(&o.builder);6658 llvm_elem_ty = try o.lowerPtrElemTy(arg_ty);
6629 if (constraintAllowsMemory(constraint)) {6659 if (constraintAllowsMemory(constraint)) {
6630 llvm_param_values[llvm_param_i] = arg_llvm_value;6660 llvm_param_values[llvm_param_i] = arg_llvm_value;
6631 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();6661 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
...@@ -6643,7 +6673,7 @@ pub const FuncGen = struct {...@@ -6643,7 +6673,7 @@ pub const FuncGen = struct {
6643 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();6673 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
6644 } else {6674 } else {
6645 const alignment = arg_ty.abiAlignment(mod);6675 const alignment = arg_ty.abiAlignment(mod);
6646 const arg_ptr = self.buildAlloca(arg_llvm_value.typeOf(), alignment);6676 const arg_ptr = try self.buildAlloca(arg_llvm_value.typeOf(), alignment);
6647 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);6677 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);
6648 store_inst.setAlignment(alignment);6678 store_inst.setAlignment(alignment);
6649 llvm_param_values[llvm_param_i] = arg_ptr;6679 llvm_param_values[llvm_param_i] = arg_ptr;
...@@ -6671,8 +6701,10 @@ pub const FuncGen = struct {...@@ -6671,8 +6701,10 @@ pub const FuncGen = struct {
6671 // In the case of indirect inputs, LLVM requires the callsite to have6701 // In the case of indirect inputs, LLVM requires the callsite to have
6672 // an elementtype(<ty>) attribute.6702 // an elementtype(<ty>) attribute.
6673 if (constraint[0] == '*') {6703 if (constraint[0] == '*') {
6674 llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse6704 llvm_param_attrs[llvm_param_i] = (if (llvm_elem_ty != .none)
6675 (try o.lowerPtrElemTy(arg_ty.childType(mod))).toLlvm(&o.builder);6705 llvm_elem_ty
6706 else
6707 try o.lowerPtrElemTy(arg_ty.childType(mod))).toLlvm(&o.builder);
6676 } else {6708 } else {
6677 llvm_param_attrs[llvm_param_i] = null;6709 llvm_param_attrs[llvm_param_i] = null;
6678 }6710 }
...@@ -6792,17 +6824,13 @@ pub const FuncGen = struct {...@@ -6792,17 +6824,13 @@ pub const FuncGen = struct {
6792 }6824 }
67936825
6794 const ret_llvm_ty = switch (return_count) {6826 const ret_llvm_ty = switch (return_count) {
6795 0 => self.context.voidType(),6827 0 => .void,
6796 1 => llvm_ret_types[0],6828 1 => llvm_ret_types[0],
6797 else => self.context.structType(6829 else => try o.builder.structType(.normal, llvm_ret_types),
6798 llvm_ret_types.ptr,
6799 @as(c_uint, @intCast(return_count)),
6800 .False,
6801 ),
6802 };6830 };
68036831
6804 const llvm_fn_ty = llvm.functionType(6832 const llvm_fn_ty = llvm.functionType(
6805 ret_llvm_ty,6833 ret_llvm_ty.toLlvm(&o.builder),
6806 llvm_param_types.ptr,6834 llvm_param_types.ptr,
6807 @as(c_uint, @intCast(param_count)),6835 @as(c_uint, @intCast(param_count)),
6808 .False,6836 .False,
...@@ -6891,7 +6919,7 @@ pub const FuncGen = struct {...@@ -6891,7 +6919,7 @@ pub const FuncGen = struct {
6891 self.builder.buildLoad(optional_llvm_ty, operand, "")6919 self.builder.buildLoad(optional_llvm_ty, operand, "")
6892 else6920 else
6893 operand;6921 operand;
6894 const llvm_i8 = self.context.intType(8);6922 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
6895 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");6923 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
6896 }6924 }
68976925
...@@ -6921,7 +6949,7 @@ pub const FuncGen = struct {...@@ -6921,7 +6949,7 @@ pub const FuncGen = struct {
6921 const zero = err_set_ty.constNull();6949 const zero = err_set_ty.constNull();
69226950
6923 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {6951 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6924 const llvm_i1 = self.context.intType(1);6952 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);
6925 switch (op) {6953 switch (op) {
6926 .EQ => return llvm_i1.constInt(1, .False), // 0 == 06954 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
6927 .NE => return llvm_i1.constInt(0, .False), // 0 != 06955 .NE => return llvm_i1.constInt(0, .False), // 0 != 0
...@@ -6979,7 +7007,7 @@ pub const FuncGen = struct {...@@ -6979,7 +7007,7 @@ pub const FuncGen = struct {
6979 const operand = try self.resolveInst(ty_op.operand);7007 const operand = try self.resolveInst(ty_op.operand);
6980 const optional_ty = self.typeOf(ty_op.operand).childType(mod);7008 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
6981 const payload_ty = optional_ty.optionalChild(mod);7009 const payload_ty = optional_ty.optionalChild(mod);
6982 const non_null_bit = self.context.intType(8).constInt(1, .False);7010 const non_null_bit = Builder.Type.i8.toLlvm(&o.builder).constInt(1, .False);
6983 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7011 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
6984 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.7012 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
6985 _ = self.builder.buildStore(non_null_bit, operand);7013 _ = self.builder.buildStore(non_null_bit, operand);
...@@ -7165,7 +7193,7 @@ pub const FuncGen = struct {...@@ -7165,7 +7193,7 @@ pub const FuncGen = struct {
7165 const mod = o.module;7193 const mod = o.module;
7166 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7194 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7167 const payload_ty = self.typeOf(ty_op.operand);7195 const payload_ty = self.typeOf(ty_op.operand);
7168 const non_null_bit = self.context.intType(8).constInt(1, .False);7196 const non_null_bit = Builder.Type.i8.toLlvm(&o.builder).constInt(1, .False);
7169 comptime assert(optional_layout_version == 3);7197 comptime assert(optional_layout_version == 3);
7170 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;7198 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
7171 const operand = try self.resolveInst(ty_op.operand);7199 const operand = try self.resolveInst(ty_op.operand);
...@@ -7175,7 +7203,7 @@ pub const FuncGen = struct {...@@ -7175,7 +7203,7 @@ pub const FuncGen = struct {
7175 }7203 }
7176 const llvm_optional_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder);7204 const llvm_optional_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder);
7177 if (isByRef(optional_ty, mod)) {7205 if (isByRef(optional_ty, mod)) {
7178 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));7206 const optional_ptr = try self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
7179 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");7207 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
7180 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7208 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
7181 try self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic);7209 try self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic);
...@@ -7203,7 +7231,7 @@ pub const FuncGen = struct {...@@ -7203,7 +7231,7 @@ pub const FuncGen = struct {
7203 const payload_offset = errUnionPayloadOffset(payload_ty, mod);7231 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
7204 const error_offset = errUnionErrorOffset(payload_ty, mod);7232 const error_offset = errUnionErrorOffset(payload_ty, mod);
7205 if (isByRef(err_un_ty, mod)) {7233 if (isByRef(err_un_ty, mod)) {
7206 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));7234 const result_ptr = try self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
7207 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");7235 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
7208 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);7236 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
7209 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));7237 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
...@@ -7232,7 +7260,7 @@ pub const FuncGen = struct {...@@ -7232,7 +7260,7 @@ pub const FuncGen = struct {
7232 const payload_offset = errUnionPayloadOffset(payload_ty, mod);7260 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
7233 const error_offset = errUnionErrorOffset(payload_ty, mod);7261 const error_offset = errUnionErrorOffset(payload_ty, mod);
7234 if (isByRef(err_un_ty, mod)) {7262 if (isByRef(err_un_ty, mod)) {
7235 const result_ptr = self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));7263 const result_ptr = try self.buildAlloca(err_un_llvm_ty, err_un_ty.abiAlignment(mod));
7236 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");7264 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
7237 const store_inst = self.builder.buildStore(operand, err_ptr);7265 const store_inst = self.builder.buildStore(operand, err_ptr);
7238 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));7266 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
...@@ -7252,8 +7280,8 @@ pub const FuncGen = struct {...@@ -7252,8 +7280,8 @@ pub const FuncGen = struct {
7252 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7280 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7253 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7281 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7254 const index = pl_op.payload;7282 const index = pl_op.payload;
7255 const llvm_u32 = self.context.intType(32);7283 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7256 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});7284 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.size", &.{.i32});
7257 const args: [1]*llvm.Value = .{llvm_u32.constInt(index, .False)};7285 const args: [1]*llvm.Value = .{llvm_u32.constInt(index, .False)};
7258 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");7286 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
7259 }7287 }
...@@ -7262,8 +7290,8 @@ pub const FuncGen = struct {...@@ -7262,8 +7290,8 @@ pub const FuncGen = struct {
7262 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7290 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7263 const index = pl_op.payload;7291 const index = pl_op.payload;
7264 const operand = try self.resolveInst(pl_op.operand);7292 const operand = try self.resolveInst(pl_op.operand);
7265 const llvm_u32 = self.context.intType(32);7293 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7266 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow", &.{llvm_u32});7294 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.grow", &.{.i32});
7267 const args: [2]*llvm.Value = .{7295 const args: [2]*llvm.Value = .{
7268 llvm_u32.constInt(index, .False),7296 llvm_u32.constInt(index, .False),
7269 operand,7297 operand,
...@@ -7371,8 +7399,7 @@ pub const FuncGen = struct {...@@ -7371,8 +7399,7 @@ pub const FuncGen = struct {
7371 true => signed_intrinsic,7399 true => signed_intrinsic,
7372 false => unsigned_intrinsic,7400 false => unsigned_intrinsic,
7373 };7401 };
7374 const llvm_inst_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder);7402 const llvm_fn = try fg.getIntrinsic(intrinsic_name, &.{try o.lowerType(inst_ty)});
7375 const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty});
7376 const result_struct = fg.builder.buildCall(7403 const result_struct = fg.builder.buildCall(
7377 llvm_fn.globalGetValueType(),7404 llvm_fn.globalGetValueType(),
7378 llvm_fn,7405 llvm_fn,
...@@ -7658,7 +7685,7 @@ pub const FuncGen = struct {...@@ -7658,7 +7685,7 @@ pub const FuncGen = struct {
7658 switch (ptr_ty.ptrSize(mod)) {7685 switch (ptr_ty.ptrSize(mod)) {
7659 .One => {7686 .One => {
7660 // It's a pointer to an array, so according to LLVM we need an extra GEP index.7687 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
7661 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), offset };7688 const indices: [2]*llvm.Value = .{ Builder.Type.i32.toLlvm(&o.builder).constNull(), offset };
7662 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");7689 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
7663 },7690 },
7664 .C, .Many => {7691 .C, .Many => {
...@@ -7687,7 +7714,7 @@ pub const FuncGen = struct {...@@ -7687,7 +7714,7 @@ pub const FuncGen = struct {
7687 .One => {7714 .One => {
7688 // It's a pointer to an array, so according to LLVM we need an extra GEP index.7715 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
7689 const indices: [2]*llvm.Value = .{7716 const indices: [2]*llvm.Value = .{
7690 self.context.intType(32).constNull(), negative_offset,7717 Builder.Type.i32.toLlvm(&o.builder).constNull(), negative_offset,
7691 };7718 };
7692 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");7719 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
7693 },7720 },
...@@ -7723,10 +7750,9 @@ pub const FuncGen = struct {...@@ -7723,10 +7750,9 @@ pub const FuncGen = struct {
77237750
7724 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;7751 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
77257752
7726 const llvm_lhs_ty = (try o.lowerType(lhs_ty)).toLlvm(&o.builder);
7727 const llvm_dest_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);7753 const llvm_dest_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
77287754
7729 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});7755 const llvm_fn = try self.getIntrinsic(intrinsic_name, &.{try o.lowerType(lhs_ty)});
7730 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");7756 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
77317757
7732 const result = self.builder.buildExtractValue(result_struct, 0, "");7758 const result = self.builder.buildExtractValue(result_struct, 0, "");
...@@ -7737,7 +7763,7 @@ pub const FuncGen = struct {...@@ -7737,7 +7763,7 @@ pub const FuncGen = struct {
77377763
7738 if (isByRef(dest_ty, mod)) {7764 if (isByRef(dest_ty, mod)) {
7739 const result_alignment = dest_ty.abiAlignment(mod);7765 const result_alignment = dest_ty.abiAlignment(mod);
7740 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);7766 const alloca_inst = try self.buildAlloca(llvm_dest_ty, result_alignment);
7741 {7767 {
7742 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");7768 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
7743 const store_inst = self.builder.buildStore(result, field_ptr);7769 const store_inst = self.builder.buildStore(result, field_ptr);
...@@ -7764,7 +7790,7 @@ pub const FuncGen = struct {...@@ -7764,7 +7790,7 @@ pub const FuncGen = struct {
7764 vector_len: usize,7790 vector_len: usize,
7765 ) !*llvm.Value {7791 ) !*llvm.Value {
7766 const args_len = @as(c_uint, @intCast(args_vectors.len));7792 const args_len = @as(c_uint, @intCast(args_vectors.len));
7767 const llvm_i32 = self.context.intType(32);7793 const llvm_i32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7768 assert(args_len <= 3);7794 assert(args_len <= 3);
77697795
7770 var i: usize = 0;7796 var i: usize = 0;
...@@ -7784,23 +7810,21 @@ pub const FuncGen = struct {...@@ -7784,23 +7810,21 @@ pub const FuncGen = struct {
77847810
7785 fn getLibcFunction(7811 fn getLibcFunction(
7786 self: *FuncGen,7812 self: *FuncGen,
7787 fn_name: [:0]const u8,7813 fn_name: Builder.String,
7788 param_types: []const *llvm.Type,7814 param_types: []const Builder.Type,
7789 return_type: *llvm.Type,7815 return_type: Builder.Type,
7790 ) Allocator.Error!*llvm.Value {7816 ) Allocator.Error!*llvm.Value {
7791 const o = self.dg.object;7817 const o = self.dg.object;
7792 return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {7818 const slice = fn_name.toSlice(&o.builder).?;
7793 const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);7819 return o.llvm_module.getNamedFunction(slice) orelse b: {
7820 const alias = o.llvm_module.getNamedGlobalAlias(slice.ptr, slice.len);
7794 break :b if (alias) |a| a.getAliasee() else null;7821 break :b if (alias) |a| a.getAliasee() else null;
7795 } orelse b: {7822 } orelse b: {
7796 const name = try o.builder.string(fn_name);7823 const fn_type = try o.builder.fnType(return_type, param_types, .normal);
77977824 const f = o.llvm_module.addFunction(slice, fn_type.toLlvm(&o.builder));
7798 const params_len = @as(c_uint, @intCast(param_types.len));
7799 const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False);
7800 const f = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type);
78017825
7802 var global = Builder.Global{7826 var global = Builder.Global{
7803 .type = try o.builder.fnType(.void, &.{}, .normal),7827 .type = fn_type,
7804 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },7828 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
7805 };7829 };
7806 var function = Builder.Function{7830 var function = Builder.Function{
...@@ -7808,9 +7832,8 @@ pub const FuncGen = struct {...@@ -7808,9 +7832,8 @@ pub const FuncGen = struct {
7808 };7832 };
78097833
7810 try o.builder.llvm_globals.append(self.gpa, f);7834 try o.builder.llvm_globals.append(self.gpa, f);
7811 _ = try o.builder.addGlobal(name, global);7835 _ = try o.builder.addGlobal(fn_name, global);
7812 try o.builder.functions.append(self.gpa, function);7836 try o.builder.functions.append(self.gpa, function);
7813
7814 break :b f;7837 break :b f;
7815 };7838 };
7816 }7839 }
...@@ -7827,7 +7850,7 @@ pub const FuncGen = struct {...@@ -7827,7 +7850,7 @@ pub const FuncGen = struct {
7827 const mod = o.module;7850 const mod = o.module;
7828 const target = o.module.getTarget();7851 const target = o.module.getTarget();
7829 const scalar_ty = ty.scalarType(mod);7852 const scalar_ty = ty.scalarType(mod);
7830 const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);7853 const scalar_llvm_ty = try o.lowerType(scalar_ty);
78317854
7832 if (intrinsicsAllowed(scalar_ty, target)) {7855 if (intrinsicsAllowed(scalar_ty, target)) {
7833 const llvm_predicate: llvm.RealPredicate = switch (pred) {7856 const llvm_predicate: llvm.RealPredicate = switch (pred) {
...@@ -7843,7 +7866,6 @@ pub const FuncGen = struct {...@@ -7843,7 +7866,6 @@ pub const FuncGen = struct {
78437866
7844 const float_bits = scalar_ty.floatBits(target);7867 const float_bits = scalar_ty.floatBits(target);
7845 const compiler_rt_float_abbrev = compilerRtFloatAbbrev(float_bits);7868 const compiler_rt_float_abbrev = compilerRtFloatAbbrev(float_bits);
7846 var fn_name_buf: [64]u8 = undefined;
7847 const fn_base_name = switch (pred) {7869 const fn_base_name = switch (pred) {
7848 .neq => "ne",7870 .neq => "ne",
7849 .eq => "eq",7871 .eq => "eq",
...@@ -7852,15 +7874,15 @@ pub const FuncGen = struct {...@@ -7852,15 +7874,15 @@ pub const FuncGen = struct {
7852 .gt => "gt",7874 .gt => "gt",
7853 .gte => "ge",7875 .gte => "ge",
7854 };7876 };
7855 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f2", .{7877 const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });
7856 fn_base_name, compiler_rt_float_abbrev,
7857 }) catch unreachable;
78587878
7859 const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty };7879 const libc_fn = try self.getLibcFunction(
7860 const llvm_i32 = self.context.intType(32);7880 fn_name,
7861 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..], llvm_i32);7881 ([1]Builder.Type{scalar_llvm_ty} ** 2)[0..],
7882 .i32,
7883 );
78627884
7863 const zero = llvm_i32.constInt(0, .False);7885 const zero = Builder.Type.i32.toLlvm(&o.builder).constInt(0, .False);
7864 const int_pred: llvm.IntPredicate = switch (pred) {7886 const int_pred: llvm.IntPredicate = switch (pred) {
7865 .eq => .EQ,7887 .eq => .EQ,
7866 .neq => .NE,7888 .neq => .NE,
...@@ -7872,7 +7894,7 @@ pub const FuncGen = struct {...@@ -7872,7 +7894,7 @@ pub const FuncGen = struct {
78727894
7873 if (ty.zigTypeTag(mod) == .Vector) {7895 if (ty.zigTypeTag(mod) == .Vector) {
7874 const vec_len = ty.vectorLen(mod);7896 const vec_len = ty.vectorLen(mod);
7875 const vector_result_ty = llvm_i32.vectorType(vec_len);7897 const vector_result_ty = (try o.builder.vectorType(.normal, vec_len, .i32)).toLlvm(&o.builder);
78767898
7877 var result = vector_result_ty.getUndef();7899 var result = vector_result_ty.getUndef();
7878 result = try self.buildElementwiseCall(libc_fn, &params, result, vec_len);7900 result = try self.buildElementwiseCall(libc_fn, &params, result, vec_len);
...@@ -7913,7 +7935,7 @@ pub const FuncGen = struct {...@@ -7913,7 +7935,7 @@ pub const FuncGen = struct {
79137935
7914 const FloatOpStrat = union(enum) {7936 const FloatOpStrat = union(enum) {
7915 intrinsic: []const u8,7937 intrinsic: []const u8,
7916 libc: [:0]const u8,7938 libc: Builder.String,
7917 };7939 };
79187940
7919 /// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.)7941 /// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.)
...@@ -7930,11 +7952,10 @@ pub const FuncGen = struct {...@@ -7930,11 +7952,10 @@ pub const FuncGen = struct {
7930 const mod = o.module;7952 const mod = o.module;
7931 const target = mod.getTarget();7953 const target = mod.getTarget();
7932 const scalar_ty = ty.scalarType(mod);7954 const scalar_ty = ty.scalarType(mod);
7933 const llvm_ty = (try o.lowerType(ty)).toLlvm(&o.builder);7955 const llvm_ty = try o.lowerType(ty);
7934 const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);7956 const scalar_llvm_ty = try o.lowerType(scalar_ty);
79357957
7936 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);7958 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
7937 var fn_name_buf: [64]u8 = undefined;
7938 const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {7959 const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {
7939 // Some operations are dedicated LLVM instructions, not available as intrinsics7960 // Some operations are dedicated LLVM instructions, not available as intrinsics
7940 .neg => return self.builder.buildFNeg(params[0], ""),7961 .neg => return self.builder.buildFNeg(params[0], ""),
...@@ -7952,7 +7973,7 @@ pub const FuncGen = struct {...@@ -7952,7 +7973,7 @@ pub const FuncGen = struct {
7952 .neg => {7973 .neg => {
7953 // In this case we can generate a softfloat negation by XORing the7974 // In this case we can generate a softfloat negation by XORing the
7954 // bits with a constant.7975 // bits with a constant.
7955 const int_llvm_ty = self.context.intType(float_bits);7976 const int_llvm_ty = (try o.builder.intType(@intCast(float_bits))).toLlvm(&o.builder);
7956 const one = int_llvm_ty.constInt(1, .False);7977 const one = int_llvm_ty.constInt(1, .False);
7957 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);7978 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
7958 const sign_mask = one.constShl(shift_amt);7979 const sign_mask = one.constShl(shift_amt);
...@@ -7965,13 +7986,11 @@ pub const FuncGen = struct {...@@ -7965,13 +7986,11 @@ pub const FuncGen = struct {
7965 const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, "");7986 const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, "");
7966 break :blk self.builder.buildXor(bitcasted_operand, sign_mask, "");7987 break :blk self.builder.buildXor(bitcasted_operand, sign_mask, "");
7967 };7988 };
7968 return self.builder.buildBitCast(result, llvm_ty, "");7989 return self.builder.buildBitCast(result, llvm_ty.toLlvm(&o.builder), "");
7969 },
7970 .add, .sub, .div, .mul => FloatOpStrat{
7971 .libc = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f3", .{
7972 @tagName(op), compilerRtFloatAbbrev(float_bits),
7973 }) catch unreachable,
7974 },7990 },
7991 .add, .sub, .div, .mul => .{ .libc = try o.builder.fmt("__{s}{s}f3", .{
7992 @tagName(op), compilerRtFloatAbbrev(float_bits),
7993 }) },
7975 .ceil,7994 .ceil,
7976 .cos,7995 .cos,
7977 .exp,7996 .exp,
...@@ -7990,21 +8009,22 @@ pub const FuncGen = struct {...@@ -7990,21 +8009,22 @@ pub const FuncGen = struct {
7990 .sqrt,8009 .sqrt,
7991 .tan,8010 .tan,
7992 .trunc,8011 .trunc,
7993 => FloatOpStrat{8012 => .{ .libc = try o.builder.fmt("{s}{s}{s}", .{
7994 .libc = std.fmt.bufPrintZ(&fn_name_buf, "{s}{s}{s}", .{8013 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
7995 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),8014 }) },
7996 }) catch unreachable,
7997 },
7998 };8015 };
7999 };8016 };
80008017
8001 const llvm_fn: *llvm.Value = switch (strat) {8018 const llvm_fn: *llvm.Value = switch (strat) {
8002 .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}),8019 .intrinsic => |fn_name| try self.getIntrinsic(fn_name, &.{llvm_ty}),
8003 .libc => |fn_name| b: {8020 .libc => |fn_name| b: {
8004 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };8021 const libc_fn = try self.getLibcFunction(
8005 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);8022 fn_name,
8023 ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],
8024 scalar_llvm_ty,
8025 );
8006 if (ty.zigTypeTag(mod) == .Vector) {8026 if (ty.zigTypeTag(mod) == .Vector) {
8007 const result = llvm_ty.getUndef();8027 const result = llvm_ty.toLlvm(&o.builder).getUndef();
8008 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod));8028 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod));
8009 }8029 }
80108030
...@@ -8061,7 +8081,7 @@ pub const FuncGen = struct {...@@ -8061,7 +8081,7 @@ pub const FuncGen = struct {
80618081
8062 if (isByRef(dest_ty, mod)) {8082 if (isByRef(dest_ty, mod)) {
8063 const result_alignment = dest_ty.abiAlignment(mod);8083 const result_alignment = dest_ty.abiAlignment(mod);
8064 const alloca_inst = self.buildAlloca(llvm_dest_ty, result_alignment);8084 const alloca_inst = try self.buildAlloca(llvm_dest_ty, result_alignment);
8065 {8085 {
8066 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");8086 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
8067 const store_inst = self.builder.buildStore(result, field_ptr);8087 const store_inst = self.builder.buildStore(result, field_ptr);
...@@ -8266,17 +8286,15 @@ pub const FuncGen = struct {...@@ -8266,17 +8286,15 @@ pub const FuncGen = struct {
8266 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);8286 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
8267 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");8287 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
8268 } else {8288 } else {
8269 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);8289 const operand_llvm_ty = try o.lowerType(operand_ty);
8270 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);8290 const dest_llvm_ty = try o.lowerType(dest_ty);
82718291
8272 var fn_name_buf: [64]u8 = undefined;8292 const fn_name = try o.builder.fmt("__trunc{s}f{s}f2", .{
8273 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{
8274 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),8293 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
8275 }) catch unreachable;8294 });
82768295
8277 const params = [1]*llvm.Value{operand};8296 const params = [1]*llvm.Value{operand};
8278 const param_types = [1]*llvm.Type{operand_llvm_ty};8297 const llvm_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
8279 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
82808298
8281 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");8299 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
8282 }8300 }
...@@ -8297,17 +8315,15 @@ pub const FuncGen = struct {...@@ -8297,17 +8315,15 @@ pub const FuncGen = struct {
8297 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);8315 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
8298 return self.builder.buildFPExt(operand, dest_llvm_ty, "");8316 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
8299 } else {8317 } else {
8300 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);8318 const operand_llvm_ty = try o.lowerType(operand_ty);
8301 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);8319 const dest_llvm_ty = try o.lowerType(dest_ty);
83028320
8303 var fn_name_buf: [64]u8 = undefined;8321 const fn_name = try o.builder.fmt("__extend{s}f{s}f2", .{
8304 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{
8305 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),8322 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
8306 }) catch unreachable;8323 });
83078324
8308 const params = [1]*llvm.Value{operand};8325 const params = [1]*llvm.Value{operand};
8309 const param_types = [1]*llvm.Type{operand_llvm_ty};8326 const llvm_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
8310 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
83118327
8312 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");8328 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
8313 }8329 }
...@@ -8358,7 +8374,7 @@ pub const FuncGen = struct {...@@ -8358,7 +8374,7 @@ pub const FuncGen = struct {
8358 if (!result_is_ref) {8374 if (!result_is_ref) {
8359 return self.dg.todo("implement bitcast vector to non-ref array", .{});8375 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8360 }8376 }
8361 const array_ptr = self.buildAlloca(llvm_dest_ty, null);8377 const array_ptr = try self.buildAlloca(llvm_dest_ty, null);
8362 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;8378 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
8363 if (bitcast_ok) {8379 if (bitcast_ok) {
8364 const llvm_store = self.builder.buildStore(operand, array_ptr);8380 const llvm_store = self.builder.buildStore(operand, array_ptr);
...@@ -8367,7 +8383,7 @@ pub const FuncGen = struct {...@@ -8367,7 +8383,7 @@ pub const FuncGen = struct {
8367 // If the ABI size of the element type is not evenly divisible by size in bits;8383 // If the ABI size of the element type is not evenly divisible by size in bits;
8368 // a simple bitcast will not work, and we fall back to extractelement.8384 // a simple bitcast will not work, and we fall back to extractelement.
8369 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8385 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
8370 const llvm_u32 = self.context.intType(32);8386 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
8371 const zero = llvm_usize.constNull();8387 const zero = llvm_usize.constNull();
8372 const vector_len = operand_ty.arrayLen(mod);8388 const vector_len = operand_ty.arrayLen(mod);
8373 var i: u64 = 0;8389 var i: u64 = 0;
...@@ -8401,7 +8417,7 @@ pub const FuncGen = struct {...@@ -8401,7 +8417,7 @@ pub const FuncGen = struct {
8401 const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);8417 const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
8402 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);8418 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
8403 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8419 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
8404 const llvm_u32 = self.context.intType(32);8420 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
8405 const zero = llvm_usize.constNull();8421 const zero = llvm_usize.constNull();
8406 const vector_len = operand_ty.arrayLen(mod);8422 const vector_len = operand_ty.arrayLen(mod);
8407 var vector = llvm_vector_ty.getUndef();8423 var vector = llvm_vector_ty.getUndef();
...@@ -8427,7 +8443,7 @@ pub const FuncGen = struct {...@@ -8427,7 +8443,7 @@ pub const FuncGen = struct {
84278443
8428 if (result_is_ref) {8444 if (result_is_ref) {
8429 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));8445 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));
8430 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8446 const result_ptr = try self.buildAlloca(llvm_dest_ty, alignment);
8431 const store_inst = self.builder.buildStore(operand, result_ptr);8447 const store_inst = self.builder.buildStore(operand, result_ptr);
8432 store_inst.setAlignment(alignment);8448 store_inst.setAlignment(alignment);
8433 return result_ptr;8449 return result_ptr;
...@@ -8438,7 +8454,7 @@ pub const FuncGen = struct {...@@ -8438,7 +8454,7 @@ pub const FuncGen = struct {
8438 // but LLVM won't let us bitcast struct values.8454 // but LLVM won't let us bitcast struct values.
8439 // Therefore, we store operand to alloca, then load for result.8455 // Therefore, we store operand to alloca, then load for result.
8440 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));8456 const alignment = @max(operand_ty.abiAlignment(mod), inst_ty.abiAlignment(mod));
8441 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8457 const result_ptr = try self.buildAlloca(llvm_dest_ty, alignment);
8442 const store_inst = self.builder.buildStore(operand, result_ptr);8458 const store_inst = self.builder.buildStore(operand, result_ptr);
8443 store_inst.setAlignment(alignment);8459 store_inst.setAlignment(alignment);
8444 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");8460 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
...@@ -8489,7 +8505,7 @@ pub const FuncGen = struct {...@@ -8489,7 +8505,7 @@ pub const FuncGen = struct {
8489 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);8505 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
8490 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {8506 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
8491 const alignment = inst_ty.abiAlignment(mod);8507 const alignment = inst_ty.abiAlignment(mod);
8492 const alloca = self.buildAlloca(arg_val.typeOf(), alignment);8508 const alloca = try self.buildAlloca(arg_val.typeOf(), alignment);
8493 const store_inst = self.builder.buildStore(arg_val, alloca);8509 const store_inst = self.builder.buildStore(arg_val, alloca);
8494 store_inst.setAlignment(alignment);8510 store_inst.setAlignment(alignment);
8495 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);8511 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);
...@@ -8527,11 +8543,11 @@ pub const FuncGen = struct {...@@ -8527,11 +8543,11 @@ pub const FuncGen = struct {
85278543
8528 /// Use this instead of builder.buildAlloca, because this function makes sure to8544 /// Use this instead of builder.buildAlloca, because this function makes sure to
8529 /// put the alloca instruction at the top of the function!8545 /// put the alloca instruction at the top of the function!
8530 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {8546 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) Allocator.Error!*llvm.Value {
8531 const o = self.dg.object;8547 const o = self.dg.object;
8532 const mod = o.module;8548 const mod = o.module;
8533 const target = mod.getTarget();8549 const target = mod.getTarget();
8534 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, target);8550 return o.buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, target);
8535 }8551 }
85368552
8537 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {8553 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
...@@ -8547,7 +8563,7 @@ pub const FuncGen = struct {...@@ -8547,7 +8563,7 @@ pub const FuncGen = struct {
8547 // Even if safety is disabled, we still emit a memset to undefined since it conveys8563 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8548 // extra information to LLVM. However, safety makes the difference between using8564 // extra information to LLVM. However, safety makes the difference between using
8549 // 0xaa or actual undefined for the fill byte.8565 // 0xaa or actual undefined for the fill byte.
8550 const u8_llvm_ty = self.context.intType(8);8566 const u8_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
8551 const fill_byte = if (safety)8567 const fill_byte = if (safety)
8552 u8_llvm_ty.constInt(0xaa, .False)8568 u8_llvm_ty.constInt(0xaa, .False)
8553 else8569 else
...@@ -8558,7 +8574,7 @@ pub const FuncGen = struct {...@@ -8558,7 +8574,7 @@ pub const FuncGen = struct {
8558 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8574 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8559 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));8575 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
8560 if (safety and mod.comp.bin_file.options.valgrind) {8576 if (safety and mod.comp.bin_file.options.valgrind) {
8561 self.valgrindMarkUndef(dest_ptr, len);8577 try self.valgrindMarkUndef(dest_ptr, len);
8562 }8578 }
8563 return null;8579 return null;
8564 }8580 }
...@@ -8609,7 +8625,7 @@ pub const FuncGen = struct {...@@ -8609,7 +8625,7 @@ pub const FuncGen = struct {
86098625
8610 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8626 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8611 _ = inst;8627 _ = inst;
8612 const llvm_fn = self.getIntrinsic("llvm.trap", &.{});8628 const llvm_fn = try self.getIntrinsic("llvm.trap", &.{});
8613 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .Cold, .Auto, "");8629 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .Cold, .Auto, "");
8614 _ = self.builder.buildUnreachable();8630 _ = self.builder.buildUnreachable();
8615 return null;8631 return null;
...@@ -8617,7 +8633,7 @@ pub const FuncGen = struct {...@@ -8617,7 +8633,7 @@ pub const FuncGen = struct {
86178633
8618 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8634 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8619 _ = inst;8635 _ = inst;
8620 const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});8636 const llvm_fn = try self.getIntrinsic("llvm.debugtrap", &.{});
8621 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, "");8637 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, "");
8622 return null;8638 return null;
8623 }8639 }
...@@ -8633,8 +8649,8 @@ pub const FuncGen = struct {...@@ -8633,8 +8649,8 @@ pub const FuncGen = struct {
8633 return llvm_usize.constNull();8649 return llvm_usize.constNull();
8634 }8650 }
86358651
8636 const llvm_i32 = self.context.intType(32);8652 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
8637 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});8653 const llvm_fn = try self.getIntrinsic("llvm.returnaddress", &.{});
8638 const params = [_]*llvm.Value{llvm_i32.constNull()};8654 const params = [_]*llvm.Value{llvm_i32.constNull()};
8639 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");8655 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
8640 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");8656 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
...@@ -8643,16 +8659,13 @@ pub const FuncGen = struct {...@@ -8643,16 +8659,13 @@ pub const FuncGen = struct {
8643 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8659 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
8644 _ = inst;8660 _ = inst;
8645 const o = self.dg.object;8661 const o = self.dg.object;
8646 const llvm_i32 = self.context.intType(32);
8647 const llvm_fn_name = "llvm.frameaddress.p0";8662 const llvm_fn_name = "llvm.frameaddress.p0";
8648 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {8663 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8649 const llvm_p0i8 = self.context.pointerType(0);8664 const fn_type = try o.builder.fnType(.ptr, &.{.i32}, .normal);
8650 const param_types = [_]*llvm.Type{llvm_i32};8665 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
8651 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);
8652 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
8653 };8666 };
86548667
8655 const params = [_]*llvm.Value{llvm_i32.constNull()};8668 const params = [_]*llvm.Value{Builder.Type.i32.toLlvm(&o.builder).constNull()};
8656 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");8669 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
8657 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8670 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
8658 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");8671 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
...@@ -8841,9 +8854,8 @@ pub const FuncGen = struct {...@@ -8841,9 +8854,8 @@ pub const FuncGen = struct {
8841 const dest_slice = try self.resolveInst(bin_op.lhs);8854 const dest_slice = try self.resolveInst(bin_op.lhs);
8842 const ptr_ty = self.typeOf(bin_op.lhs);8855 const ptr_ty = self.typeOf(bin_op.lhs);
8843 const elem_ty = self.typeOf(bin_op.rhs);8856 const elem_ty = self.typeOf(bin_op.rhs);
8844 const target = mod.getTarget();
8845 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8857 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8846 const u8_llvm_ty = self.context.intType(8);8858 const u8_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
8847 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);8859 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
8848 const is_volatile = ptr_ty.isVolatilePtr(mod);8860 const is_volatile = ptr_ty.isVolatilePtr(mod);
88498861
...@@ -8864,7 +8876,7 @@ pub const FuncGen = struct {...@@ -8864,7 +8876,7 @@ pub const FuncGen = struct {
8864 u8_llvm_ty.constInt(0xaa, .False)8876 u8_llvm_ty.constInt(0xaa, .False)
8865 else8877 else
8866 u8_llvm_ty.getUndef();8878 u8_llvm_ty.getUndef();
8867 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8879 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8868 if (intrinsic_len0_traps) {8880 if (intrinsic_len0_traps) {
8869 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8881 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
8870 } else {8882 } else {
...@@ -8872,7 +8884,7 @@ pub const FuncGen = struct {...@@ -8872,7 +8884,7 @@ pub const FuncGen = struct {
8872 }8884 }
88738885
8874 if (safety and mod.comp.bin_file.options.valgrind) {8886 if (safety and mod.comp.bin_file.options.valgrind) {
8875 self.valgrindMarkUndef(dest_ptr, len);8887 try self.valgrindMarkUndef(dest_ptr, len);
8876 }8888 }
8877 return null;8889 return null;
8878 }8890 }
...@@ -8886,7 +8898,7 @@ pub const FuncGen = struct {...@@ -8886,7 +8898,7 @@ pub const FuncGen = struct {
8886 .ty = Type.u8,8898 .ty = Type.u8,
8887 .val = byte_val,8899 .val = byte_val,
8888 });8900 });
8889 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8901 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
88908902
8891 if (intrinsic_len0_traps) {8903 if (intrinsic_len0_traps) {
8892 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8904 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
...@@ -8903,7 +8915,7 @@ pub const FuncGen = struct {...@@ -8903,7 +8915,7 @@ pub const FuncGen = struct {
8903 if (elem_abi_size == 1) {8915 if (elem_abi_size == 1) {
8904 // In this case we can take advantage of LLVM's intrinsic.8916 // In this case we can take advantage of LLVM's intrinsic.
8905 const fill_byte = try self.bitCast(value, elem_ty, Type.u8);8917 const fill_byte = try self.bitCast(value, elem_ty, Type.u8);
8906 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8918 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
89078919
8908 if (intrinsic_len0_traps) {8920 if (intrinsic_len0_traps) {
8909 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8921 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
...@@ -8934,7 +8946,7 @@ pub const FuncGen = struct {...@@ -8934,7 +8946,7 @@ pub const FuncGen = struct {
8934 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");8946 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");
8935 const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd");8947 const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd");
89368948
8937 const llvm_usize_ty = self.context.intType(target.ptrBitWidth());8949 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
8938 const len = switch (ptr_ty.ptrSize(mod)) {8950 const len = switch (ptr_ty.ptrSize(mod)) {
8939 .Slice => self.builder.buildExtractValue(dest_slice, 1, ""),8951 .Slice => self.builder.buildExtractValue(dest_slice, 1, ""),
8940 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),8952 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),
...@@ -9008,7 +9020,7 @@ pub const FuncGen = struct {...@@ -9008,7 +9020,7 @@ pub const FuncGen = struct {
9008 const src_slice = try self.resolveInst(bin_op.rhs);9020 const src_slice = try self.resolveInst(bin_op.rhs);
9009 const src_ptr_ty = self.typeOf(bin_op.rhs);9021 const src_ptr_ty = self.typeOf(bin_op.rhs);
9010 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);9022 const src_ptr = self.sliceOrArrayPtr(src_slice, src_ptr_ty);
9011 const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);9023 const len = try self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
9012 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);9024 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
9013 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);9025 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
90149026
...@@ -9123,9 +9135,8 @@ pub const FuncGen = struct {...@@ -9123,9 +9135,8 @@ pub const FuncGen = struct {
9123 const operand_ty = self.typeOf(ty_op.operand);9135 const operand_ty = self.typeOf(ty_op.operand);
9124 const operand = try self.resolveInst(ty_op.operand);9136 const operand = try self.resolveInst(ty_op.operand);
91259137
9126 const llvm_i1 = self.context.intType(1);9138 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);
9127 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);9139 const fn_val = try self.getIntrinsic(llvm_fn_name, &.{try o.lowerType(operand_ty)});
9128 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
91299140
9130 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };9141 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
9131 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");9142 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
...@@ -9151,8 +9162,7 @@ pub const FuncGen = struct {...@@ -9151,8 +9162,7 @@ pub const FuncGen = struct {
9151 const operand = try self.resolveInst(ty_op.operand);9162 const operand = try self.resolveInst(ty_op.operand);
91529163
9153 const params = [_]*llvm.Value{operand};9164 const params = [_]*llvm.Value{operand};
9154 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);9165 const fn_val = try self.getIntrinsic(llvm_fn_name, &.{try o.lowerType(operand_ty)});
9155 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
91569166
9157 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");9167 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
9158 const result_ty = self.typeOfIndex(inst);9168 const result_ty = self.typeOfIndex(inst);
...@@ -9178,15 +9188,16 @@ pub const FuncGen = struct {...@@ -9178,15 +9188,16 @@ pub const FuncGen = struct {
9178 assert(bits % 8 == 0);9188 assert(bits % 8 == 0);
91799189
9180 var operand = try self.resolveInst(ty_op.operand);9190 var operand = try self.resolveInst(ty_op.operand);
9181 var operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);9191 var operand_llvm_ty = try o.lowerType(operand_ty);
91829192
9183 if (bits % 16 == 8) {9193 if (bits % 16 == 8) {
9184 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte9194 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
9185 // The truncated result at the end will be the correct bswap9195 // The truncated result at the end will be the correct bswap
9186 const scalar_llvm_ty = self.context.intType(bits + 8);9196 const scalar_ty = try o.builder.intType(@intCast(bits + 8));
9197 const scalar_llvm_ty = scalar_ty.toLlvm(&o.builder);
9187 if (operand_ty.zigTypeTag(mod) == .Vector) {9198 if (operand_ty.zigTypeTag(mod) == .Vector) {
9188 const vec_len = operand_ty.vectorLen(mod);9199 const vec_len = operand_ty.vectorLen(mod);
9189 operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len);9200 operand_llvm_ty = try o.builder.vectorType(.normal, vec_len, scalar_ty);
91909201
9191 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);9202 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
9192 defer self.gpa.free(shifts);9203 defer self.gpa.free(shifts);
...@@ -9196,18 +9207,18 @@ pub const FuncGen = struct {...@@ -9196,18 +9207,18 @@ pub const FuncGen = struct {
9196 }9207 }
9197 const shift_vec = llvm.constVector(shifts.ptr, vec_len);9208 const shift_vec = llvm.constVector(shifts.ptr, vec_len);
91989209
9199 const extended = self.builder.buildZExt(operand, operand_llvm_ty, "");9210 const extended = self.builder.buildZExt(operand, operand_llvm_ty.toLlvm(&o.builder), "");
9200 operand = self.builder.buildShl(extended, shift_vec, "");9211 operand = self.builder.buildShl(extended, shift_vec, "");
9201 } else {9212 } else {
9202 const extended = self.builder.buildZExt(operand, scalar_llvm_ty, "");9213 const extended = self.builder.buildZExt(operand, scalar_llvm_ty, "");
9203 operand = self.builder.buildShl(extended, scalar_llvm_ty.constInt(8, .False), "");9214 operand = self.builder.buildShl(extended, scalar_llvm_ty.constInt(8, .False), "");
9204 operand_llvm_ty = scalar_llvm_ty;9215 operand_llvm_ty = scalar_ty;
9205 }9216 }
9206 bits = bits + 8;9217 bits = bits + 8;
9207 }9218 }
92089219
9209 const params = [_]*llvm.Value{operand};9220 const params = [_]*llvm.Value{operand};
9210 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});9221 const fn_val = try self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
92119222
9212 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");9223 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
92139224
...@@ -9252,7 +9263,7 @@ pub const FuncGen = struct {...@@ -9252,7 +9263,7 @@ pub const FuncGen = struct {
92529263
9253 self.builder.positionBuilderAtEnd(end_block);9264 self.builder.positionBuilderAtEnd(end_block);
92549265
9255 const llvm_type = self.context.intType(1);9266 const llvm_type = Builder.Type.i1.toLlvm(&o.builder);
9256 const incoming_values: [2]*llvm.Value = .{9267 const incoming_values: [2]*llvm.Value = .{
9257 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),9268 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
9258 };9269 };
...@@ -9281,25 +9292,30 @@ pub const FuncGen = struct {...@@ -9281,25 +9292,30 @@ pub const FuncGen = struct {
92819292
9282 // TODO: detect when the type changes and re-emit this function.9293 // TODO: detect when the type changes and re-emit this function.
9283 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);9294 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
9284 if (gop.found_existing) return gop.value_ptr.*;9295 if (gop.found_existing) return gop.value_ptr.toLlvm(&o.builder);
9285 errdefer assert(o.named_enum_map.remove(enum_type.decl));9296 errdefer assert(o.named_enum_map.remove(enum_type.decl));
92869297
9287 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
9288 defer arena_allocator.deinit();
9289 const arena = arena_allocator.allocator();
9290
9291 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);9298 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9292 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)});9299 const llvm_fn_name = try o.builder.fmt("__zig_is_named_enum_value_{}", .{
92939300 fqn.fmt(&mod.intern_pool),
9294 const param_types = [_]*llvm.Type{(try o.lowerType(enum_type.tag_ty.toType())).toLlvm(&o.builder)};9301 });
92959302
9296 const llvm_ret_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder);9303 const fn_type = try o.builder.fnType(.i1, &.{try o.lowerType(
9297 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);9304 enum_type.tag_ty.toType(),
9298 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);9305 )}, .normal);
9306 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder));
9299 fn_val.setLinkage(.Internal);9307 fn_val.setLinkage(.Internal);
9300 fn_val.setFunctionCallConv(.Fast);9308 fn_val.setFunctionCallConv(.Fast);
9301 o.addCommonFnAttributes(fn_val);9309 o.addCommonFnAttributes(fn_val);
9302 gop.value_ptr.* = fn_val;9310
9311 var global = Builder.Global{
9312 .linkage = .internal,
9313 .type = fn_type,
9314 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9315 };
9316 var function = Builder.Function{
9317 .global = @enumFromInt(o.builder.globals.count()),
9318 };
93039319
9304 const prev_block = self.builder.getInsertBlock();9320 const prev_block = self.builder.getInsertBlock();
9305 const prev_debug_location = self.builder.getCurrentDebugLocation2();9321 const prev_debug_location = self.builder.getCurrentDebugLocation2();
...@@ -9330,10 +9346,15 @@ pub const FuncGen = struct {...@@ -9330,10 +9346,15 @@ pub const FuncGen = struct {
9330 switch_instr.addCase(this_tag_int_value, named_block);9346 switch_instr.addCase(this_tag_int_value, named_block);
9331 }9347 }
9332 self.builder.positionBuilderAtEnd(named_block);9348 self.builder.positionBuilderAtEnd(named_block);
9333 _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False));9349 _ = self.builder.buildRet(Builder.Type.i1.toLlvm(&o.builder).constInt(1, .False));
93349350
9335 self.builder.positionBuilderAtEnd(unnamed_block);9351 self.builder.positionBuilderAtEnd(unnamed_block);
9336 _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False));9352 _ = self.builder.buildRet(Builder.Type.i1.toLlvm(&o.builder).constInt(0, .False));
9353
9354 try o.builder.llvm_globals.append(self.gpa, fn_val);
9355 _ = try o.builder.addGlobal(llvm_fn_name, global);
9356 try o.builder.functions.append(self.gpa, function);
9357 gop.value_ptr.* = global.kind.function;
9337 return fn_val;9358 return fn_val;
9338 }9359 }
93399360
...@@ -9361,20 +9382,22 @@ pub const FuncGen = struct {...@@ -9361,20 +9382,22 @@ pub const FuncGen = struct {
9361 const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});9382 const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
93629383
9363 const slice_ty = Type.slice_const_u8_sentinel_0;9384 const slice_ty = Type.slice_const_u8_sentinel_0;
9364 const llvm_ret_ty = (try o.lowerType(slice_ty)).toLlvm(&o.builder);9385 const ret_ty = try o.lowerType(slice_ty);
9386 const llvm_ret_ty = ret_ty.toLlvm(&o.builder);
9365 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);9387 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
9366 const slice_alignment = slice_ty.abiAlignment(mod);9388 const slice_alignment = slice_ty.abiAlignment(mod);
93679389
9368 const param_types = [_]*llvm.Type{(try o.lowerType(enum_type.tag_ty.toType())).toLlvm(&o.builder)};9390 const fn_type = try o.builder.fnType(ret_ty, &.{
93699391 try o.lowerType(enum_type.tag_ty.toType()),
9370 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);9392 }, .normal);
9371 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type);9393 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder));
9372 fn_val.setLinkage(.Internal);9394 fn_val.setLinkage(.Internal);
9373 fn_val.setFunctionCallConv(.Fast);9395 fn_val.setFunctionCallConv(.Fast);
9374 o.addCommonFnAttributes(fn_val);9396 o.addCommonFnAttributes(fn_val);
93759397
9376 var global = Builder.Global{9398 var global = Builder.Global{
9377 .type = try o.builder.fnType(.void, &.{}, .normal),9399 .linkage = .internal,
9400 .type = fn_type,
9378 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },9401 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9379 };9402 };
9380 var function = Builder.Function{9403 var function = Builder.Function{
...@@ -9457,15 +9480,24 @@ pub const FuncGen = struct {...@@ -9457,15 +9480,24 @@ pub const FuncGen = struct {
94579480
9458 // Function signature: fn (anyerror) bool9481 // Function signature: fn (anyerror) bool
94599482
9460 const ret_llvm_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder);9483 const fn_type = try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal);
9461 const anyerror_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder);9484 const llvm_fn = o.llvm_module.addFunction(lt_errors_fn_name, fn_type.toLlvm(&o.builder));
9462 const param_types = [_]*llvm.Type{anyerror_llvm_ty};9485
9486 var global = Builder.Global{
9487 .type = fn_type,
9488 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9489 };
9490 var function = Builder.Function{
9491 .global = @enumFromInt(o.builder.globals.count()),
9492 };
94639493
9464 const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False);
9465 const llvm_fn = o.llvm_module.addFunction(lt_errors_fn_name, fn_type);
9466 llvm_fn.setLinkage(.Internal);9494 llvm_fn.setLinkage(.Internal);
9467 llvm_fn.setFunctionCallConv(.Fast);9495 llvm_fn.setFunctionCallConv(.Fast);
9468 o.addCommonFnAttributes(llvm_fn);9496 o.addCommonFnAttributes(llvm_fn);
9497
9498 try o.builder.llvm_globals.append(self.gpa, llvm_fn);
9499 _ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global);
9500 try o.builder.functions.append(self.gpa, function);
9469 return llvm_fn;9501 return llvm_fn;
9470 }9502 }
94719503
...@@ -9523,7 +9555,7 @@ pub const FuncGen = struct {...@@ -9523,7 +9555,7 @@ pub const FuncGen = struct {
9523 const values = try self.gpa.alloc(*llvm.Value, mask_len);9555 const values = try self.gpa.alloc(*llvm.Value, mask_len);
9524 defer self.gpa.free(values);9556 defer self.gpa.free(values);
95259557
9526 const llvm_i32 = self.context.intType(32);9558 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
95279559
9528 for (values, 0..) |*val, i| {9560 for (values, 0..) |*val, i| {
9529 const elem = try mask.elemValue(mod, i);9561 const elem = try mask.elemValue(mod, i);
...@@ -9565,9 +9597,9 @@ pub const FuncGen = struct {...@@ -9565,9 +9597,9 @@ pub const FuncGen = struct {
9565 const llvm_result_ty = accum_init.typeOf();9597 const llvm_result_ty = accum_init.typeOf();
95669598
9567 // Allocate and initialize our mutable variables9599 // Allocate and initialize our mutable variables
9568 const i_ptr = self.buildAlloca(llvm_usize_ty, null);9600 const i_ptr = try self.buildAlloca(llvm_usize_ty, null);
9569 _ = self.builder.buildStore(llvm_usize_ty.constInt(0, .False), i_ptr);9601 _ = self.builder.buildStore(llvm_usize_ty.constInt(0, .False), i_ptr);
9570 const accum_ptr = self.buildAlloca(llvm_result_ty, null);9602 const accum_ptr = try self.buildAlloca(llvm_result_ty, null);
9571 _ = self.builder.buildStore(accum_init, accum_ptr);9603 _ = self.builder.buildStore(accum_init, accum_ptr);
95729604
9573 // Setup the loop9605 // Setup the loop
...@@ -9656,27 +9688,25 @@ pub const FuncGen = struct {...@@ -9656,27 +9688,25 @@ pub const FuncGen = struct {
96569688
9657 // Reduction could not be performed with intrinsics.9689 // Reduction could not be performed with intrinsics.
9658 // Use a manual loop over a softfloat call instead.9690 // Use a manual loop over a softfloat call instead.
9659 var fn_name_buf: [64]u8 = undefined;
9660 const float_bits = scalar_ty.floatBits(target);9691 const float_bits = scalar_ty.floatBits(target);
9661 const fn_name = switch (reduce.operation) {9692 const fn_name = switch (reduce.operation) {
9662 .Min => std.fmt.bufPrintZ(&fn_name_buf, "{s}fmin{s}", .{9693 .Min => try o.builder.fmt("{s}fmin{s}", .{
9663 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),9694 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
9664 }) catch unreachable,9695 }),
9665 .Max => std.fmt.bufPrintZ(&fn_name_buf, "{s}fmax{s}", .{9696 .Max => try o.builder.fmt("{s}fmax{s}", .{
9666 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),9697 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
9667 }) catch unreachable,9698 }),
9668 .Add => std.fmt.bufPrintZ(&fn_name_buf, "__add{s}f3", .{9699 .Add => try o.builder.fmt("__add{s}f3", .{
9669 compilerRtFloatAbbrev(float_bits),9700 compilerRtFloatAbbrev(float_bits),
9670 }) catch unreachable,9701 }),
9671 .Mul => std.fmt.bufPrintZ(&fn_name_buf, "__mul{s}f3", .{9702 .Mul => try o.builder.fmt("__mul{s}f3", .{
9672 compilerRtFloatAbbrev(float_bits),9703 compilerRtFloatAbbrev(float_bits),
9673 }) catch unreachable,9704 }),
9674 else => unreachable,9705 else => unreachable,
9675 };9706 };
96769707
9677 const param_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);9708 const param_llvm_ty = try o.lowerType(scalar_ty);
9678 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };9709 const libc_fn = try self.getLibcFunction(fn_name, &(.{param_llvm_ty} ** 2), param_llvm_ty);
9679 const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
9680 const init_value = try o.lowerValue(.{9710 const init_value = try o.lowerValue(.{
9681 .ty = scalar_ty,9711 .ty = scalar_ty,
9682 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {9712 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
...@@ -9701,7 +9731,7 @@ pub const FuncGen = struct {...@@ -9701,7 +9731,7 @@ pub const FuncGen = struct {
97019731
9702 switch (result_ty.zigTypeTag(mod)) {9732 switch (result_ty.zigTypeTag(mod)) {
9703 .Vector => {9733 .Vector => {
9704 const llvm_u32 = self.context.intType(32);9734 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
97059735
9706 var vector = llvm_result_ty.getUndef();9736 var vector = llvm_result_ty.getUndef();
9707 for (elements, 0..) |elem, i| {9737 for (elements, 0..) |elem, i| {
...@@ -9716,7 +9746,7 @@ pub const FuncGen = struct {...@@ -9716,7 +9746,7 @@ pub const FuncGen = struct {
9716 const struct_obj = mod.typeToStruct(result_ty).?;9746 const struct_obj = mod.typeToStruct(result_ty).?;
9717 assert(struct_obj.haveLayout());9747 assert(struct_obj.haveLayout());
9718 const big_bits = struct_obj.backing_int_ty.bitSize(mod);9748 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
9719 const int_llvm_ty = self.context.intType(@as(c_uint, @intCast(big_bits)));9749 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);
9720 const fields = struct_obj.fields.values();9750 const fields = struct_obj.fields.values();
9721 comptime assert(Type.packed_struct_layout_version == 2);9751 comptime assert(Type.packed_struct_layout_version == 2);
9722 var running_int: *llvm.Value = int_llvm_ty.constNull();9752 var running_int: *llvm.Value = int_llvm_ty.constNull();
...@@ -9727,7 +9757,7 @@ pub const FuncGen = struct {...@@ -9727,7 +9757,7 @@ pub const FuncGen = struct {
97279757
9728 const non_int_val = try self.resolveInst(elem);9758 const non_int_val = try self.resolveInst(elem);
9729 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));9759 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));
9730 const small_int_ty = self.context.intType(ty_bit_size);9760 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);
9731 const small_int_val = if (field.ty.isPtrAtRuntime(mod))9761 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
9732 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9762 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9733 else9763 else
...@@ -9745,10 +9775,10 @@ pub const FuncGen = struct {...@@ -9745,10 +9775,10 @@ pub const FuncGen = struct {
9745 }9775 }
97469776
9747 if (isByRef(result_ty, mod)) {9777 if (isByRef(result_ty, mod)) {
9748 const llvm_u32 = self.context.intType(32);9778 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
9749 // TODO in debug builds init to undef so that the padding will be 0xaa9779 // TODO in debug builds init to undef so that the padding will be 0xaa
9750 // even if we fully populate the fields.9780 // even if we fully populate the fields.
9751 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9781 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
97529782
9753 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };9783 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };
9754 for (elements, 0..) |elem, i| {9784 for (elements, 0..) |elem, i| {
...@@ -9786,7 +9816,7 @@ pub const FuncGen = struct {...@@ -9786,7 +9816,7 @@ pub const FuncGen = struct {
9786 assert(isByRef(result_ty, mod));9816 assert(isByRef(result_ty, mod));
97879817
9788 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);9818 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
9789 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9819 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
97909820
9791 const array_info = result_ty.arrayInfo(mod);9821 const array_info = result_ty.arrayInfo(mod);
9792 const elem_ptr_ty = try mod.ptrType(.{9822 const elem_ptr_ty = try mod.ptrType(.{
...@@ -9834,11 +9864,11 @@ pub const FuncGen = struct {...@@ -9834,11 +9864,11 @@ pub const FuncGen = struct {
98349864
9835 if (union_obj.layout == .Packed) {9865 if (union_obj.layout == .Packed) {
9836 const big_bits = union_ty.bitSize(mod);9866 const big_bits = union_ty.bitSize(mod);
9837 const int_llvm_ty = self.context.intType(@as(c_uint, @intCast(big_bits)));9867 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);
9838 const field = union_obj.fields.values()[extra.field_index];9868 const field = union_obj.fields.values()[extra.field_index];
9839 const non_int_val = try self.resolveInst(extra.init);9869 const non_int_val = try self.resolveInst(extra.init);
9840 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));9870 const ty_bit_size = @as(u16, @intCast(field.ty.bitSize(mod)));
9841 const small_int_ty = self.context.intType(ty_bit_size);9871 const small_int_ty = (try o.builder.intType(@intCast(ty_bit_size))).toLlvm(&o.builder);
9842 const small_int_val = if (field.ty.isPtrAtRuntime(mod))9872 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
9843 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9873 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9844 else9874 else
...@@ -9866,51 +9896,47 @@ pub const FuncGen = struct {...@@ -9866,51 +9896,47 @@ pub const FuncGen = struct {
9866 // necessarily match the format that we need, depending on which tag is active.9896 // necessarily match the format that we need, depending on which tag is active.
9867 // We must construct the correct unnamed struct type here, in order to then set9897 // We must construct the correct unnamed struct type here, in order to then set
9868 // the fields appropriately.9898 // the fields appropriately.
9869 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);9899 const result_ptr = try self.buildAlloca(union_llvm_ty, layout.abi_align);
9870 const llvm_payload = try self.resolveInst(extra.init);9900 const llvm_payload = try self.resolveInst(extra.init);
9871 assert(union_obj.haveFieldTypes());9901 assert(union_obj.haveFieldTypes());
9872 const field = union_obj.fields.values()[extra.field_index];9902 const field = union_obj.fields.values()[extra.field_index];
9873 const field_llvm_ty = (try o.lowerType(field.ty)).toLlvm(&o.builder);9903 const field_llvm_ty = try o.lowerType(field.ty);
9874 const field_size = field.ty.abiSize(mod);9904 const field_size = field.ty.abiSize(mod);
9875 const field_align = field.normalAlignment(mod);9905 const field_align = field.normalAlignment(mod);
98769906
9877 const llvm_union_ty = t: {9907 const llvm_union_ty = (t: {
9878 const payload = p: {9908 const payload_ty = p: {
9879 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) {9909 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) {
9880 const padding_len = @as(c_uint, @intCast(layout.payload_size));9910 const padding_len = layout.payload_size;
9881 break :p self.context.intType(8).arrayType(padding_len);9911 break :p try o.builder.arrayType(padding_len, .i8);
9882 }9912 }
9883 if (field_size == layout.payload_size) {9913 if (field_size == layout.payload_size) {
9884 break :p field_llvm_ty;9914 break :p field_llvm_ty;
9885 }9915 }
9886 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));9916 const padding_len = layout.payload_size - field_size;
9887 const fields: [2]*llvm.Type = .{9917 break :p try o.builder.structType(.@"packed", &.{
9888 field_llvm_ty, self.context.intType(8).arrayType(padding_len),9918 field_llvm_ty, try o.builder.arrayType(padding_len, .i8),
9889 };9919 });
9890 break :p self.context.structType(&fields, fields.len, .True);
9891 };9920 };
9892 if (layout.tag_size == 0) {9921 if (layout.tag_size == 0) break :t try o.builder.structType(.normal, &.{payload_ty});
9893 const fields: [1]*llvm.Type = .{payload};9922 const tag_ty = try o.lowerType(union_obj.tag_ty);
9894 break :t self.context.structType(&fields, fields.len, .False);9923 var fields: [3]Builder.Type = undefined;
9895 }9924 var fields_len: usize = 2;
9896 const tag_llvm_ty = (try o.lowerType(union_obj.tag_ty)).toLlvm(&o.builder);
9897 var fields: [3]*llvm.Type = undefined;
9898 var fields_len: c_uint = 2;
9899 if (layout.tag_align >= layout.payload_align) {9925 if (layout.tag_align >= layout.payload_align) {
9900 fields = .{ tag_llvm_ty, payload, undefined };9926 fields = .{ tag_ty, payload_ty, undefined };
9901 } else {9927 } else {
9902 fields = .{ payload, tag_llvm_ty, undefined };9928 fields = .{ payload_ty, tag_ty, undefined };
9903 }9929 }
9904 if (layout.padding != 0) {9930 if (layout.padding != 0) {
9905 fields[2] = self.context.intType(8).arrayType(layout.padding);9931 fields[fields_len] = try o.builder.arrayType(layout.padding, .i8);
9906 fields_len = 3;9932 fields_len += 1;
9907 }9933 }
9908 break :t self.context.structType(&fields, fields_len, .False);9934 break :t try o.builder.structType(.normal, fields[0..fields_len]);
9909 };9935 }).toLlvm(&o.builder);
99109936
9911 // Now we follow the layout as expressed above with GEP instructions to set the9937 // Now we follow the layout as expressed above with GEP instructions to set the
9912 // tag and the payload.9938 // tag and the payload.
9913 const index_type = self.context.intType(32);9939 const index_type = Builder.Type.i32.toLlvm(&o.builder);
99149940
9915 const field_ptr_ty = try mod.ptrType(.{9941 const field_ptr_ty = try mod.ptrType(.{
9916 .child = field.ty.toIntern(),9942 .child = field.ty.toIntern(),
...@@ -9996,22 +10022,16 @@ pub const FuncGen = struct {...@@ -9996,22 +10022,16 @@ pub const FuncGen = struct {
9996 .data => {},10022 .data => {},
9997 }10023 }
999810024
9999 const llvm_ptr_u8 = self.context.pointerType(0);
10000 const llvm_u32 = self.context.intType(32);
10001
10002 const llvm_fn_name = "llvm.prefetch.p0";10025 const llvm_fn_name = "llvm.prefetch.p0";
10003 const fn_val = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {10026 const fn_val = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
10004 // declare void @llvm.prefetch(i8*, i32, i32, i32)10027 // declare void @llvm.prefetch(i8*, i32, i32, i32)
10005 const llvm_void = self.context.voidType();10028 const fn_type = try o.builder.fnType(.void, &.{ .ptr, .i32, .i32, .i32 }, .normal);
10006 const param_types = [_]*llvm.Type{10029 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
10007 llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32,
10008 };
10009 const fn_type = llvm.functionType(llvm_void, &param_types, param_types.len, .False);
10010 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
10011 };10030 };
1001210031
10013 const ptr = try self.resolveInst(prefetch.ptr);10032 const ptr = try self.resolveInst(prefetch.ptr);
1001410033
10034 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
10015 const params = [_]*llvm.Value{10035 const params = [_]*llvm.Value{
10016 ptr,10036 ptr,
10017 llvm_u32.constInt(@intFromEnum(prefetch.rw), .False),10037 llvm_u32.constInt(@intFromEnum(prefetch.rw), .False),
...@@ -10033,7 +10053,7 @@ pub const FuncGen = struct {...@@ -10033,7 +10053,7 @@ pub const FuncGen = struct {
10033 }10053 }
1003410054
10035 fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !?*llvm.Value {10055 fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !?*llvm.Value {
10036 const llvm_u32 = self.context.intType(32);10056 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
1003710057
10038 const llvm_fn_name = switch (dimension) {10058 const llvm_fn_name = switch (dimension) {
10039 0 => basename ++ ".x",10059 0 => basename ++ ".x",
...@@ -10043,7 +10063,7 @@ pub const FuncGen = struct {...@@ -10043,7 +10063,7 @@ pub const FuncGen = struct {
10043 };10063 };
1004410064
10045 const args: [0]*llvm.Value = .{};10065 const args: [0]*llvm.Value = .{};
10046 const llvm_fn = self.getIntrinsic(llvm_fn_name, &.{});10066 const llvm_fn = try self.getIntrinsic(llvm_fn_name, &.{});
10047 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");10067 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
10048 }10068 }
1004910069
...@@ -10064,14 +10084,14 @@ pub const FuncGen = struct {...@@ -10064,14 +10084,14 @@ pub const FuncGen = struct {
1006410084
10065 const pl_op = self.air.instructions.items(.data)[inst].pl_op;10085 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
10066 const dimension = pl_op.payload;10086 const dimension = pl_op.payload;
10067 const llvm_u32 = self.context.intType(32);10087 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
10068 if (dimension >= 3) {10088 if (dimension >= 3) {
10069 return llvm_u32.constInt(1, .False);10089 return llvm_u32.constInt(1, .False);
10070 }10090 }
1007110091
10072 // Fetch the dispatch pointer, which points to this structure:10092 // Fetch the dispatch pointer, which points to this structure:
10073 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L291310093 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913
10074 const llvm_fn = self.getIntrinsic("llvm.amdgcn.dispatch.ptr", &.{});10094 const llvm_fn = try self.getIntrinsic("llvm.amdgcn.dispatch.ptr", &.{});
10075 const args: [0]*llvm.Value = .{};10095 const args: [0]*llvm.Value = .{};
10076 const dispatch_ptr = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");10096 const dispatch_ptr = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
10077 dispatch_ptr.setAlignment(4);10097 dispatch_ptr.setAlignment(4);
...@@ -10080,7 +10100,7 @@ pub const FuncGen = struct {...@@ -10080,7 +10100,7 @@ pub const FuncGen = struct {
10080 // Just treat the dispatch pointer as an array of u16 to keep things simple.10100 // Just treat the dispatch pointer as an array of u16 to keep things simple.
10081 const offset = 2 + dimension;10101 const offset = 2 + dimension;
10082 const index = [_]*llvm.Value{llvm_u32.constInt(offset, .False)};10102 const index = [_]*llvm.Value{llvm_u32.constInt(offset, .False)};
10083 const llvm_u16 = self.context.intType(16);10103 const llvm_u16 = Builder.Type.i16.toLlvm(&o.builder);
10084 const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, "");10104 const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, "");
10085 const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, "");10105 const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, "");
10086 workgroup_size.setAlignment(2);10106 workgroup_size.setAlignment(2);
...@@ -10126,7 +10146,7 @@ pub const FuncGen = struct {...@@ -10126,7 +10146,7 @@ pub const FuncGen = struct {
10126 opt_handle: *llvm.Value,10146 opt_handle: *llvm.Value,
10127 is_by_ref: bool,10147 is_by_ref: bool,
10128 ) *llvm.Value {10148 ) *llvm.Value {
10129 const non_null_llvm_ty = self.context.intType(8);10149 const non_null_llvm_ty = Builder.Type.i8.toLlvm(&self.dg.object.builder);
10130 const field = b: {10150 const field = b: {
10131 if (is_by_ref) {10151 if (is_by_ref) {
10132 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");10152 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
...@@ -10180,12 +10200,12 @@ pub const FuncGen = struct {...@@ -10180,12 +10200,12 @@ pub const FuncGen = struct {
10180 ) !?*llvm.Value {10200 ) !?*llvm.Value {
10181 const o = self.dg.object;10201 const o = self.dg.object;
10182 const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder);10202 const optional_llvm_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder);
10183 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");10203 const non_null_field = self.builder.buildZExt(non_null_bit, Builder.Type.i8.toLlvm(&o.builder), "");
10184 const mod = o.module;10204 const mod = o.module;
1018510205
10186 if (isByRef(optional_ty, mod)) {10206 if (isByRef(optional_ty, mod)) {
10187 const payload_alignment = optional_ty.abiAlignment(mod);10207 const payload_alignment = optional_ty.abiAlignment(mod);
10188 const alloca_inst = self.buildAlloca(optional_llvm_ty, payload_alignment);10208 const alloca_inst = try self.buildAlloca(optional_llvm_ty, payload_alignment);
1018910209
10190 {10210 {
10191 const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, "");10211 const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, "");
...@@ -10233,7 +10253,7 @@ pub const FuncGen = struct {...@@ -10233,7 +10253,7 @@ pub const FuncGen = struct {
10233 // Offset our operand pointer by the correct number of bytes.10253 // Offset our operand pointer by the correct number of bytes.
10234 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);10254 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
10235 if (byte_offset == 0) return struct_ptr;10255 if (byte_offset == 0) return struct_ptr;
10236 const byte_llvm_ty = self.context.intType(8);10256 const byte_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
10237 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);10257 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
10238 const llvm_index = llvm_usize.constInt(byte_offset, .False);10258 const llvm_index = llvm_usize.constInt(byte_offset, .False);
10239 const indices: [1]*llvm.Value = .{llvm_index};10259 const indices: [1]*llvm.Value = .{llvm_index};
...@@ -10249,7 +10269,7 @@ pub const FuncGen = struct {...@@ -10249,7 +10269,7 @@ pub const FuncGen = struct {
10249 // end of the struct. Treat our struct pointer as an array of two and get10269 // end of the struct. Treat our struct pointer as an array of two and get
10250 // the index to the element at index `1` to get a pointer to the end of10270 // the index to the element at index `1` to get a pointer to the end of
10251 // the struct.10271 // the struct.
10252 const llvm_u32 = self.context.intType(32);10272 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
10253 const llvm_index = llvm_u32.constInt(@intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);10273 const llvm_index = llvm_u32.constInt(@intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
10254 const indices: [1]*llvm.Value = .{llvm_index};10274 const indices: [1]*llvm.Value = .{llvm_index};
10255 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");10275 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
...@@ -10268,11 +10288,14 @@ pub const FuncGen = struct {...@@ -10268,11 +10288,14 @@ pub const FuncGen = struct {
10268 }10288 }
10269 }10289 }
1027010290
10271 fn getIntrinsic(fg: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {10291 fn getIntrinsic(fg: *FuncGen, name: []const u8, types: []const Builder.Type) Allocator.Error!*llvm.Value {
10292 const o = fg.dg.object;
10272 const id = llvm.lookupIntrinsicID(name.ptr, name.len);10293 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
10273 assert(id != 0);10294 assert(id != 0);
10274 const o = fg.dg.object;10295 const llvm_types = try o.gpa.alloc(*llvm.Type, types.len);
10275 return o.llvm_module.getIntrinsicDeclaration(id, types.ptr, types.len);10296 defer o.gpa.free(llvm_types);
10297 for (llvm_types, types) |*llvm_type, ty| llvm_type.* = ty.toLlvm(&o.builder);
10298 return o.llvm_module.getIntrinsicDeclaration(id, llvm_types.ptr, llvm_types.len);
10276 }10299 }
1027710300
10278 /// Load a by-ref type by constructing a new alloca and performing a memcpy.10301 /// Load a by-ref type by constructing a new alloca and performing a memcpy.
...@@ -10287,8 +10310,8 @@ pub const FuncGen = struct {...@@ -10287,8 +10310,8 @@ pub const FuncGen = struct {
10287 const mod = o.module;10310 const mod = o.module;
10288 const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder);10311 const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder);
10289 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));10312 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
10290 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);10313 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);
10291 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);10314 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
10292 const size_bytes = pointee_type.abiSize(mod);10315 const size_bytes = pointee_type.abiSize(mod);
10293 _ = fg.builder.buildMemCpy(10316 _ = fg.builder.buildMemCpy(
10294 result_ptr,10317 result_ptr,
...@@ -10317,7 +10340,7 @@ pub const FuncGen = struct {...@@ -10317,7 +10340,7 @@ pub const FuncGen = struct {
1031710340
10318 assert(info.flags.vector_index != .runtime);10341 assert(info.flags.vector_index != .runtime);
10319 if (info.flags.vector_index != .none) {10342 if (info.flags.vector_index != .none) {
10320 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);10343 const index_u32 = Builder.Type.i32.toLlvm(&o.builder).constInt(@intFromEnum(info.flags.vector_index), .False);
10321 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);10344 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
10322 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);10345 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
1032310346
...@@ -10339,7 +10362,7 @@ pub const FuncGen = struct {...@@ -10339,7 +10362,7 @@ pub const FuncGen = struct {
10339 return llvm_inst;10362 return llvm_inst;
10340 }10363 }
1034110364
10342 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);10365 const int_elem_ty = (try o.builder.intType(@intCast(info.packed_offset.host_size * 8))).toLlvm(&o.builder);
10343 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");10366 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
10344 containing_int.setAlignment(ptr_alignment);10367 containing_int.setAlignment(ptr_alignment);
10345 containing_int.setVolatile(ptr_volatile);10368 containing_int.setVolatile(ptr_volatile);
...@@ -10351,9 +10374,9 @@ pub const FuncGen = struct {...@@ -10351,9 +10374,9 @@ pub const FuncGen = struct {
1035110374
10352 if (isByRef(elem_ty, mod)) {10375 if (isByRef(elem_ty, mod)) {
10353 const result_align = elem_ty.abiAlignment(mod);10376 const result_align = elem_ty.abiAlignment(mod);
10354 const result_ptr = self.buildAlloca(elem_llvm_ty, result_align);10377 const result_ptr = try self.buildAlloca(elem_llvm_ty, result_align);
1035510378
10356 const same_size_int = self.context.intType(elem_bits);10379 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
10357 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");10380 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
10358 const store_inst = self.builder.buildStore(truncated_int, result_ptr);10381 const store_inst = self.builder.buildStore(truncated_int, result_ptr);
10359 store_inst.setAlignment(result_align);10382 store_inst.setAlignment(result_align);
...@@ -10361,13 +10384,13 @@ pub const FuncGen = struct {...@@ -10361,13 +10384,13 @@ pub const FuncGen = struct {
10361 }10384 }
1036210385
10363 if (elem_ty.zigTypeTag(mod) == .Float or elem_ty.zigTypeTag(mod) == .Vector) {10386 if (elem_ty.zigTypeTag(mod) == .Float or elem_ty.zigTypeTag(mod) == .Vector) {
10364 const same_size_int = self.context.intType(elem_bits);10387 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
10365 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");10388 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
10366 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");10389 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
10367 }10390 }
1036810391
10369 if (elem_ty.isPtrAtRuntime(mod)) {10392 if (elem_ty.isPtrAtRuntime(mod)) {
10370 const same_size_int = self.context.intType(elem_bits);10393 const same_size_int = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
10371 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");10394 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
10372 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");10395 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
10373 }10396 }
...@@ -10394,7 +10417,7 @@ pub const FuncGen = struct {...@@ -10394,7 +10417,7 @@ pub const FuncGen = struct {
1039410417
10395 assert(info.flags.vector_index != .runtime);10418 assert(info.flags.vector_index != .runtime);
10396 if (info.flags.vector_index != .none) {10419 if (info.flags.vector_index != .none) {
10397 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);10420 const index_u32 = Builder.Type.i32.toLlvm(&o.builder).constInt(@intFromEnum(info.flags.vector_index), .False);
10398 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);10421 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
10399 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);10422 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
1040010423
...@@ -10412,7 +10435,7 @@ pub const FuncGen = struct {...@@ -10412,7 +10435,7 @@ pub const FuncGen = struct {
10412 }10435 }
1041310436
10414 if (info.packed_offset.host_size != 0) {10437 if (info.packed_offset.host_size != 0) {
10415 const int_elem_ty = self.context.intType(info.packed_offset.host_size * 8);10438 const int_elem_ty = (try o.builder.intType(@intCast(info.packed_offset.host_size * 8))).toLlvm(&o.builder);
10416 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");10439 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
10417 assert(ordering == .NotAtomic);10440 assert(ordering == .NotAtomic);
10418 containing_int.setAlignment(ptr_alignment);10441 containing_int.setAlignment(ptr_alignment);
...@@ -10422,7 +10445,7 @@ pub const FuncGen = struct {...@@ -10422,7 +10445,7 @@ pub const FuncGen = struct {
10422 const shift_amt = containing_int_ty.constInt(info.packed_offset.bit_offset, .False);10445 const shift_amt = containing_int_ty.constInt(info.packed_offset.bit_offset, .False);
10423 // Convert to equally-sized integer type in order to perform the bit10446 // Convert to equally-sized integer type in order to perform the bit
10424 // operations on the value to store10447 // operations on the value to store
10425 const value_bits_type = self.context.intType(elem_bits);10448 const value_bits_type = (try o.builder.intType(@intCast(elem_bits))).toLlvm(&o.builder);
10426 const value_bits = if (elem_ty.isPtrAtRuntime(mod))10449 const value_bits = if (elem_ty.isPtrAtRuntime(mod))
10427 self.builder.buildPtrToInt(elem, value_bits_type, "")10450 self.builder.buildPtrToInt(elem, value_bits_type, "")
10428 else10451 else
...@@ -10458,20 +10481,19 @@ pub const FuncGen = struct {...@@ -10458,20 +10481,19 @@ pub const FuncGen = struct {
10458 ptr_alignment,10481 ptr_alignment,
10459 elem,10482 elem,
10460 elem_ty.abiAlignment(mod),10483 elem_ty.abiAlignment(mod),
10461 self.context.intType(Type.usize.intInfo(mod).bits).constInt(size_bytes, .False),10484 (try o.lowerType(Type.usize)).toLlvm(&o.builder).constInt(size_bytes, .False),
10462 info.flags.is_volatile,10485 info.flags.is_volatile,
10463 );10486 );
10464 }10487 }
1046510488
10466 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) void {10489 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) Allocator.Error!void {
10467 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;10490 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
10468 const o = fg.dg.object;10491 const o = fg.dg.object;
10469 const target = o.module.getTarget();10492 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
10470 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());
10471 const zero = usize_llvm_ty.constInt(0, .False);10493 const zero = usize_llvm_ty.constInt(0, .False);
10472 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);10494 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);
10473 const ptr_as_usize = fg.builder.buildPtrToInt(ptr, usize_llvm_ty, "");10495 const ptr_as_usize = fg.builder.buildPtrToInt(ptr, usize_llvm_ty, "");
10474 _ = valgrindClientRequest(fg, zero, req, ptr_as_usize, len, zero, zero, zero);10496 _ = try valgrindClientRequest(fg, zero, req, ptr_as_usize, len, zero, zero, zero);
10475 }10497 }
1047610498
10477 fn valgrindClientRequest(10499 fn valgrindClientRequest(
...@@ -10483,18 +10505,19 @@ pub const FuncGen = struct {...@@ -10483,18 +10505,19 @@ pub const FuncGen = struct {
10483 a3: *llvm.Value,10505 a3: *llvm.Value,
10484 a4: *llvm.Value,10506 a4: *llvm.Value,
10485 a5: *llvm.Value,10507 a5: *llvm.Value,
10486 ) *llvm.Value {10508 ) Allocator.Error!*llvm.Value {
10487 const o = fg.dg.object;10509 const o = fg.dg.object;
10488 const mod = o.module;10510 const mod = o.module;
10489 const target = mod.getTarget();10511 const target = mod.getTarget();
10490 if (!target_util.hasValgrindSupport(target)) return default_value;10512 if (!target_util.hasValgrindSupport(target)) return default_value;
1049110513
10492 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());10514 const usize_ty = try o.lowerType(Type.usize);
10515 const usize_llvm_ty = usize_ty.toLlvm(&o.builder);
10493 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));10516 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));
1049410517
10495 const array_llvm_ty = usize_llvm_ty.arrayType(6);10518 const array_llvm_ty = usize_llvm_ty.arrayType(6);
10496 const array_ptr = fg.valgrind_client_request_array orelse a: {10519 const array_ptr = fg.valgrind_client_request_array orelse a: {
10497 const array_ptr = fg.buildAlloca(array_llvm_ty, usize_alignment);10520 const array_ptr = try fg.buildAlloca(array_llvm_ty, usize_alignment);
10498 fg.valgrind_client_request_array = array_ptr;10521 fg.valgrind_client_request_array = array_ptr;
10499 break :a array_ptr;10522 break :a array_ptr;
10500 };10523 };
...@@ -10540,10 +10563,9 @@ pub const FuncGen = struct {...@@ -10540,10 +10563,9 @@ pub const FuncGen = struct {
10540 else => unreachable,10563 else => unreachable,
10541 };10564 };
1054210565
10566 const fn_llvm_ty = (try o.builder.fnType(usize_ty, &(.{usize_ty} ** 2), .normal)).toLlvm(&o.builder);
10543 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");10567 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");
10544 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };10568 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };
10545 const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty };
10546 const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False);
10547 const asm_fn = llvm.getInlineAsm(10569 const asm_fn = llvm.getInlineAsm(
10548 fn_llvm_ty,10570 fn_llvm_ty,
10549 arch_specific.template.ptr,10571 arch_specific.template.ptr,
...@@ -11200,7 +11222,6 @@ const ParamTypeIterator = struct {...@@ -11200,7 +11222,6 @@ const ParamTypeIterator = struct {
11200 llvm_index: u32,11222 llvm_index: u32,
11201 types_len: u32,11223 types_len: u32,
11202 types_buffer: [8]Builder.Type,11224 types_buffer: [8]Builder.Type,
11203 llvm_types_buffer: [8]*llvm.Type,
11204 byval_attr: bool,11225 byval_attr: bool,
1120511226
11206 const Lowering = union(enum) {11227 const Lowering = union(enum) {
...@@ -11298,7 +11319,6 @@ const ParamTypeIterator = struct {...@@ -11298,7 +11319,6 @@ const ParamTypeIterator = struct {
11298 .integer => {11319 .integer => {
11299 it.types_len = 1;11320 it.types_len = 1;
11300 it.types_buffer[0] = .i64;11321 it.types_buffer[0] = .i64;
11301 it.llvm_types_buffer[0] = it.types_buffer[0].toLlvm(&it.object.builder);
11302 return .multiple_llvm_types;11322 return .multiple_llvm_types;
11303 },11323 },
11304 .double_integer => return Lowering{ .i64_array = 2 },11324 .double_integer => return Lowering{ .i64_array = 2 },
...@@ -11408,31 +11428,22 @@ const ParamTypeIterator = struct {...@@ -11408,31 +11428,22 @@ const ParamTypeIterator = struct {
11408 }11428 }
11409 var types_index: u32 = 0;11429 var types_index: u32 = 0;
11410 var types_buffer: [8]Builder.Type = undefined;11430 var types_buffer: [8]Builder.Type = undefined;
11411 var llvm_types_buffer: [8]*llvm.Type = undefined;
11412 for (classes) |class| {11431 for (classes) |class| {
11413 switch (class) {11432 switch (class) {
11414 .integer => {11433 .integer => {
11415 types_buffer[types_index] = .i64;11434 types_buffer[types_index] = .i64;
11416 llvm_types_buffer[types_index] =
11417 types_buffer[types_index].toLlvm(&it.object.builder);
11418 types_index += 1;11435 types_index += 1;
11419 },11436 },
11420 .sse, .sseup => {11437 .sse, .sseup => {
11421 types_buffer[types_index] = .double;11438 types_buffer[types_index] = .double;
11422 llvm_types_buffer[types_index] =
11423 types_buffer[types_index].toLlvm(&it.object.builder);
11424 types_index += 1;11439 types_index += 1;
11425 },11440 },
11426 .float => {11441 .float => {
11427 types_buffer[types_index] = .float;11442 types_buffer[types_index] = .float;
11428 llvm_types_buffer[types_index] =
11429 types_buffer[types_index].toLlvm(&it.object.builder);
11430 types_index += 1;11443 types_index += 1;
11431 },11444 },
11432 .float_combine => {11445 .float_combine => {
11433 types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float);11446 types_buffer[types_index] = try it.object.builder.vectorType(.normal, 2, .float);
11434 llvm_types_buffer[types_index] =
11435 types_buffer[types_index].toLlvm(&it.object.builder);
11436 types_index += 1;11447 types_index += 1;
11437 },11448 },
11438 .x87 => {11449 .x87 => {
...@@ -11457,7 +11468,6 @@ const ParamTypeIterator = struct {...@@ -11457,7 +11468,6 @@ const ParamTypeIterator = struct {
11457 }11468 }
11458 it.types_len = types_index;11469 it.types_len = types_index;
11459 it.types_buffer = types_buffer;11470 it.types_buffer = types_buffer;
11460 it.llvm_types_buffer = llvm_types_buffer;
11461 it.llvm_index += types_index;11471 it.llvm_index += types_index;
11462 it.zig_index += 1;11472 it.zig_index += 1;
11463 return .multiple_llvm_types;11473 return .multiple_llvm_types;
...@@ -11472,7 +11482,6 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp...@@ -11472,7 +11482,6 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp
11472 .llvm_index = 0,11482 .llvm_index = 0,
11473 .types_len = 0,11483 .types_len = 0,
11474 .types_buffer = undefined,11484 .types_buffer = undefined,
11475 .llvm_types_buffer = undefined,
11476 .byval_attr = false,11485 .byval_attr = false,
11477 };11486 };
11478}11487}
...@@ -11740,51 +11749,6 @@ fn compilerRtIntBits(bits: u16) u16 {...@@ -11740,51 +11749,6 @@ fn compilerRtIntBits(bits: u16) u16 {
11740 return bits;11749 return bits;
11741}11750}
1174211751
11743fn buildAllocaInner(
11744 context: *llvm.Context,
11745 builder: *llvm.Builder,
11746 llvm_func: *llvm.Value,
11747 di_scope_non_null: bool,
11748 llvm_ty: *llvm.Type,
11749 maybe_alignment: ?c_uint,
11750 target: std.Target,
11751) *llvm.Value {
11752 const address_space = llvmAllocaAddressSpace(target);
11753
11754 const alloca = blk: {
11755 const prev_block = builder.getInsertBlock();
11756 const prev_debug_location = builder.getCurrentDebugLocation2();
11757 defer {
11758 builder.positionBuilderAtEnd(prev_block);
11759 if (di_scope_non_null) {
11760 builder.setCurrentDebugLocation2(prev_debug_location);
11761 }
11762 }
11763
11764 const entry_block = llvm_func.getFirstBasicBlock().?;
11765 if (entry_block.getFirstInstruction()) |first_inst| {
11766 builder.positionBuilder(entry_block, first_inst);
11767 } else {
11768 builder.positionBuilderAtEnd(entry_block);
11769 }
11770 builder.clearCurrentDebugLocation();
11771
11772 break :blk builder.buildAllocaInAddressSpace(llvm_ty, @intFromEnum(address_space), "");
11773 };
11774
11775 if (maybe_alignment) |alignment| {
11776 alloca.setAlignment(alignment);
11777 }
11778
11779 // The pointer returned from this function should have the generic address space,
11780 // if this isn't the case then cast it to the generic address space.
11781 if (address_space != .default) {
11782 return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), "");
11783 }
11784
11785 return alloca;
11786}
11787
11788fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {11752fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {
11789 return @intFromBool(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));11753 return @intFromBool(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
11790}11754}
src/codegen/llvm/Builder.zig+29-11
...@@ -1320,29 +1320,47 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {...@@ -1320,29 +1320,47 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
1320 try writer.writeByte('\n');1320 try writer.writeByte('\n');
1321 for (self.functions.items) |function| {1321 for (self.functions.items) |function| {
1322 const global = self.globals.entries.get(@intFromEnum(function.global));1322 const global = self.globals.entries.get(@intFromEnum(function.global));
1323 const item = self.type_items.items[@intFromEnum(global.value.type)];
1324 const extra = self.typeExtraDataTrail(Type.Function, item.data);
1325 const params: []const Type =
1326 @ptrCast(self.type_extra.items[extra.end..][0..extra.data.params_len]);
1323 try writer.print(1327 try writer.print(
1324 \\{s} {}{}{}{}{<}@{}{>} {}{}{{1328 \\{s} {}{}{}{}{} @{}(
1325 \\ ret {%}
1326 \\}}
1327 \\
1328 , .{1329 , .{
1329 if (function.body) |_| "define" else "declare",1330 if (function.body) |_| "define" else "declare",
1330 global.value.linkage,1331 global.value.linkage,
1331 global.value.preemption,1332 global.value.preemption,
1332 global.value.visibility,1333 global.value.visibility,
1333 global.value.dll_storage_class,1334 global.value.dll_storage_class,
1334 global.value.type.fmt(self),1335 extra.data.ret.fmt(self),
1335 global.key.fmt(self),1336 global.key.fmt(self),
1336 global.value.type.fmt(self),1337 });
1338 for (params, 0..) |param, index| {
1339 if (index > 0) try writer.writeAll(", ");
1340 try writer.print("{%} %{d}", .{ param.fmt(self), index });
1341 }
1342 switch (item.tag) {
1343 .function => {},
1344 .vararg_function => {
1345 if (params.len > 0) try writer.writeAll(", ");
1346 try writer.writeAll("...");
1347 },
1348 else => unreachable,
1349 }
1350 try writer.print(") {}{}", .{
1337 global.value.unnamed_addr,1351 global.value.unnamed_addr,
1338 global.value.alignment,1352 global.value.alignment,
1339 self.typeExtraData(
1340 Type.Function,
1341 self.type_items.items[@intFromEnum(global.value.type)].data,
1342 ).ret.fmt(self),
1343 });1353 });
1354 if (function.body) |_| try writer.print(
1355 \\{{
1356 \\ ret {%}
1357 \\}}
1358 \\
1359 , .{
1360 extra.data.ret.fmt(self),
1361 });
1362 try writer.writeByte('\n');
1344 }1363 }
1345 try writer.writeByte('\n');
1346}1364}
13471365
1348inline fn useLibLlvm(self: *const Builder) bool {1366inline fn useLibLlvm(self: *const Builder) bool {