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 {
569569 /// Therefore, this table keeps track of the mapping.
570570 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Global.Index),
571571 /// 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),
573573 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
574574 /// the compiler.
575575 /// TODO when InternPool garbage collection is implemented, this map needs
......@@ -1210,7 +1210,7 @@ pub const Object = struct {
12101210 if (isByRef(param_ty, mod)) {
12111211 const alignment = param_ty.abiAlignment(mod);
12121212 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);
12141214 const store_inst = builder.buildStore(param, arg_ptr);
12151215 store_inst.setAlignment(alignment);
12161216 args.appendAssumeCapacity(arg_ptr);
......@@ -1267,12 +1267,12 @@ pub const Object = struct {
12671267
12681268 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
12691269 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);
12711271 const alignment = @max(
12721272 param_ty.abiAlignment(mod),
12731273 o.target_data.abiAlignmentOfType(int_llvm_ty),
12741274 );
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);
12761276 const store_inst = builder.buildStore(param, arg_ptr);
12771277 store_inst.setAlignment(alignment);
12781278
......@@ -1317,13 +1317,13 @@ pub const Object = struct {
13171317 },
13181318 .multiple_llvm_types => {
13191319 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];
13211321 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
13221322 const param_llvm_ty = (try o.lowerType(param_ty)).toLlvm(&o.builder);
13231323 const param_alignment = param_ty.abiAlignment(mod);
1324 const arg_ptr = buildAllocaInner(o.context, 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);
1326 for (field_types, 0..) |_, field_i_usize| {
1324 const arg_ptr = try o.buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1325 const llvm_ty = (try o.builder.structType(.normal, field_types)).toLlvm(&o.builder);
1326 for (0..field_types.len) |field_i_usize| {
13271327 const field_i = @as(c_uint, @intCast(field_i_usize));
13281328 const param = llvm_func.getParam(llvm_arg_i);
13291329 llvm_arg_i += 1;
......@@ -1344,7 +1344,7 @@ pub const Object = struct {
13441344 assert(!it.byval_attr);
13451345 const param = llvm_func.getParam(llvm_arg_i);
13461346 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), "");
13481348 try args.ensureUnusedCapacity(1);
13491349 args.appendAssumeCapacity(casted);
13501350 },
......@@ -1355,7 +1355,7 @@ pub const Object = struct {
13551355 llvm_arg_i += 1;
13561356
13571357 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);
13591359 _ = builder.buildStore(param, arg_ptr);
13601360
13611361 if (isByRef(param_ty, mod)) {
......@@ -1373,7 +1373,7 @@ pub const Object = struct {
13731373 llvm_arg_i += 1;
13741374
13751375 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);
13771377 _ = builder.buildStore(param, arg_ptr);
13781378
13791379 if (isByRef(param_ty, mod)) {
......@@ -3563,7 +3563,7 @@ pub const Object = struct {
35633563 const bigint = int_val.toBigInt(&bigint_space, mod);
35643564
35653565 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
35683568 const unsigned_val = v: {
35693569 if (bigint.limbs.len == 1) {
......@@ -3587,26 +3587,26 @@ pub const Object = struct {
35873587 switch (tv.ty.floatBits(target)) {
35883588 16 => {
35893589 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);
35913591 const int = llvm_i16.constInt(repr, .False);
35923592 return int.constBitCast(llvm_ty);
35933593 },
35943594 32 => {
35953595 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);
35973597 const int = llvm_i32.constInt(repr, .False);
35983598 return int.constBitCast(llvm_ty);
35993599 },
36003600 64 => {
36013601 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);
36033603 const int = llvm_i64.constInt(repr, .False);
36043604 return int.constBitCast(llvm_ty);
36053605 },
36063606 80 => {
36073607 const float = tv.val.toFloat(f80, mod);
36083608 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);
36103610 var x = llvm_i80.constInt(repr.exp, .False);
36113611 x = x.constShl(llvm_i80.constInt(64, .False));
36123612 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));
......@@ -3623,7 +3623,7 @@ pub const Object = struct {
36233623 if (native_endian == .Big) {
36243624 std.mem.swap(u64, &buf[0], &buf[1]);
36253625 }
3626 const int = o.context.intType(128).constIntOfArbitraryPrecision(buf.len, &buf);
3626 const int = Builder.Type.i128.toLlvm(&o.builder).constIntOfArbitraryPrecision(buf.len, &buf);
36273627 return int.constBitCast(llvm_ty);
36283628 },
36293629 else => unreachable,
......@@ -3660,7 +3660,7 @@ pub const Object = struct {
36603660 comptime assert(optional_layout_version == 3);
36613661 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);
36643664 const non_null_bit = switch (opt.val) {
36653665 .none => llvm_i8.constNull(),
36663666 else => llvm_i8.constInt(1, .False),
......@@ -3761,7 +3761,7 @@ pub const Object = struct {
37613761 const elem_ty = vector_type.child.toType();
37623762 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);
37633763 defer gpa.free(llvm_elems);
3764 const llvm_i8 = o.context.intType(8);
3764 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
37653765 for (llvm_elems, 0..) |*llvm_elem, i| {
37663766 llvm_elem.* = switch (aggregate.storage) {
37673767 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),
......@@ -3802,7 +3802,7 @@ pub const Object = struct {
38023802
38033803 const padding_len = offset - prev_offset;
38043804 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)));
38063806 // TODO make this and all other padding elsewhere in debug
38073807 // builds be 0xaa not undef.
38083808 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
......@@ -3824,7 +3824,7 @@ pub const Object = struct {
38243824 offset = std.mem.alignForward(u64, offset, big_align);
38253825 const padding_len = offset - prev_offset;
38263826 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)));
38283828 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
38293829 }
38303830 }
......@@ -3850,7 +3850,7 @@ pub const Object = struct {
38503850 if (struct_obj.layout == .Packed) {
38513851 assert(struct_obj.haveLayout());
38523852 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);
38543854 const fields = struct_obj.fields.values();
38553855 comptime assert(Type.packed_struct_layout_version == 2);
38563856 var running_int: *llvm.Value = int_llvm_ty.constNull();
......@@ -3863,7 +3863,7 @@ pub const Object = struct {
38633863 .val = try tv.val.fieldValue(mod, i),
38643864 });
38653865 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);
38673867 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
38683868 non_int_val.constPtrToInt(small_int_ty)
38693869 else
......@@ -3899,7 +3899,7 @@ pub const Object = struct {
38993899
39003900 const padding_len = offset - prev_offset;
39013901 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)));
39033903 // TODO make this and all other padding elsewhere in debug
39043904 // builds be 0xaa not undef.
39053905 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
......@@ -3921,7 +3921,7 @@ pub const Object = struct {
39213921 offset = std.mem.alignForward(u64, offset, big_align);
39223922 const padding_len = offset - prev_offset;
39233923 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)));
39253925 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());
39263926 }
39273927 }
......@@ -3969,7 +3969,7 @@ pub const Object = struct {
39693969 return llvm_union_ty.constNull();
39703970 const non_int_val = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
39713971 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);
39733973 const small_int_val = if (field_ty.isPtrAtRuntime(mod))
39743974 non_int_val.constPtrToInt(small_int_ty)
39753975 else
......@@ -3985,7 +3985,7 @@ pub const Object = struct {
39853985 const payload = p: {
39863986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
39873987 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();
39893989 }
39903990 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
39913991 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);
......@@ -3995,7 +3995,7 @@ pub const Object = struct {
39953995 }
39963996 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));
39973997 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(),
39993999 };
40004000 break :p o.context.constStruct(&fields, fields.len, .True);
40014001 };
......@@ -4020,7 +4020,7 @@ pub const Object = struct {
40204020 fields = .{ payload, llvm_tag_value, undefined };
40214021 }
40224022 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();
40244024 fields_len = 3;
40254025 }
40264026 if (need_unnamed) {
......@@ -4033,25 +4033,25 @@ pub const Object = struct {
40334033 }
40344034 }
40354035
4036 fn lowerIntAsPtr(o: *Object, val: Value) Error!*llvm.Value {
4036 fn lowerIntAsPtr(o: *Object, val: Value) Allocator.Error!*llvm.Value {
40374037 const mod = o.module;
40384038 switch (mod.intern_pool.indexToKey(val.toIntern())) {
40394039 .undef => return o.context.pointerType(0).getUndef(),
40404040 .int => {
40414041 var bigint_space: Value.BigIntSpace = undefined;
40424042 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);
40444044 return llvm_int.constIntToPtr(o.context.pointerType(0));
40454045 },
40464046 else => unreachable,
40474047 }
40484048 }
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 {
40514051 const mod = o.module;
40524052 const int_info = ty.intInfo(mod);
40534053 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
40564056 const unsigned_val = v: {
40574057 if (bigint.limbs.len == 1) {
......@@ -4090,7 +4090,6 @@ pub const Object = struct {
40904090
40914091 fn lowerParentPtr(o: *Object, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value {
40924092 const mod = o.module;
4093 const target = mod.getTarget();
40944093 return switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
40954094 .decl => |decl| o.lowerParentPtrDecl(ptr_val, decl),
40964095 .mut_decl => |mut_decl| o.lowerParentPtrDecl(ptr_val, mut_decl.decl),
......@@ -4107,7 +4106,7 @@ pub const Object = struct {
41074106 }
41084107
41094108 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);
41114110 const indices: [2]*llvm.Value = .{
41124111 llvm_u32.constInt(0, .False),
41134112 llvm_u32.constInt(payload_offset, .False),
......@@ -4128,7 +4127,7 @@ pub const Object = struct {
41284127 return parent_llvm_ptr;
41294128 }
41304129
4131 const llvm_u32 = o.context.intType(32);
4130 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
41324131 const indices: [2]*llvm.Value = .{
41334132 llvm_u32.constInt(0, .False),
41344133 llvm_u32.constInt(0, .False),
......@@ -4153,7 +4152,7 @@ pub const Object = struct {
41534152 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
41544153
41554154 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);
41574156 switch (parent_ty.zigTypeTag(mod)) {
41584157 .Union => {
41594158 if (parent_ty.containerLayout(mod) == .Packed) {
......@@ -4180,7 +4179,7 @@ pub const Object = struct {
41804179 .Struct => {
41814180 if (parent_ty.containerLayout(mod) == .Packed) {
41824181 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);
41844183 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
41854184 // count bits of fields before this one
41864185 const prev_bits = b: {
......@@ -4438,6 +4437,51 @@ pub const Object = struct {
44384437 llvm_fn.addByValAttr(llvm_arg_i, param_llvm_ty.toLlvm(&o.builder));
44394438 }
44404439 }
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 }
44414485};
44424486
44434487pub const DeclGen = struct {
......@@ -4934,7 +4978,7 @@ pub const FuncGen = struct {
49344978
49354979 const ret_ptr = if (!sret) null else blk: {
49364980 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));
49384982 try llvm_args.append(ret_ptr);
49394983 break :blk ret_ptr;
49404984 };
......@@ -4971,7 +5015,7 @@ pub const FuncGen = struct {
49715015 } else {
49725016 const alignment = param_ty.abiAlignment(mod);
49735017 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);
49755019 const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);
49765020 store_inst.setAlignment(alignment);
49775021 try llvm_args.append(arg_ptr);
......@@ -4984,7 +5028,7 @@ pub const FuncGen = struct {
49845028
49855029 const alignment = param_ty.abiAlignment(mod);
49865030 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);
49885032 if (isByRef(param_ty, mod)) {
49895033 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
49905034 load_inst.setAlignment(alignment);
......@@ -5003,7 +5047,7 @@ pub const FuncGen = struct {
50035047 const param_ty = self.typeOf(arg);
50045048 const llvm_arg = try self.resolveInst(arg);
50055049 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
50085052 if (isByRef(param_ty, mod)) {
50095053 const alignment = param_ty.abiAlignment(mod);
......@@ -5017,7 +5061,7 @@ pub const FuncGen = struct {
50175061 param_ty.abiAlignment(mod),
50185062 o.target_data.abiAlignmentOfType(int_llvm_ty),
50195063 );
5020 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
5064 const int_ptr = try self.buildAlloca(int_llvm_ty, alignment);
50215065 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
50225066 store_inst.setAlignment(alignment);
50235067 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
......@@ -5037,22 +5081,22 @@ pub const FuncGen = struct {
50375081 .multiple_llvm_types => {
50385082 const arg = args[it.zig_index - 1];
50395083 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];
50415085 const llvm_arg = try self.resolveInst(arg);
50425086 const is_by_ref = isByRef(param_ty, mod);
50435087 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);
50455089 const store_inst = self.builder.buildStore(llvm_arg, p);
50465090 store_inst.setAlignment(param_ty.abiAlignment(mod));
50475091 break :p p;
50485092 };
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);
50515095 try llvm_args.ensureUnusedCapacity(it.types_len);
50525096 for (llvm_types, 0..) |field_ty, i_usize| {
50535097 const i = @as(c_uint, @intCast(i_usize));
50545098 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, "");
50565100 load_inst.setAlignment(target.ptrBitWidth() / 8);
50575101 llvm_args.appendAssumeCapacity(load_inst);
50585102 }
......@@ -5060,7 +5104,7 @@ pub const FuncGen = struct {
50605104 .as_u16 => {
50615105 const arg = args[it.zig_index - 1];
50625106 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), "");
50645108 try llvm_args.append(casted);
50655109 },
50665110 .float_array => |count| {
......@@ -5068,7 +5112,7 @@ pub const FuncGen = struct {
50685112 const arg_ty = self.typeOf(arg);
50695113 var llvm_arg = try self.resolveInst(arg);
50705114 if (!isByRef(arg_ty, mod)) {
5071 const p = self.buildAlloca(llvm_arg.typeOf(), null);
5115 const p = try self.buildAlloca(llvm_arg.typeOf(), null);
50725116 const store_inst = self.builder.buildStore(llvm_arg, p);
50735117 store_inst.setAlignment(arg_ty.abiAlignment(mod));
50745118 llvm_arg = store_inst;
......@@ -5088,13 +5132,13 @@ pub const FuncGen = struct {
50885132 const arg_ty = self.typeOf(arg);
50895133 var llvm_arg = try self.resolveInst(arg);
50905134 if (!isByRef(arg_ty, mod)) {
5091 const p = self.buildAlloca(llvm_arg.typeOf(), null);
5135 const p = try self.buildAlloca(llvm_arg.typeOf(), null);
50925136 const store_inst = self.builder.buildStore(llvm_arg, p);
50935137 store_inst.setAlignment(arg_ty.abiAlignment(mod));
50945138 llvm_arg = store_inst;
50955139 }
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);
50985142 const alignment = arg_ty.abiAlignment(mod);
50995143 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
51005144 load_inst.setAlignment(alignment);
......@@ -5198,7 +5242,7 @@ pub const FuncGen = struct {
51985242 // a different LLVM type than the usual one. We solve this here at the callsite
51995243 // by using our canonical type, then loading it if necessary.
52005244 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);
52025246 const store_inst = self.builder.buildStore(call, rp);
52035247 store_inst.setAlignment(alignment);
52045248 if (isByRef(return_type, mod)) {
......@@ -5214,7 +5258,7 @@ pub const FuncGen = struct {
52145258 // our by-ref status disagrees with sret so we must allocate, store,
52155259 // and return the allocation pointer.
52165260 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);
52185262 const store_inst = self.builder.buildStore(call, rp);
52195263 store_inst.setAlignment(alignment);
52205264 return rp;
......@@ -5235,7 +5279,7 @@ pub const FuncGen = struct {
52355279 });
52365280 const null_opt_addr_global = try o.getNullOptAddr();
52375281 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);
52395283 // example:
52405284 // call fastcc void @test2.panic(
52415285 // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
......@@ -5310,7 +5354,7 @@ pub const FuncGen = struct {
53105354 return null;
53115355 }
53125356
5313 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5357 const rp = try self.buildAlloca(llvm_ret_ty, alignment);
53145358 const store_inst = self.builder.buildStore(operand, rp);
53155359 store_inst.setAlignment(alignment);
53165360 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");
......@@ -5369,16 +5413,12 @@ pub const FuncGen = struct {
53695413 const mod = o.module;
53705414
53715415 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
53745418 const llvm_fn_name = "llvm.va_copy";
53755419 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5376 const param_types = [_]*llvm.Type{
5377 self.context.pointerType(0),
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);
5420 const fn_type = try o.builder.fnType(.void, &.{ .ptr, .ptr }, .normal);
5421 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
53825422 };
53835423
53845424 const args: [2]*llvm.Value = .{ dest_list, src_list };
......@@ -5400,9 +5440,8 @@ pub const FuncGen = struct {
54005440
54015441 const llvm_fn_name = "llvm.va_end";
54025442 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5403 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5404 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5405 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
5443 const fn_type = try o.builder.fnType(.void, &.{.ptr}, .normal);
5444 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
54065445 };
54075446 const args: [1]*llvm.Value = .{list};
54085447 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
......@@ -5416,13 +5455,12 @@ pub const FuncGen = struct {
54165455 const llvm_va_list_ty = (try o.lowerType(va_list_ty)).toLlvm(&o.builder);
54175456
54185457 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
54215460 const llvm_fn_name = "llvm.va_start";
54225461 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5423 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5424 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5425 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type);
5462 const fn_type = try o.builder.fnType(.void, &.{.ptr}, .normal);
5463 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
54265464 };
54275465 const args: [1]*llvm.Value = .{list};
54285466 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
......@@ -5495,7 +5533,7 @@ pub const FuncGen = struct {
54955533 const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
54965534 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
54975535 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);
54995537 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");
55005538 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");
55015539 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, llvm_i2.constInt(1, .False), "");
......@@ -5529,7 +5567,7 @@ pub const FuncGen = struct {
55295567 mixed_block,
55305568 both_pl_block_end,
55315569 };
5532 const llvm_i1 = self.context.intType(1);
5570 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);
55335571 const llvm_i1_0 = llvm_i1.constInt(0, .False);
55345572 const llvm_i1_1 = llvm_i1.constInt(1, .False);
55355573 const incoming_values: [3]*llvm.Value = .{
......@@ -5767,13 +5805,11 @@ pub const FuncGen = struct {
57675805
57685806 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
57695807 const o = self.dg.object;
5770 const mod = o.module;
57715808 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
57725809 const cond = try self.resolveInst(pl_op.operand);
57735810 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
57745811 const else_block = self.context.appendBasicBlock(self.llvm_func, "Else");
5775 const target = mod.getTarget();
5776 const llvm_usize = self.context.intType(target.ptrBitWidth());
5812 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
57775813 const cond_int = if (cond.typeOf().getTypeKind() == .Pointer)
57785814 self.builder.buildPtrToInt(cond, llvm_usize, "")
57795815 else
......@@ -5874,48 +5910,46 @@ pub const FuncGen = struct {
58745910
58755911 const dest_ty = self.typeOfIndex(inst);
58765912 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);
58785914 const target = mod.getTarget();
58795915
58805916 if (intrinsicsAllowed(dest_scalar_ty, target)) {
58815917 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), "");
58835919 } else {
5884 return self.builder.buildUIToFP(operand, dest_llvm_ty, "");
5920 return self.builder.buildUIToFP(operand, dest_llvm_ty.toLlvm(&o.builder), "");
58855921 }
58865922 }
58875923
58885924 const operand_bits = @as(u16, @intCast(operand_scalar_ty.bitSize(mod)));
58895925 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);
58915927 var extended = e: {
58925928 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), "");
58945930 } else {
5895 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty, "");
5931 break :e self.builder.buildZExtOrBitCast(operand, rt_int_ty.toLlvm(&o.builder), "");
58965932 }
58975933 };
58985934 const dest_bits = dest_scalar_ty.floatBits(target);
58995935 const compiler_rt_operand_abbrev = compilerRtIntAbbrev(rt_int_bits);
59005936 const compiler_rt_dest_abbrev = compilerRtFloatAbbrev(dest_bits);
59015937 const sign_prefix = if (operand_scalar_ty.isSignedInt(mod)) "" else "un";
5902 var fn_name_buf: [64]u8 = undefined;
5903 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__float{s}{s}i{s}f", .{
5938 const fn_name = try o.builder.fmt("__float{s}{s}i{s}f", .{
59045939 sign_prefix,
59055940 compiler_rt_operand_abbrev,
59065941 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;
59105945 if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) {
59115946 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
59125947 // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have.
5913 const v2i64 = self.context.intType(64).vectorType(2);
5914 extended = self.builder.buildBitCast(extended, v2i64, "");
5915 param_types = [1]*llvm.Type{v2i64};
5948 param_type = try o.builder.vectorType(.normal, 2, .i64);
5949 extended = self.builder.buildBitCast(extended, param_type.toLlvm(&o.builder), "");
59165950 }
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);
59195953 const params = [1]*llvm.Value{extended};
59205954
59215955 return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
......@@ -5935,23 +5969,23 @@ pub const FuncGen = struct {
59355969
59365970 const dest_ty = self.typeOfIndex(inst);
59375971 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
59405974 if (intrinsicsAllowed(operand_scalar_ty, target)) {
59415975 // TODO set fast math flag
59425976 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), "");
59445978 } else {
5945 return self.builder.buildFPToUI(operand, dest_llvm_ty, "");
5979 return self.builder.buildFPToUI(operand, dest_llvm_ty.toLlvm(&o.builder), "");
59465980 }
59475981 }
59485982
5949 const rt_int_bits = compilerRtIntBits(@as(u16, @intCast(dest_scalar_ty.bitSize(mod))));
5950 const ret_ty = self.context.intType(rt_int_bits);
5983 const rt_int_bits = compilerRtIntBits(@intCast(dest_scalar_ty.bitSize(mod)));
5984 const ret_ty = try o.builder.intType(rt_int_bits);
59515985 const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: {
59525986 // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard
59535987 // 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);
59555989 } else ret_ty;
59565990
59575991 const operand_bits = operand_scalar_ty.floatBits(target);
......@@ -5960,22 +5994,20 @@ pub const FuncGen = struct {
59605994 const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits);
59615995 const sign_prefix = if (dest_scalar_ty.isSignedInt(mod)) "" else "uns";
59625996
5963 var fn_name_buf: [64]u8 = undefined;
5964 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{
5997 const fn_name = try o.builder.fmt("__fix{s}{s}f{s}i", .{
59655998 sign_prefix,
59665999 compiler_rt_operand_abbrev,
59676000 compiler_rt_dest_abbrev,
5968 }) catch unreachable;
6001 });
59696002
5970 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
5971 const param_types = [1]*llvm.Type{operand_llvm_ty};
5972 const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
6003 const operand_llvm_ty = try o.lowerType(operand_ty);
6004 const libc_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, libc_ret_ty);
59736005 const params = [1]*llvm.Value{operand};
59746006
59756007 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, "");
5978 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");
6009 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty.toLlvm(&o.builder), "");
6010 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty.toLlvm(&o.builder), "");
59796011 return result;
59806012 }
59816013
......@@ -5989,11 +6021,10 @@ pub const FuncGen = struct {
59896021 }
59906022 }
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 {
59936025 const o = fg.dg.object;
59946026 const mod = o.module;
5995 const target = mod.getTarget();
5996 const llvm_usize_ty = fg.context.intType(target.ptrBitWidth());
6027 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
59976028 switch (ty.ptrSize(mod)) {
59986029 .Slice => {
59996030 const len = fg.builder.buildExtractValue(ptr, 1, "");
......@@ -6080,7 +6111,7 @@ pub const FuncGen = struct {
60806111 const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder);
60816112 const elem_ty = array_ty.childType(mod);
60826113 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 };
60846115 if (isByRef(elem_ty, mod)) {
60856116 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, "");
60866117 if (canElideLoad(self, body_tail))
......@@ -6128,7 +6159,7 @@ pub const FuncGen = struct {
61286159 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
61296160 const ptr = if (ptr_ty.isSinglePointer(mod)) ptr: {
61306161 // 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 };
61326163 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
61336164 } else ptr: {
61346165 const indices: [1]*llvm.Value = .{rhs};
......@@ -6162,7 +6193,7 @@ pub const FuncGen = struct {
61626193 const llvm_elem_ty = (try o.lowerPtrElemTy(elem_ty)).toLlvm(&o.builder);
61636194 if (ptr_ty.isSinglePointer(mod)) {
61646195 // 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 };
61666197 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
61676198 } else {
61686199 const indices: [1]*llvm.Value = .{rhs};
......@@ -6216,12 +6247,12 @@ pub const FuncGen = struct {
62166247 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
62176248 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
62186249 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);
62206251 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
62216252 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
62226253 } else if (field_ty.isPtrAtRuntime(mod)) {
62236254 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);
62256256 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
62266257 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
62276258 }
......@@ -6238,12 +6269,12 @@ pub const FuncGen = struct {
62386269 const elem_llvm_ty = (try o.lowerType(field_ty)).toLlvm(&o.builder);
62396270 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
62406271 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);
62426273 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
62436274 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
62446275 } else if (field_ty.isPtrAtRuntime(mod)) {
62456276 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);
62476278 const truncated_int = self.builder.buildTrunc(containing_int, same_size_int, "");
62486279 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
62496280 }
......@@ -6302,7 +6333,6 @@ pub const FuncGen = struct {
63026333
63036334 const field_ptr = try self.resolveInst(extra.field_ptr);
63046335
6305 const target = o.module.getTarget();
63066336 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
63076337 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
63086338
......@@ -6310,7 +6340,7 @@ pub const FuncGen = struct {
63106340 if (field_offset == 0) {
63116341 return field_ptr;
63126342 }
6313 const llvm_usize_ty = self.context.intType(target.ptrBitWidth());
6343 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
63146344
63156345 const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize_ty, "");
63166346 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 {
64936523 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
64946524 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
64956525 const alignment = operand_ty.abiAlignment(mod);
6496 const alloca = self.buildAlloca(operand.typeOf(), alignment);
6526 const alloca = try self.buildAlloca(operand.typeOf(), alignment);
64976527 const store_inst = self.builder.buildStore(operand, alloca);
64986528 store_inst.setAlignment(alignment);
64996529 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);
......@@ -6532,7 +6562,7 @@ pub const FuncGen = struct {
65326562 // The exact number of return / parameter values depends on which output values
65336563 // are passed by reference as indirect outputs (determined below).
65346564 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);
65366566 const llvm_ret_indirect = try arena.alloc(bool, max_return_count);
65376567
65386568 const max_param_count = inputs.len + outputs.len;
......@@ -6571,7 +6601,7 @@ pub const FuncGen = struct {
65716601 const output_inst = try self.resolveInst(output);
65726602 const output_ty = self.typeOf(output);
65736603 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
65766606 if (llvm_ret_indirect[i]) {
65776607 // Pass the result by reference as an indirect output (e.g. "=*m")
......@@ -6579,7 +6609,7 @@ pub const FuncGen = struct {
65796609
65806610 llvm_param_values[llvm_param_i] = output_inst;
65816611 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);
65836613 llvm_param_i += 1;
65846614 } else {
65856615 // Pass the result directly (e.g. "=r")
......@@ -6588,7 +6618,7 @@ pub const FuncGen = struct {
65886618 }
65896619 } else {
65906620 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);
65926622 llvm_ret_i += 1;
65936623 }
65946624
......@@ -6623,9 +6653,9 @@ pub const FuncGen = struct {
66236653
66246654 const arg_llvm_value = try self.resolveInst(input);
66256655 const arg_ty = self.typeOf(input);
6626 var llvm_elem_ty: ?*llvm.Type = null;
6656 var llvm_elem_ty: Builder.Type = .none;
66276657 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);
66296659 if (constraintAllowsMemory(constraint)) {
66306660 llvm_param_values[llvm_param_i] = arg_llvm_value;
66316661 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
......@@ -6643,7 +6673,7 @@ pub const FuncGen = struct {
66436673 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
66446674 } else {
66456675 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);
66476677 const store_inst = self.builder.buildStore(arg_llvm_value, arg_ptr);
66486678 store_inst.setAlignment(alignment);
66496679 llvm_param_values[llvm_param_i] = arg_ptr;
......@@ -6671,8 +6701,10 @@ pub const FuncGen = struct {
66716701 // In the case of indirect inputs, LLVM requires the callsite to have
66726702 // an elementtype(<ty>) attribute.
66736703 if (constraint[0] == '*') {
6674 llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse
6675 (try o.lowerPtrElemTy(arg_ty.childType(mod))).toLlvm(&o.builder);
6704 llvm_param_attrs[llvm_param_i] = (if (llvm_elem_ty != .none)
6705 llvm_elem_ty
6706 else
6707 try o.lowerPtrElemTy(arg_ty.childType(mod))).toLlvm(&o.builder);
66766708 } else {
66776709 llvm_param_attrs[llvm_param_i] = null;
66786710 }
......@@ -6792,17 +6824,13 @@ pub const FuncGen = struct {
67926824 }
67936825
67946826 const ret_llvm_ty = switch (return_count) {
6795 0 => self.context.voidType(),
6827 0 => .void,
67966828 1 => llvm_ret_types[0],
6797 else => self.context.structType(
6798 llvm_ret_types.ptr,
6799 @as(c_uint, @intCast(return_count)),
6800 .False,
6801 ),
6829 else => try o.builder.structType(.normal, llvm_ret_types),
68026830 };
68036831
68046832 const llvm_fn_ty = llvm.functionType(
6805 ret_llvm_ty,
6833 ret_llvm_ty.toLlvm(&o.builder),
68066834 llvm_param_types.ptr,
68076835 @as(c_uint, @intCast(param_count)),
68086836 .False,
......@@ -6891,7 +6919,7 @@ pub const FuncGen = struct {
68916919 self.builder.buildLoad(optional_llvm_ty, operand, "")
68926920 else
68936921 operand;
6894 const llvm_i8 = self.context.intType(8);
6922 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
68956923 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
68966924 }
68976925
......@@ -6921,7 +6949,7 @@ pub const FuncGen = struct {
69216949 const zero = err_set_ty.constNull();
69226950
69236951 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);
69256953 switch (op) {
69266954 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
69276955 .NE => return llvm_i1.constInt(0, .False), // 0 != 0
......@@ -6979,7 +7007,7 @@ pub const FuncGen = struct {
69797007 const operand = try self.resolveInst(ty_op.operand);
69807008 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
69817009 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);
69837011 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
69847012 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
69857013 _ = self.builder.buildStore(non_null_bit, operand);
......@@ -7165,7 +7193,7 @@ pub const FuncGen = struct {
71657193 const mod = o.module;
71667194 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
71677195 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);
71697197 comptime assert(optional_layout_version == 3);
71707198 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
71717199 const operand = try self.resolveInst(ty_op.operand);
......@@ -7175,7 +7203,7 @@ pub const FuncGen = struct {
71757203 }
71767204 const llvm_optional_ty = (try o.lowerType(optional_ty)).toLlvm(&o.builder);
71777205 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));
71797207 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
71807208 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
71817209 try self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic);
......@@ -7203,7 +7231,7 @@ pub const FuncGen = struct {
72037231 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
72047232 const error_offset = errUnionErrorOffset(payload_ty, mod);
72057233 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));
72077235 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
72087236 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
72097237 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
......@@ -7232,7 +7260,7 @@ pub const FuncGen = struct {
72327260 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
72337261 const error_offset = errUnionErrorOffset(payload_ty, mod);
72347262 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));
72367264 const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, "");
72377265 const store_inst = self.builder.buildStore(operand, err_ptr);
72387266 store_inst.setAlignment(Type.anyerror.abiAlignment(mod));
......@@ -7252,8 +7280,8 @@ pub const FuncGen = struct {
72527280 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
72537281 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
72547282 const index = pl_op.payload;
7255 const llvm_u32 = self.context.intType(32);
7256 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});
7283 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7284 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.size", &.{.i32});
72577285 const args: [1]*llvm.Value = .{llvm_u32.constInt(index, .False)};
72587286 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
72597287 }
......@@ -7262,8 +7290,8 @@ pub const FuncGen = struct {
72627290 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
72637291 const index = pl_op.payload;
72647292 const operand = try self.resolveInst(pl_op.operand);
7265 const llvm_u32 = self.context.intType(32);
7266 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow", &.{llvm_u32});
7293 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7294 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.grow", &.{.i32});
72677295 const args: [2]*llvm.Value = .{
72687296 llvm_u32.constInt(index, .False),
72697297 operand,
......@@ -7371,8 +7399,7 @@ pub const FuncGen = struct {
73717399 true => signed_intrinsic,
73727400 false => unsigned_intrinsic,
73737401 };
7374 const llvm_inst_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder);
7375 const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty});
7402 const llvm_fn = try fg.getIntrinsic(intrinsic_name, &.{try o.lowerType(inst_ty)});
73767403 const result_struct = fg.builder.buildCall(
73777404 llvm_fn.globalGetValueType(),
73787405 llvm_fn,
......@@ -7658,7 +7685,7 @@ pub const FuncGen = struct {
76587685 switch (ptr_ty.ptrSize(mod)) {
76597686 .One => {
76607687 // 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 };
76627689 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
76637690 },
76647691 .C, .Many => {
......@@ -7687,7 +7714,7 @@ pub const FuncGen = struct {
76877714 .One => {
76887715 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
76897716 const indices: [2]*llvm.Value = .{
7690 self.context.intType(32).constNull(), negative_offset,
7717 Builder.Type.i32.toLlvm(&o.builder).constNull(), negative_offset,
76917718 };
76927719 return self.builder.buildInBoundsGEP(llvm_elem_ty, ptr, &indices, indices.len, "");
76937720 },
......@@ -7723,10 +7750,9 @@ pub const FuncGen = struct {
77237750
77247751 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);
77277753 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)});
77307756 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
77317757
77327758 const result = self.builder.buildExtractValue(result_struct, 0, "");
......@@ -7737,7 +7763,7 @@ pub const FuncGen = struct {
77377763
77387764 if (isByRef(dest_ty, mod)) {
77397765 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);
77417767 {
77427768 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
77437769 const store_inst = self.builder.buildStore(result, field_ptr);
......@@ -7764,7 +7790,7 @@ pub const FuncGen = struct {
77647790 vector_len: usize,
77657791 ) !*llvm.Value {
77667792 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);
77687794 assert(args_len <= 3);
77697795
77707796 var i: usize = 0;
......@@ -7784,23 +7810,21 @@ pub const FuncGen = struct {
77847810
77857811 fn getLibcFunction(
77867812 self: *FuncGen,
7787 fn_name: [:0]const u8,
7788 param_types: []const *llvm.Type,
7789 return_type: *llvm.Type,
7813 fn_name: Builder.String,
7814 param_types: []const Builder.Type,
7815 return_type: Builder.Type,
77907816 ) Allocator.Error!*llvm.Value {
77917817 const o = self.dg.object;
7792 return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {
7793 const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);
7818 const slice = fn_name.toSlice(&o.builder).?;
7819 return o.llvm_module.getNamedFunction(slice) orelse b: {
7820 const alias = o.llvm_module.getNamedGlobalAlias(slice.ptr, slice.len);
77947821 break :b if (alias) |a| a.getAliasee() else null;
77957822 } orelse b: {
7796 const name = try o.builder.string(fn_name);
7797
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);
7823 const fn_type = try o.builder.fnType(return_type, param_types, .normal);
7824 const f = o.llvm_module.addFunction(slice, fn_type.toLlvm(&o.builder));
78017825
78027826 var global = Builder.Global{
7803 .type = try o.builder.fnType(.void, &.{}, .normal),
7827 .type = fn_type,
78047828 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
78057829 };
78067830 var function = Builder.Function{
......@@ -7808,9 +7832,8 @@ pub const FuncGen = struct {
78087832 };
78097833
78107834 try o.builder.llvm_globals.append(self.gpa, f);
7811 _ = try o.builder.addGlobal(name, global);
7835 _ = try o.builder.addGlobal(fn_name, global);
78127836 try o.builder.functions.append(self.gpa, function);
7813
78147837 break :b f;
78157838 };
78167839 }
......@@ -7827,7 +7850,7 @@ pub const FuncGen = struct {
78277850 const mod = o.module;
78287851 const target = o.module.getTarget();
78297852 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
78327855 if (intrinsicsAllowed(scalar_ty, target)) {
78337856 const llvm_predicate: llvm.RealPredicate = switch (pred) {
......@@ -7843,7 +7866,6 @@ pub const FuncGen = struct {
78437866
78447867 const float_bits = scalar_ty.floatBits(target);
78457868 const compiler_rt_float_abbrev = compilerRtFloatAbbrev(float_bits);
7846 var fn_name_buf: [64]u8 = undefined;
78477869 const fn_base_name = switch (pred) {
78487870 .neq => "ne",
78497871 .eq => "eq",
......@@ -7852,15 +7874,15 @@ pub const FuncGen = struct {
78527874 .gt => "gt",
78537875 .gte => "ge",
78547876 };
7855 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__{s}{s}f2", .{
7856 fn_base_name, compiler_rt_float_abbrev,
7857 }) catch unreachable;
7877 const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });
78587878
7859 const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty };
7860 const llvm_i32 = self.context.intType(32);
7861 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..], llvm_i32);
7879 const libc_fn = try self.getLibcFunction(
7880 fn_name,
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);
78647886 const int_pred: llvm.IntPredicate = switch (pred) {
78657887 .eq => .EQ,
78667888 .neq => .NE,
......@@ -7872,7 +7894,7 @@ pub const FuncGen = struct {
78727894
78737895 if (ty.zigTypeTag(mod) == .Vector) {
78747896 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
78777899 var result = vector_result_ty.getUndef();
78787900 result = try self.buildElementwiseCall(libc_fn, &params, result, vec_len);
......@@ -7913,7 +7935,7 @@ pub const FuncGen = struct {
79137935
79147936 const FloatOpStrat = union(enum) {
79157937 intrinsic: []const u8,
7916 libc: [:0]const u8,
7938 libc: Builder.String,
79177939 };
79187940
79197941 /// Creates a floating point operation (add, sub, fma, sqrt, exp, etc.)
......@@ -7930,11 +7952,10 @@ pub const FuncGen = struct {
79307952 const mod = o.module;
79317953 const target = mod.getTarget();
79327954 const scalar_ty = ty.scalarType(mod);
7933 const llvm_ty = (try o.lowerType(ty)).toLlvm(&o.builder);
7934 const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
7955 const llvm_ty = try o.lowerType(ty);
7956 const scalar_llvm_ty = try o.lowerType(scalar_ty);
79357957
79367958 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
7937 var fn_name_buf: [64]u8 = undefined;
79387959 const strat: FloatOpStrat = if (intrinsics_allowed) switch (op) {
79397960 // Some operations are dedicated LLVM instructions, not available as intrinsics
79407961 .neg => return self.builder.buildFNeg(params[0], ""),
......@@ -7952,7 +7973,7 @@ pub const FuncGen = struct {
79527973 .neg => {
79537974 // In this case we can generate a softfloat negation by XORing the
79547975 // 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);
79567977 const one = int_llvm_ty.constInt(1, .False);
79577978 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
79587979 const sign_mask = one.constShl(shift_amt);
......@@ -7965,13 +7986,11 @@ pub const FuncGen = struct {
79657986 const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, "");
79667987 break :blk self.builder.buildXor(bitcasted_operand, sign_mask, "");
79677988 };
7968 return self.builder.buildBitCast(result, llvm_ty, "");
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,
7989 return self.builder.buildBitCast(result, llvm_ty.toLlvm(&o.builder), "");
79747990 },
7991 .add, .sub, .div, .mul => .{ .libc = try o.builder.fmt("__{s}{s}f3", .{
7992 @tagName(op), compilerRtFloatAbbrev(float_bits),
7993 }) },
79757994 .ceil,
79767995 .cos,
79777996 .exp,
......@@ -7990,21 +8009,22 @@ pub const FuncGen = struct {
79908009 .sqrt,
79918010 .tan,
79928011 .trunc,
7993 => FloatOpStrat{
7994 .libc = std.fmt.bufPrintZ(&fn_name_buf, "{s}{s}{s}", .{
7995 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
7996 }) catch unreachable,
7997 },
8012 => .{ .libc = try o.builder.fmt("{s}{s}{s}", .{
8013 libcFloatPrefix(float_bits), @tagName(op), libcFloatSuffix(float_bits),
8014 }) },
79988015 };
79998016 };
80008017
80018018 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}),
80038020 .libc => |fn_name| b: {
8004 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };
8005 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);
8021 const libc_fn = try self.getLibcFunction(
8022 fn_name,
8023 ([1]Builder.Type{scalar_llvm_ty} ** 3)[0..params.len],
8024 scalar_llvm_ty,
8025 );
80068026 if (ty.zigTypeTag(mod) == .Vector) {
8007 const result = llvm_ty.getUndef();
8027 const result = llvm_ty.toLlvm(&o.builder).getUndef();
80088028 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod));
80098029 }
80108030
......@@ -8061,7 +8081,7 @@ pub const FuncGen = struct {
80618081
80628082 if (isByRef(dest_ty, mod)) {
80638083 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);
80658085 {
80668086 const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, "");
80678087 const store_inst = self.builder.buildStore(result, field_ptr);
......@@ -8266,17 +8286,15 @@ pub const FuncGen = struct {
82668286 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
82678287 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
82688288 } else {
8269 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
8270 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
8289 const operand_llvm_ty = try o.lowerType(operand_ty);
8290 const dest_llvm_ty = try o.lowerType(dest_ty);
82718291
8272 var fn_name_buf: [64]u8 = undefined;
8273 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{
8292 const fn_name = try o.builder.fmt("__trunc{s}f{s}f2", .{
82748293 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
8275 }) catch unreachable;
8294 });
82768295
82778296 const params = [1]*llvm.Value{operand};
8278 const param_types = [1]*llvm.Type{operand_llvm_ty};
8279 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
8297 const llvm_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
82808298
82818299 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
82828300 }
......@@ -8297,17 +8315,15 @@ pub const FuncGen = struct {
82978315 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
82988316 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
82998317 } else {
8300 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
8301 const dest_llvm_ty = (try o.lowerType(dest_ty)).toLlvm(&o.builder);
8318 const operand_llvm_ty = try o.lowerType(operand_ty);
8319 const dest_llvm_ty = try o.lowerType(dest_ty);
83028320
8303 var fn_name_buf: [64]u8 = undefined;
8304 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{
8321 const fn_name = try o.builder.fmt("__extend{s}f{s}f2", .{
83058322 compilerRtFloatAbbrev(src_bits), compilerRtFloatAbbrev(dest_bits),
8306 }) catch unreachable;
8323 });
83078324
83088325 const params = [1]*llvm.Value{operand};
8309 const param_types = [1]*llvm.Type{operand_llvm_ty};
8310 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
8326 const llvm_fn = try self.getLibcFunction(fn_name, &.{operand_llvm_ty}, dest_llvm_ty);
83118327
83128328 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
83138329 }
......@@ -8358,7 +8374,7 @@ pub const FuncGen = struct {
83588374 if (!result_is_ref) {
83598375 return self.dg.todo("implement bitcast vector to non-ref array", .{});
83608376 }
8361 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
8377 const array_ptr = try self.buildAlloca(llvm_dest_ty, null);
83628378 const bitcast_ok = elem_ty.bitSize(mod) == elem_ty.abiSize(mod) * 8;
83638379 if (bitcast_ok) {
83648380 const llvm_store = self.builder.buildStore(operand, array_ptr);
......@@ -8367,7 +8383,7 @@ pub const FuncGen = struct {
83678383 // If the ABI size of the element type is not evenly divisible by size in bits;
83688384 // a simple bitcast will not work, and we fall back to extractelement.
83698385 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);
83718387 const zero = llvm_usize.constNull();
83728388 const vector_len = operand_ty.arrayLen(mod);
83738389 var i: u64 = 0;
......@@ -8401,7 +8417,7 @@ pub const FuncGen = struct {
84018417 const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
84028418 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
84038419 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);
84058421 const zero = llvm_usize.constNull();
84068422 const vector_len = operand_ty.arrayLen(mod);
84078423 var vector = llvm_vector_ty.getUndef();
......@@ -8427,7 +8443,7 @@ pub const FuncGen = struct {
84278443
84288444 if (result_is_ref) {
84298445 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);
84318447 const store_inst = self.builder.buildStore(operand, result_ptr);
84328448 store_inst.setAlignment(alignment);
84338449 return result_ptr;
......@@ -8438,7 +8454,7 @@ pub const FuncGen = struct {
84388454 // but LLVM won't let us bitcast struct values.
84398455 // Therefore, we store operand to alloca, then load for result.
84408456 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);
84428458 const store_inst = self.builder.buildStore(operand, result_ptr);
84438459 store_inst.setAlignment(alignment);
84448460 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
......@@ -8489,7 +8505,7 @@ pub const FuncGen = struct {
84898505 _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block);
84908506 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
84918507 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);
84938509 const store_inst = self.builder.buildStore(arg_val, alloca);
84948510 store_inst.setAlignment(alignment);
84958511 _ = dib.insertDeclareAtEnd(alloca, di_local_var, debug_loc, insert_block);
......@@ -8527,11 +8543,11 @@ pub const FuncGen = struct {
85278543
85288544 /// Use this instead of builder.buildAlloca, because this function makes sure to
85298545 /// 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 {
85318547 const o = self.dg.object;
85328548 const mod = o.module;
85338549 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);
85358551 }
85368552
85378553 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value {
......@@ -8547,7 +8563,7 @@ pub const FuncGen = struct {
85478563 // Even if safety is disabled, we still emit a memset to undefined since it conveys
85488564 // extra information to LLVM. However, safety makes the difference between using
85498565 // 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);
85518567 const fill_byte = if (safety)
85528568 u8_llvm_ty.constInt(0xaa, .False)
85538569 else
......@@ -8558,7 +8574,7 @@ pub const FuncGen = struct {
85588574 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
85598575 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
85608576 if (safety and mod.comp.bin_file.options.valgrind) {
8561 self.valgrindMarkUndef(dest_ptr, len);
8577 try self.valgrindMarkUndef(dest_ptr, len);
85628578 }
85638579 return null;
85648580 }
......@@ -8609,7 +8625,7 @@ pub const FuncGen = struct {
86098625
86108626 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
86118627 _ = inst;
8612 const llvm_fn = self.getIntrinsic("llvm.trap", &.{});
8628 const llvm_fn = try self.getIntrinsic("llvm.trap", &.{});
86138629 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .Cold, .Auto, "");
86148630 _ = self.builder.buildUnreachable();
86158631 return null;
......@@ -8617,7 +8633,7 @@ pub const FuncGen = struct {
86178633
86188634 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
86198635 _ = inst;
8620 const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});
8636 const llvm_fn = try self.getIntrinsic("llvm.debugtrap", &.{});
86218637 _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, "");
86228638 return null;
86238639 }
......@@ -8633,8 +8649,8 @@ pub const FuncGen = struct {
86338649 return llvm_usize.constNull();
86348650 }
86358651
8636 const llvm_i32 = self.context.intType(32);
8637 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
8652 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
8653 const llvm_fn = try self.getIntrinsic("llvm.returnaddress", &.{});
86388654 const params = [_]*llvm.Value{llvm_i32.constNull()};
86398655 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
86408656 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
......@@ -8643,16 +8659,13 @@ pub const FuncGen = struct {
86438659 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
86448660 _ = inst;
86458661 const o = self.dg.object;
8646 const llvm_i32 = self.context.intType(32);
86478662 const llvm_fn_name = "llvm.frameaddress.p0";
86488663 const llvm_fn = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8649 const llvm_p0i8 = self.context.pointerType(0);
8650 const param_types = [_]*llvm.Type{llvm_i32};
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);
8664 const fn_type = try o.builder.fnType(.ptr, &.{.i32}, .normal);
8665 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
86538666 };
86548667
8655 const params = [_]*llvm.Value{llvm_i32.constNull()};
8668 const params = [_]*llvm.Value{Builder.Type.i32.toLlvm(&o.builder).constNull()};
86568669 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
86578670 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
86588671 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
......@@ -8841,9 +8854,8 @@ pub const FuncGen = struct {
88418854 const dest_slice = try self.resolveInst(bin_op.lhs);
88428855 const ptr_ty = self.typeOf(bin_op.lhs);
88438856 const elem_ty = self.typeOf(bin_op.rhs);
8844 const target = mod.getTarget();
88458857 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);
88478859 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
88488860 const is_volatile = ptr_ty.isVolatilePtr(mod);
88498861
......@@ -8864,7 +8876,7 @@ pub const FuncGen = struct {
88648876 u8_llvm_ty.constInt(0xaa, .False)
88658877 else
88668878 u8_llvm_ty.getUndef();
8867 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8879 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
88688880 if (intrinsic_len0_traps) {
88698881 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
88708882 } else {
......@@ -8872,7 +8884,7 @@ pub const FuncGen = struct {
88728884 }
88738885
88748886 if (safety and mod.comp.bin_file.options.valgrind) {
8875 self.valgrindMarkUndef(dest_ptr, len);
8887 try self.valgrindMarkUndef(dest_ptr, len);
88768888 }
88778889 return null;
88788890 }
......@@ -8886,7 +8898,7 @@ pub const FuncGen = struct {
88868898 .ty = Type.u8,
88878899 .val = byte_val,
88888900 });
8889 const len = self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8901 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
88908902
88918903 if (intrinsic_len0_traps) {
88928904 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
......@@ -8903,7 +8915,7 @@ pub const FuncGen = struct {
89038915 if (elem_abi_size == 1) {
89048916 // In this case we can take advantage of LLVM's intrinsic.
89058917 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
89088920 if (intrinsic_len0_traps) {
89098921 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
......@@ -8934,7 +8946,7 @@ pub const FuncGen = struct {
89348946 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");
89358947 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);
89388950 const len = switch (ptr_ty.ptrSize(mod)) {
89398951 .Slice => self.builder.buildExtractValue(dest_slice, 1, ""),
89408952 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),
......@@ -9008,7 +9020,7 @@ pub const FuncGen = struct {
90089020 const src_slice = try self.resolveInst(bin_op.rhs);
90099021 const src_ptr_ty = self.typeOf(bin_op.rhs);
90109022 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);
90129024 const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
90139025 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);
90149026
......@@ -9123,9 +9135,8 @@ pub const FuncGen = struct {
91239135 const operand_ty = self.typeOf(ty_op.operand);
91249136 const operand = try self.resolveInst(ty_op.operand);
91259137
9126 const llvm_i1 = self.context.intType(1);
9127 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
9128 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
9138 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);
9139 const fn_val = try self.getIntrinsic(llvm_fn_name, &.{try o.lowerType(operand_ty)});
91299140
91309141 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
91319142 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 {
91519162 const operand = try self.resolveInst(ty_op.operand);
91529163
91539164 const params = [_]*llvm.Value{operand};
9154 const operand_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
9155 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
9165 const fn_val = try self.getIntrinsic(llvm_fn_name, &.{try o.lowerType(operand_ty)});
91569166
91579167 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
91589168 const result_ty = self.typeOfIndex(inst);
......@@ -9178,15 +9188,16 @@ pub const FuncGen = struct {
91789188 assert(bits % 8 == 0);
91799189
91809190 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
91839193 if (bits % 16 == 8) {
91849194 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
91859195 // 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);
91879198 if (operand_ty.zigTypeTag(mod) == .Vector) {
91889199 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
91919202 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
91929203 defer self.gpa.free(shifts);
......@@ -9196,18 +9207,18 @@ pub const FuncGen = struct {
91969207 }
91979208 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), "");
92009211 operand = self.builder.buildShl(extended, shift_vec, "");
92019212 } else {
92029213 const extended = self.builder.buildZExt(operand, scalar_llvm_ty, "");
92039214 operand = self.builder.buildShl(extended, scalar_llvm_ty.constInt(8, .False), "");
9204 operand_llvm_ty = scalar_llvm_ty;
9215 operand_llvm_ty = scalar_ty;
92059216 }
92069217 bits = bits + 8;
92079218 }
92089219
92099220 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
92129223 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 {
92529263
92539264 self.builder.positionBuilderAtEnd(end_block);
92549265
9255 const llvm_type = self.context.intType(1);
9266 const llvm_type = Builder.Type.i1.toLlvm(&o.builder);
92569267 const incoming_values: [2]*llvm.Value = .{
92579268 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
92589269 };
......@@ -9281,25 +9292,30 @@ pub const FuncGen = struct {
92819292
92829293 // TODO: detect when the type changes and re-emit this function.
92839294 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);
92859296 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
92919298 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)});
9293
9294 const param_types = [_]*llvm.Type{(try o.lowerType(enum_type.tag_ty.toType())).toLlvm(&o.builder)};
9299 const llvm_fn_name = try o.builder.fmt("__zig_is_named_enum_value_{}", .{
9300 fqn.fmt(&mod.intern_pool),
9301 });
92959302
9296 const llvm_ret_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder);
9297 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
9298 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);
9303 const fn_type = try o.builder.fnType(.i1, &.{try o.lowerType(
9304 enum_type.tag_ty.toType(),
9305 )}, .normal);
9306 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder));
92999307 fn_val.setLinkage(.Internal);
93009308 fn_val.setFunctionCallConv(.Fast);
93019309 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
93049320 const prev_block = self.builder.getInsertBlock();
93059321 const prev_debug_location = self.builder.getCurrentDebugLocation2();
......@@ -9330,10 +9346,15 @@ pub const FuncGen = struct {
93309346 switch_instr.addCase(this_tag_int_value, named_block);
93319347 }
93329348 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
93359351 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;
93379358 return fn_val;
93389359 }
93399360
......@@ -9361,20 +9382,22 @@ pub const FuncGen = struct {
93619382 const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
93629383
93639384 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);
93659387 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
93669388 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)};
9369
9370 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
9371 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type);
9390 const fn_type = try o.builder.fnType(ret_ty, &.{
9391 try o.lowerType(enum_type.tag_ty.toType()),
9392 }, .normal);
9393 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type.toLlvm(&o.builder));
93729394 fn_val.setLinkage(.Internal);
93739395 fn_val.setFunctionCallConv(.Fast);
93749396 o.addCommonFnAttributes(fn_val);
93759397
93769398 var global = Builder.Global{
9377 .type = try o.builder.fnType(.void, &.{}, .normal),
9399 .linkage = .internal,
9400 .type = fn_type,
93789401 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
93799402 };
93809403 var function = Builder.Function{
......@@ -9457,15 +9480,24 @@ pub const FuncGen = struct {
94579480
94589481 // Function signature: fn (anyerror) bool
94599482
9460 const ret_llvm_ty = (try o.lowerType(Type.bool)).toLlvm(&o.builder);
9461 const anyerror_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder);
9462 const param_types = [_]*llvm.Type{anyerror_llvm_ty};
9483 const fn_type = try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal);
9484 const llvm_fn = o.llvm_module.addFunction(lt_errors_fn_name, fn_type.toLlvm(&o.builder));
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);
94669494 llvm_fn.setLinkage(.Internal);
94679495 llvm_fn.setFunctionCallConv(.Fast);
94689496 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);
94699501 return llvm_fn;
94709502 }
94719503
......@@ -9523,7 +9555,7 @@ pub const FuncGen = struct {
95239555 const values = try self.gpa.alloc(*llvm.Value, mask_len);
95249556 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
95289560 for (values, 0..) |*val, i| {
95299561 const elem = try mask.elemValue(mod, i);
......@@ -9565,9 +9597,9 @@ pub const FuncGen = struct {
95659597 const llvm_result_ty = accum_init.typeOf();
95669598
95679599 // 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);
95699601 _ = 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);
95719603 _ = self.builder.buildStore(accum_init, accum_ptr);
95729604
95739605 // Setup the loop
......@@ -9656,27 +9688,25 @@ pub const FuncGen = struct {
96569688
96579689 // Reduction could not be performed with intrinsics.
96589690 // Use a manual loop over a softfloat call instead.
9659 var fn_name_buf: [64]u8 = undefined;
96609691 const float_bits = scalar_ty.floatBits(target);
96619692 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}", .{
96639694 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
9664 }) catch unreachable,
9665 .Max => std.fmt.bufPrintZ(&fn_name_buf, "{s}fmax{s}", .{
9695 }),
9696 .Max => try o.builder.fmt("{s}fmax{s}", .{
96669697 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
9667 }) catch unreachable,
9668 .Add => std.fmt.bufPrintZ(&fn_name_buf, "__add{s}f3", .{
9698 }),
9699 .Add => try o.builder.fmt("__add{s}f3", .{
96699700 compilerRtFloatAbbrev(float_bits),
9670 }) catch unreachable,
9671 .Mul => std.fmt.bufPrintZ(&fn_name_buf, "__mul{s}f3", .{
9701 }),
9702 .Mul => try o.builder.fmt("__mul{s}f3", .{
96729703 compilerRtFloatAbbrev(float_bits),
9673 }) catch unreachable,
9704 }),
96749705 else => unreachable,
96759706 };
96769707
9677 const param_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
9678 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };
9679 const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
9708 const param_llvm_ty = try o.lowerType(scalar_ty);
9709 const libc_fn = try self.getLibcFunction(fn_name, &(.{param_llvm_ty} ** 2), param_llvm_ty);
96809710 const init_value = try o.lowerValue(.{
96819711 .ty = scalar_ty,
96829712 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
......@@ -9701,7 +9731,7 @@ pub const FuncGen = struct {
97019731
97029732 switch (result_ty.zigTypeTag(mod)) {
97039733 .Vector => {
9704 const llvm_u32 = self.context.intType(32);
9734 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
97059735
97069736 var vector = llvm_result_ty.getUndef();
97079737 for (elements, 0..) |elem, i| {
......@@ -9716,7 +9746,7 @@ pub const FuncGen = struct {
97169746 const struct_obj = mod.typeToStruct(result_ty).?;
97179747 assert(struct_obj.haveLayout());
97189748 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);
97209750 const fields = struct_obj.fields.values();
97219751 comptime assert(Type.packed_struct_layout_version == 2);
97229752 var running_int: *llvm.Value = int_llvm_ty.constNull();
......@@ -9727,7 +9757,7 @@ pub const FuncGen = struct {
97279757
97289758 const non_int_val = try self.resolveInst(elem);
97299759 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);
97319761 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
97329762 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
97339763 else
......@@ -9745,10 +9775,10 @@ pub const FuncGen = struct {
97459775 }
97469776
97479777 if (isByRef(result_ty, mod)) {
9748 const llvm_u32 = self.context.intType(32);
9778 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
97499779 // TODO in debug builds init to undef so that the padding will be 0xaa
97509780 // 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
97539783 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };
97549784 for (elements, 0..) |elem, i| {
......@@ -9786,7 +9816,7 @@ pub const FuncGen = struct {
97869816 assert(isByRef(result_ty, mod));
97879817
97889818 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
97919821 const array_info = result_ty.arrayInfo(mod);
97929822 const elem_ptr_ty = try mod.ptrType(.{
......@@ -9834,11 +9864,11 @@ pub const FuncGen = struct {
98349864
98359865 if (union_obj.layout == .Packed) {
98369866 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);
98389868 const field = union_obj.fields.values()[extra.field_index];
98399869 const non_int_val = try self.resolveInst(extra.init);
98409870 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);
98429872 const small_int_val = if (field.ty.isPtrAtRuntime(mod))
98439873 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
98449874 else
......@@ -9866,51 +9896,47 @@ pub const FuncGen = struct {
98669896 // necessarily match the format that we need, depending on which tag is active.
98679897 // We must construct the correct unnamed struct type here, in order to then set
98689898 // 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);
98709900 const llvm_payload = try self.resolveInst(extra.init);
98719901 assert(union_obj.haveFieldTypes());
98729902 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);
98749904 const field_size = field.ty.abiSize(mod);
98759905 const field_align = field.normalAlignment(mod);
98769906
9877 const llvm_union_ty = t: {
9878 const payload = p: {
9907 const llvm_union_ty = (t: {
9908 const payload_ty = p: {
98799909 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) {
9880 const padding_len = @as(c_uint, @intCast(layout.payload_size));
9881 break :p self.context.intType(8).arrayType(padding_len);
9910 const padding_len = layout.payload_size;
9911 break :p try o.builder.arrayType(padding_len, .i8);
98829912 }
98839913 if (field_size == layout.payload_size) {
98849914 break :p field_llvm_ty;
98859915 }
9886 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));
9887 const fields: [2]*llvm.Type = .{
9888 field_llvm_ty, self.context.intType(8).arrayType(padding_len),
9889 };
9890 break :p self.context.structType(&fields, fields.len, .True);
9916 const padding_len = layout.payload_size - field_size;
9917 break :p try o.builder.structType(.@"packed", &.{
9918 field_llvm_ty, try o.builder.arrayType(padding_len, .i8),
9919 });
98919920 };
9892 if (layout.tag_size == 0) {
9893 const fields: [1]*llvm.Type = .{payload};
9894 break :t self.context.structType(&fields, fields.len, .False);
9895 }
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;
9921 if (layout.tag_size == 0) break :t try o.builder.structType(.normal, &.{payload_ty});
9922 const tag_ty = try o.lowerType(union_obj.tag_ty);
9923 var fields: [3]Builder.Type = undefined;
9924 var fields_len: usize = 2;
98999925 if (layout.tag_align >= layout.payload_align) {
9900 fields = .{ tag_llvm_ty, payload, undefined };
9926 fields = .{ tag_ty, payload_ty, undefined };
99019927 } else {
9902 fields = .{ payload, tag_llvm_ty, undefined };
9928 fields = .{ payload_ty, tag_ty, undefined };
99039929 }
99049930 if (layout.padding != 0) {
9905 fields[2] = self.context.intType(8).arrayType(layout.padding);
9906 fields_len = 3;
9931 fields[fields_len] = try o.builder.arrayType(layout.padding, .i8);
9932 fields_len += 1;
99079933 }
9908 break :t self.context.structType(&fields, fields_len, .False);
9909 };
9934 break :t try o.builder.structType(.normal, fields[0..fields_len]);
9935 }).toLlvm(&o.builder);
99109936
99119937 // Now we follow the layout as expressed above with GEP instructions to set the
99129938 // tag and the payload.
9913 const index_type = self.context.intType(32);
9939 const index_type = Builder.Type.i32.toLlvm(&o.builder);
99149940
99159941 const field_ptr_ty = try mod.ptrType(.{
99169942 .child = field.ty.toIntern(),
......@@ -9996,22 +10022,16 @@ pub const FuncGen = struct {
999610022 .data => {},
999710023 }
999810024
9999 const llvm_ptr_u8 = self.context.pointerType(0);
10000 const llvm_u32 = self.context.intType(32);
10001
1000210025 const llvm_fn_name = "llvm.prefetch.p0";
1000310026 const fn_val = o.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
1000410027 // declare void @llvm.prefetch(i8*, i32, i32, i32)
10005 const llvm_void = self.context.voidType();
10006 const param_types = [_]*llvm.Type{
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);
10028 const fn_type = try o.builder.fnType(.void, &.{ .ptr, .i32, .i32, .i32 }, .normal);
10029 break :blk o.llvm_module.addFunction(llvm_fn_name, fn_type.toLlvm(&o.builder));
1001110030 };
1001210031
1001310032 const ptr = try self.resolveInst(prefetch.ptr);
1001410033
10034 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
1001510035 const params = [_]*llvm.Value{
1001610036 ptr,
1001710037 llvm_u32.constInt(@intFromEnum(prefetch.rw), .False),
......@@ -10033,7 +10053,7 @@ pub const FuncGen = struct {
1003310053 }
1003410054
1003510055 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
1003810058 const llvm_fn_name = switch (dimension) {
1003910059 0 => basename ++ ".x",
......@@ -10043,7 +10063,7 @@ pub const FuncGen = struct {
1004310063 };
1004410064
1004510065 const args: [0]*llvm.Value = .{};
10046 const llvm_fn = self.getIntrinsic(llvm_fn_name, &.{});
10066 const llvm_fn = try self.getIntrinsic(llvm_fn_name, &.{});
1004710067 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
1004810068 }
1004910069
......@@ -10064,14 +10084,14 @@ pub const FuncGen = struct {
1006410084
1006510085 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
1006610086 const dimension = pl_op.payload;
10067 const llvm_u32 = self.context.intType(32);
10087 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
1006810088 if (dimension >= 3) {
1006910089 return llvm_u32.constInt(1, .False);
1007010090 }
1007110091
1007210092 // Fetch the dispatch pointer, which points to this structure:
1007310093 // 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", &.{});
1007510095 const args: [0]*llvm.Value = .{};
1007610096 const dispatch_ptr = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
1007710097 dispatch_ptr.setAlignment(4);
......@@ -10080,7 +10100,7 @@ pub const FuncGen = struct {
1008010100 // Just treat the dispatch pointer as an array of u16 to keep things simple.
1008110101 const offset = 2 + dimension;
1008210102 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);
1008410104 const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, "");
1008510105 const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, "");
1008610106 workgroup_size.setAlignment(2);
......@@ -10126,7 +10146,7 @@ pub const FuncGen = struct {
1012610146 opt_handle: *llvm.Value,
1012710147 is_by_ref: bool,
1012810148 ) *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);
1013010150 const field = b: {
1013110151 if (is_by_ref) {
1013210152 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
......@@ -10180,12 +10200,12 @@ pub const FuncGen = struct {
1018010200 ) !?*llvm.Value {
1018110201 const o = self.dg.object;
1018210202 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), "");
1018410204 const mod = o.module;
1018510205
1018610206 if (isByRef(optional_ty, mod)) {
1018710207 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
1019010210 {
1019110211 const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, "");
......@@ -10233,7 +10253,7 @@ pub const FuncGen = struct {
1023310253 // Offset our operand pointer by the correct number of bytes.
1023410254 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
1023510255 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);
1023710257 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
1023810258 const llvm_index = llvm_usize.constInt(byte_offset, .False);
1023910259 const indices: [1]*llvm.Value = .{llvm_index};
......@@ -10249,7 +10269,7 @@ pub const FuncGen = struct {
1024910269 // end of the struct. Treat our struct pointer as an array of two and get
1025010270 // the index to the element at index `1` to get a pointer to the end of
1025110271 // the struct.
10252 const llvm_u32 = self.context.intType(32);
10272 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
1025310273 const llvm_index = llvm_u32.constInt(@intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);
1025410274 const indices: [1]*llvm.Value = .{llvm_index};
1025510275 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
......@@ -10268,11 +10288,14 @@ pub const FuncGen = struct {
1026810288 }
1026910289 }
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;
1027210293 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
1027310294 assert(id != 0);
10274 const o = fg.dg.object;
10275 return o.llvm_module.getIntrinsicDeclaration(id, types.ptr, types.len);
10295 const llvm_types = try o.gpa.alloc(*llvm.Type, 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);
1027610299 }
1027710300
1027810301 /// Load a by-ref type by constructing a new alloca and performing a memcpy.
......@@ -10287,8 +10310,8 @@ pub const FuncGen = struct {
1028710310 const mod = o.module;
1028810311 const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder);
1028910312 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
10290 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
10291 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
10313 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);
10314 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
1029210315 const size_bytes = pointee_type.abiSize(mod);
1029310316 _ = fg.builder.buildMemCpy(
1029410317 result_ptr,
......@@ -10317,7 +10340,7 @@ pub const FuncGen = struct {
1031710340
1031810341 assert(info.flags.vector_index != .runtime);
1031910342 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);
1032110344 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
1032210345 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
1032310346
......@@ -10339,7 +10362,7 @@ pub const FuncGen = struct {
1033910362 return llvm_inst;
1034010363 }
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);
1034310366 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
1034410367 containing_int.setAlignment(ptr_alignment);
1034510368 containing_int.setVolatile(ptr_volatile);
......@@ -10351,9 +10374,9 @@ pub const FuncGen = struct {
1035110374
1035210375 if (isByRef(elem_ty, mod)) {
1035310376 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);
1035710380 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
1035810381 const store_inst = self.builder.buildStore(truncated_int, result_ptr);
1035910382 store_inst.setAlignment(result_align);
......@@ -10361,13 +10384,13 @@ pub const FuncGen = struct {
1036110384 }
1036210385
1036310386 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);
1036510388 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
1036610389 return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
1036710390 }
1036810391
1036910392 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);
1037110394 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
1037210395 return self.builder.buildIntToPtr(truncated_int, elem_llvm_ty, "");
1037310396 }
......@@ -10394,7 +10417,7 @@ pub const FuncGen = struct {
1039410417
1039510418 assert(info.flags.vector_index != .runtime);
1039610419 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);
1039810421 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
1039910422 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
1040010423
......@@ -10412,7 +10435,7 @@ pub const FuncGen = struct {
1041210435 }
1041310436
1041410437 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);
1041610439 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
1041710440 assert(ordering == .NotAtomic);
1041810441 containing_int.setAlignment(ptr_alignment);
......@@ -10422,7 +10445,7 @@ pub const FuncGen = struct {
1042210445 const shift_amt = containing_int_ty.constInt(info.packed_offset.bit_offset, .False);
1042310446 // Convert to equally-sized integer type in order to perform the bit
1042410447 // 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);
1042610449 const value_bits = if (elem_ty.isPtrAtRuntime(mod))
1042710450 self.builder.buildPtrToInt(elem, value_bits_type, "")
1042810451 else
......@@ -10458,20 +10481,19 @@ pub const FuncGen = struct {
1045810481 ptr_alignment,
1045910482 elem,
1046010483 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),
1046210485 info.flags.is_volatile,
1046310486 );
1046410487 }
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 {
1046710490 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
1046810491 const o = fg.dg.object;
10469 const target = o.module.getTarget();
10470 const usize_llvm_ty = fg.context.intType(target.ptrBitWidth());
10492 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
1047110493 const zero = usize_llvm_ty.constInt(0, .False);
1047210494 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);
1047310495 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);
1047510497 }
1047610498
1047710499 fn valgrindClientRequest(
......@@ -10483,18 +10505,19 @@ pub const FuncGen = struct {
1048310505 a3: *llvm.Value,
1048410506 a4: *llvm.Value,
1048510507 a5: *llvm.Value,
10486 ) *llvm.Value {
10508 ) Allocator.Error!*llvm.Value {
1048710509 const o = fg.dg.object;
1048810510 const mod = o.module;
1048910511 const target = mod.getTarget();
1049010512 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);
1049310516 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));
1049410517
1049510518 const array_llvm_ty = usize_llvm_ty.arrayType(6);
1049610519 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);
1049810521 fg.valgrind_client_request_array = array_ptr;
1049910522 break :a array_ptr;
1050010523 };
......@@ -10540,10 +10563,9 @@ pub const FuncGen = struct {
1054010563 else => unreachable,
1054110564 };
1054210565
10566 const fn_llvm_ty = (try o.builder.fnType(usize_ty, &(.{usize_ty} ** 2), .normal)).toLlvm(&o.builder);
1054310567 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");
1054410568 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);
1054710569 const asm_fn = llvm.getInlineAsm(
1054810570 fn_llvm_ty,
1054910571 arch_specific.template.ptr,
......@@ -11200,7 +11222,6 @@ const ParamTypeIterator = struct {
1120011222 llvm_index: u32,
1120111223 types_len: u32,
1120211224 types_buffer: [8]Builder.Type,
11203 llvm_types_buffer: [8]*llvm.Type,
1120411225 byval_attr: bool,
1120511226
1120611227 const Lowering = union(enum) {
......@@ -11298,7 +11319,6 @@ const ParamTypeIterator = struct {
1129811319 .integer => {
1129911320 it.types_len = 1;
1130011321 it.types_buffer[0] = .i64;
11301 it.llvm_types_buffer[0] = it.types_buffer[0].toLlvm(&it.object.builder);
1130211322 return .multiple_llvm_types;
1130311323 },
1130411324 .double_integer => return Lowering{ .i64_array = 2 },
......@@ -11408,31 +11428,22 @@ const ParamTypeIterator = struct {
1140811428 }
1140911429 var types_index: u32 = 0;
1141011430 var types_buffer: [8]Builder.Type = undefined;
11411 var llvm_types_buffer: [8]*llvm.Type = undefined;
1141211431 for (classes) |class| {
1141311432 switch (class) {
1141411433 .integer => {
1141511434 types_buffer[types_index] = .i64;
11416 llvm_types_buffer[types_index] =
11417 types_buffer[types_index].toLlvm(&it.object.builder);
1141811435 types_index += 1;
1141911436 },
1142011437 .sse, .sseup => {
1142111438 types_buffer[types_index] = .double;
11422 llvm_types_buffer[types_index] =
11423 types_buffer[types_index].toLlvm(&it.object.builder);
1142411439 types_index += 1;
1142511440 },
1142611441 .float => {
1142711442 types_buffer[types_index] = .float;
11428 llvm_types_buffer[types_index] =
11429 types_buffer[types_index].toLlvm(&it.object.builder);
1143011443 types_index += 1;
1143111444 },
1143211445 .float_combine => {
1143311446 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);
1143611447 types_index += 1;
1143711448 },
1143811449 .x87 => {
......@@ -11457,7 +11468,6 @@ const ParamTypeIterator = struct {
1145711468 }
1145811469 it.types_len = types_index;
1145911470 it.types_buffer = types_buffer;
11460 it.llvm_types_buffer = llvm_types_buffer;
1146111471 it.llvm_index += types_index;
1146211472 it.zig_index += 1;
1146311473 return .multiple_llvm_types;
......@@ -11472,7 +11482,6 @@ fn iterateParamTypes(object: *Object, fn_info: InternPool.Key.FuncType) ParamTyp
1147211482 .llvm_index = 0,
1147311483 .types_len = 0,
1147411484 .types_buffer = undefined,
11475 .llvm_types_buffer = undefined,
1147611485 .byval_attr = false,
1147711486 };
1147811487}
......@@ -11740,51 +11749,6 @@ fn compilerRtIntBits(bits: u16) u16 {
1174011749 return bits;
1174111750}
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
1178811752fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {
1178911753 return @intFromBool(Type.anyerror.abiAlignment(mod) > payload_ty.abiAlignment(mod));
1179011754}
src/codegen/llvm/Builder.zig+29-11
......@@ -1320,29 +1320,47 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
13201320 try writer.writeByte('\n');
13211321 for (self.functions.items) |function| {
13221322 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]);
13231327 try writer.print(
1324 \\{s} {}{}{}{}{<}@{}{>} {}{}{{
1325 \\ ret {%}
1326 \\}}
1327 \\
1328 \\{s} {}{}{}{}{} @{}(
13281329 , .{
13291330 if (function.body) |_| "define" else "declare",
13301331 global.value.linkage,
13311332 global.value.preemption,
13321333 global.value.visibility,
13331334 global.value.dll_storage_class,
1334 global.value.type.fmt(self),
1335 extra.data.ret.fmt(self),
13351336 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(") {}{}", .{
13371351 global.value.unnamed_addr,
13381352 global.value.alignment,
1339 self.typeExtraData(
1340 Type.Function,
1341 self.type_items.items[@intFromEnum(global.value.type)].data,
1342 ).ret.fmt(self),
13431353 });
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');
13441363 }
1345 try writer.writeByte('\n');
13461364}
13471365
13481366inline fn useLibLlvm(self: *const Builder) bool {