authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-08 23:13:06-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
log2cb52235b91f7e4bf5a4ebf77a5008adfc30c8b9
tree07495729dae15f20cd1cdf00cc37a3c8dbbb07ea
parent65fd401c063ed5214fd6d38b04278571df24f962

llvm: convert all calls to `constInt`


3 files changed, 834 insertions(+), 454 deletions(-)

src/codegen/llvm.zig+273-363
...@@ -611,7 +611,7 @@ pub const Object = struct {...@@ -611,7 +611,7 @@ pub const Object = struct {
611 };611 };
612 errdefer builder.llvm_context.dispose();612 errdefer builder.llvm_context.dispose();
613613
614 initializeLLVMTarget(options.target.cpu.arch);614 builder.initializeLLVMTarget(options.target.cpu.arch);
615615
616 builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context);616 builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context);
617 errdefer builder.llvm_module.dispose();617 errdefer builder.llvm_module.dispose();
...@@ -832,7 +832,7 @@ pub const Object = struct {...@@ -832,7 +832,7 @@ pub const Object = struct {
832832
833 const slice_fields = [_]*llvm.Value{833 const slice_fields = [_]*llvm.Value{
834 str_global,834 str_global,
835 llvm_usize_ty.toLlvm(&o.builder).constInt(name.len, .False),835 (try o.builder.intConst(llvm_usize_ty, name.len)).toLlvm(&o.builder),
836 };836 };
837 llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len);837 llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len);
838 }838 }
...@@ -874,8 +874,8 @@ pub const Object = struct {...@@ -874,8 +874,8 @@ pub const Object = struct {
874 // }874 // }
875875
876 const lhs = llvm_fn.getParam(0);876 const lhs = llvm_fn.getParam(0);
877 const rhs = lhs.typeOf().constInt(errors_len, .False);877 const rhs = try object.builder.intConst(Builder.Type.err_int, errors_len);
878 const is_lt = builder.buildICmp(.ULT, lhs, rhs, "");878 const is_lt = builder.buildICmp(.ULT, lhs, rhs.toLlvm(&object.builder), "");
879 _ = builder.buildRet(is_lt);879 _ = builder.buildRet(is_lt);
880 }880 }
881881
...@@ -3474,10 +3474,8 @@ pub const Object = struct {...@@ -3474,10 +3474,8 @@ pub const Object = struct {
3474 .@"unreachable",3474 .@"unreachable",
3475 .generic_poison,3475 .generic_poison,
3476 => unreachable, // non-runtime values3476 => unreachable, // non-runtime values
3477 .false, .true => {3477 .false => return Builder.Constant.false.toLlvm(&o.builder),
3478 const llvm_type = (try o.lowerType(tv.ty)).toLlvm(&o.builder);3478 .true => return Builder.Constant.true.toLlvm(&o.builder),
3479 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
3480 },
3481 },3479 },
3482 .variable,3480 .variable,
3483 .enum_literal,3481 .enum_literal,
...@@ -3503,9 +3501,9 @@ pub const Object = struct {...@@ -3503,9 +3501,9 @@ pub const Object = struct {
3503 return lowerBigInt(o, tv.ty, bigint);3501 return lowerBigInt(o, tv.ty, bigint);
3504 },3502 },
3505 .err => |err| {3503 .err => |err| {
3506 const llvm_ty = Builder.Type.err_int.toLlvm(&o.builder);
3507 const int = try mod.getErrorValue(err.name);3504 const int = try mod.getErrorValue(err.name);
3508 return llvm_ty.constInt(int, .False);3505 const llvm_int = try o.builder.intConst(Builder.Type.err_int, int);
3506 return llvm_int.toLlvm(&o.builder);
3509 },3507 },
3510 .error_union => |error_union| {3508 .error_union => |error_union| {
3511 const err_tv: TypedValue = switch (error_union.val) {3509 const err_tv: TypedValue = switch (error_union.val) {
...@@ -3556,79 +3554,33 @@ pub const Object = struct {...@@ -3556,79 +3554,33 @@ pub const Object = struct {
3556 return o.context.constStruct(&fields_buf, llvm_field_count, .False);3554 return o.context.constStruct(&fields_buf, llvm_field_count, .False);
3557 }3555 }
3558 },3556 },
3559 .enum_tag => {3557 .enum_tag => |enum_tag| return o.lowerValue(.{
3560 const int_val = try tv.intFromEnum(mod);3558 .ty = mod.intern_pool.typeOf(enum_tag.int).toType(),
35613559 .val = enum_tag.int.toValue(),
3562 var bigint_space: Value.BigIntSpace = undefined;3560 }),
3563 const bigint = int_val.toBigInt(&bigint_space, mod);3561 .float => return switch (tv.ty.floatBits(target)) {
35643562 16 => int: {
3565 const int_info = tv.ty.intInfo(mod);3563 const repr: i16 = @bitCast(tv.val.toFloat(f16, mod));
3566 const llvm_type = (try o.builder.intType(@intCast(int_info.bits))).toLlvm(&o.builder);3564 break :int try o.builder.intConst(.i16, repr);
35673565 },
3568 const unsigned_val = v: {3566 32 => int: {
3569 if (bigint.limbs.len == 1) {3567 const repr: i32 = @bitCast(tv.val.toFloat(f32, mod));
3570 break :v llvm_type.constInt(bigint.limbs[0], .False);3568 break :int try o.builder.intConst(.i32, repr);
3571 }3569 },
3572 if (@sizeOf(usize) == @sizeOf(u64)) {3570 64 => int: {
3573 break :v llvm_type.constIntOfArbitraryPrecision(3571 const repr: i64 = @bitCast(tv.val.toFloat(f64, mod));
3574 @as(c_uint, @intCast(bigint.limbs.len)),3572 break :int try o.builder.intConst(.i64, repr);
3575 bigint.limbs.ptr,3573 },
3576 );3574 80 => int: {
3577 }3575 const repr: i80 = @bitCast(tv.val.toFloat(f80, mod));
3578 @panic("TODO implement bigint to llvm int for 32-bit compiler builds");3576 break :int try o.builder.intConst(.i80, repr);
3579 };3577 },
3580 if (!bigint.positive) {3578 128 => int: {
3581 return llvm.constNeg(unsigned_val);3579 const repr: i128 = @bitCast(tv.val.toFloat(f128, mod));
3582 }3580 break :int try o.builder.intConst(.i128, repr);
3583 return unsigned_val;3581 },
3584 },3582 else => unreachable,
3585 .float => {3583 }.toLlvm(&o.builder).constBitCast((try o.lowerType(tv.ty)).toLlvm(&o.builder)),
3586 const llvm_ty = (try o.lowerType(tv.ty)).toLlvm(&o.builder);
3587 switch (tv.ty.floatBits(target)) {
3588 16 => {
3589 const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod)));
3590 const llvm_i16 = Builder.Type.i16.toLlvm(&o.builder);
3591 const int = llvm_i16.constInt(repr, .False);
3592 return int.constBitCast(llvm_ty);
3593 },
3594 32 => {
3595 const repr = @as(u32, @bitCast(tv.val.toFloat(f32, mod)));
3596 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
3597 const int = llvm_i32.constInt(repr, .False);
3598 return int.constBitCast(llvm_ty);
3599 },
3600 64 => {
3601 const repr = @as(u64, @bitCast(tv.val.toFloat(f64, mod)));
3602 const llvm_i64 = Builder.Type.i64.toLlvm(&o.builder);
3603 const int = llvm_i64.constInt(repr, .False);
3604 return int.constBitCast(llvm_ty);
3605 },
3606 80 => {
3607 const float = tv.val.toFloat(f80, mod);
3608 const repr = std.math.break_f80(float);
3609 const llvm_i80 = Builder.Type.i80.toLlvm(&o.builder);
3610 var x = llvm_i80.constInt(repr.exp, .False);
3611 x = x.constShl(llvm_i80.constInt(64, .False));
3612 x = x.constOr(llvm_i80.constInt(repr.fraction, .False));
3613 if (backendSupportsF80(target)) {
3614 return x.constBitCast(llvm_ty);
3615 } else {
3616 return x;
3617 }
3618 },
3619 128 => {
3620 var buf: [2]u64 = @as([2]u64, @bitCast(tv.val.toFloat(f128, mod)));
3621 // LLVM seems to require that the lower half of the f128 be placed first
3622 // in the buffer.
3623 if (native_endian == .Big) {
3624 std.mem.swap(u64, &buf[0], &buf[1]);
3625 }
3626 const int = Builder.Type.i128.toLlvm(&o.builder).constIntOfArbitraryPrecision(buf.len, &buf);
3627 return int.constBitCast(llvm_ty);
3628 },
3629 else => unreachable,
3630 }
3631 },
3632 .ptr => |ptr| {3584 .ptr => |ptr| {
3633 const ptr_tv: TypedValue = switch (ptr.len) {3585 const ptr_tv: TypedValue = switch (ptr.len) {
3634 .none => tv,3586 .none => tv,
...@@ -3660,11 +3612,7 @@ pub const Object = struct {...@@ -3660,11 +3612,7 @@ pub const Object = struct {
3660 comptime assert(optional_layout_version == 3);3612 comptime assert(optional_layout_version == 3);
3661 const payload_ty = tv.ty.optionalChild(mod);3613 const payload_ty = tv.ty.optionalChild(mod);
36623614
3663 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);3615 const non_null_bit = (try o.builder.intConst(.i8, @intFromBool(opt.val != .none))).toLlvm(&o.builder);
3664 const non_null_bit = switch (opt.val) {
3665 .none => llvm_i8.constNull(),
3666 else => llvm_i8.constInt(1, .False),
3667 };
3668 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {3616 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3669 return non_null_bit;3617 return non_null_bit;
3670 }3618 }
...@@ -3761,10 +3709,9 @@ pub const Object = struct {...@@ -3761,10 +3709,9 @@ pub const Object = struct {
3761 const elem_ty = vector_type.child.toType();3709 const elem_ty = vector_type.child.toType();
3762 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);3710 const llvm_elems = try gpa.alloc(*llvm.Value, vector_type.len);
3763 defer gpa.free(llvm_elems);3711 defer gpa.free(llvm_elems);
3764 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);
3765 for (llvm_elems, 0..) |*llvm_elem, i| {3712 for (llvm_elems, 0..) |*llvm_elem, i| {
3766 llvm_elem.* = switch (aggregate.storage) {3713 llvm_elem.* = switch (aggregate.storage) {
3767 .bytes => |bytes| llvm_i8.constInt(bytes[i], .False),3714 .bytes => |bytes| (try o.builder.intConst(.i8, bytes[i])).toLlvm(&o.builder),
3768 .elems => |elems| try o.lowerValue(.{3715 .elems => |elems| try o.lowerValue(.{
3769 .ty = elem_ty,3716 .ty = elem_ty,
3770 .val = elems[i].toValue(),3717 .val = elems[i].toValue(),
...@@ -3802,10 +3749,10 @@ pub const Object = struct {...@@ -3802,10 +3749,10 @@ pub const Object = struct {
38023749
3803 const padding_len = offset - prev_offset;3750 const padding_len = offset - prev_offset;
3804 if (padding_len > 0) {3751 if (padding_len > 0) {
3805 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));3752 const llvm_array_ty = try o.builder.arrayType(padding_len, .i8);
3806 // TODO make this and all other padding elsewhere in debug3753 // TODO make this and all other padding elsewhere in debug
3807 // builds be 0xaa not undef.3754 // builds be 0xaa not undef.
3808 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3755 llvm_fields.appendAssumeCapacity(llvm_array_ty.toLlvm(&o.builder).getUndef());
3809 }3756 }
38103757
3811 const field_llvm_val = try o.lowerValue(.{3758 const field_llvm_val = try o.lowerValue(.{
...@@ -3824,8 +3771,8 @@ pub const Object = struct {...@@ -3824,8 +3771,8 @@ pub const Object = struct {
3824 offset = std.mem.alignForward(u64, offset, big_align);3771 offset = std.mem.alignForward(u64, offset, big_align);
3825 const padding_len = offset - prev_offset;3772 const padding_len = offset - prev_offset;
3826 if (padding_len > 0) {3773 if (padding_len > 0) {
3827 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));3774 const llvm_array_ty = try o.builder.arrayType(padding_len, .i8);
3828 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3775 llvm_fields.appendAssumeCapacity(llvm_array_ty.toLlvm(&o.builder).getUndef());
3829 }3776 }
3830 }3777 }
38313778
...@@ -3850,10 +3797,10 @@ pub const Object = struct {...@@ -3850,10 +3797,10 @@ pub const Object = struct {
3850 if (struct_obj.layout == .Packed) {3797 if (struct_obj.layout == .Packed) {
3851 assert(struct_obj.haveLayout());3798 assert(struct_obj.haveLayout());
3852 const big_bits = struct_obj.backing_int_ty.bitSize(mod);3799 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
3853 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);3800 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));
3854 const fields = struct_obj.fields.values();3801 const fields = struct_obj.fields.values();
3855 comptime assert(Type.packed_struct_layout_version == 2);3802 comptime assert(Type.packed_struct_layout_version == 2);
3856 var running_int: *llvm.Value = int_llvm_ty.constNull();3803 var running_int = (try o.builder.intConst(int_llvm_ty, 0)).toLlvm(&o.builder);
3857 var running_bits: u16 = 0;3804 var running_bits: u16 = 0;
3858 for (fields, 0..) |field, i| {3805 for (fields, 0..) |field, i| {
3859 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;3806 if (!field.ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
...@@ -3868,11 +3815,11 @@ pub const Object = struct {...@@ -3868,11 +3815,11 @@ pub const Object = struct {
3868 non_int_val.constPtrToInt(small_int_ty)3815 non_int_val.constPtrToInt(small_int_ty)
3869 else3816 else
3870 non_int_val.constBitCast(small_int_ty);3817 non_int_val.constBitCast(small_int_ty);
3871 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);3818 const shift_rhs = (try o.builder.intConst(int_llvm_ty, running_bits)).toLlvm(&o.builder);
3872 // If the field is as large as the entire packed struct, this3819 // If the field is as large as the entire packed struct, this
3873 // zext would go from, e.g. i16 to i16. This is legal with3820 // zext would go from, e.g. i16 to i16. This is legal with
3874 // constZExtOrBitCast but not legal with constZExt.3821 // constZExtOrBitCast but not legal with constZExt.
3875 const extended_int_val = small_int_val.constZExtOrBitCast(int_llvm_ty);3822 const extended_int_val = small_int_val.constZExtOrBitCast(int_llvm_ty.toLlvm(&o.builder));
3876 const shifted = extended_int_val.constShl(shift_rhs);3823 const shifted = extended_int_val.constShl(shift_rhs);
3877 running_int = running_int.constOr(shifted);3824 running_int = running_int.constOr(shifted);
3878 running_bits += ty_bit_size;3825 running_bits += ty_bit_size;
...@@ -3899,10 +3846,10 @@ pub const Object = struct {...@@ -3899,10 +3846,10 @@ pub const Object = struct {
38993846
3900 const padding_len = offset - prev_offset;3847 const padding_len = offset - prev_offset;
3901 if (padding_len > 0) {3848 if (padding_len > 0) {
3902 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));3849 const llvm_array_ty = try o.builder.arrayType(padding_len, .i8);
3903 // TODO make this and all other padding elsewhere in debug3850 // TODO make this and all other padding elsewhere in debug
3904 // builds be 0xaa not undef.3851 // builds be 0xaa not undef.
3905 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3852 llvm_fields.appendAssumeCapacity(llvm_array_ty.toLlvm(&o.builder).getUndef());
3906 }3853 }
39073854
3908 const field_llvm_val = try o.lowerValue(.{3855 const field_llvm_val = try o.lowerValue(.{
...@@ -3921,8 +3868,8 @@ pub const Object = struct {...@@ -3921,8 +3868,8 @@ pub const Object = struct {
3921 offset = std.mem.alignForward(u64, offset, big_align);3868 offset = std.mem.alignForward(u64, offset, big_align);
3922 const padding_len = offset - prev_offset;3869 const padding_len = offset - prev_offset;
3923 if (padding_len > 0) {3870 if (padding_len > 0) {
3924 const llvm_array_ty = Builder.Type.i8.toLlvm(&o.builder).arrayType(@as(c_uint, @intCast(padding_len)));3871 const llvm_array_ty = try o.builder.arrayType(padding_len, .i8);
3925 llvm_fields.appendAssumeCapacity(llvm_array_ty.getUndef());3872 llvm_fields.appendAssumeCapacity(llvm_array_ty.toLlvm(&o.builder).getUndef());
3926 }3873 }
3927 }3874 }
39283875
...@@ -3985,7 +3932,7 @@ pub const Object = struct {...@@ -3985,7 +3932,7 @@ pub const Object = struct {
3985 const payload = p: {3932 const payload = p: {
3986 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {3933 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) {
3987 const padding_len = @as(c_uint, @intCast(layout.payload_size));3934 const padding_len = @as(c_uint, @intCast(layout.payload_size));
3988 break :p Builder.Type.i8.toLlvm(&o.builder).arrayType(padding_len).getUndef();3935 break :p (try o.builder.arrayType(padding_len, .i8)).toLlvm(&o.builder).getUndef();
3989 }3936 }
3990 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });3937 const field = try lowerValue(o, .{ .ty = field_ty, .val = tag_and_val.val });
3991 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);3938 need_unnamed = need_unnamed or o.isUnnamedType(field_ty, field);
...@@ -3995,7 +3942,7 @@ pub const Object = struct {...@@ -3995,7 +3942,7 @@ pub const Object = struct {
3995 }3942 }
3996 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));3943 const padding_len = @as(c_uint, @intCast(layout.payload_size - field_size));
3997 const fields: [2]*llvm.Value = .{3944 const fields: [2]*llvm.Value = .{
3998 field, Builder.Type.i8.toLlvm(&o.builder).arrayType(padding_len).getUndef(),3945 field, (try o.builder.arrayType(padding_len, .i8)).toLlvm(&o.builder).getUndef(),
3999 };3946 };
4000 break :p o.context.constStruct(&fields, fields.len, .True);3947 break :p o.context.constStruct(&fields, fields.len, .True);
4001 };3948 };
...@@ -4020,7 +3967,7 @@ pub const Object = struct {...@@ -4020,7 +3967,7 @@ pub const Object = struct {
4020 fields = .{ payload, llvm_tag_value, undefined };3967 fields = .{ payload, llvm_tag_value, undefined };
4021 }3968 }
4022 if (layout.padding != 0) {3969 if (layout.padding != 0) {
4023 fields[2] = Builder.Type.i8.toLlvm(&o.builder).arrayType(layout.padding).getUndef();3970 fields[2] = (try o.builder.arrayType(layout.padding, .i8)).toLlvm(&o.builder).getUndef();
4024 fields_len = 3;3971 fields_len = 3;
4025 }3972 }
4026 if (need_unnamed) {3973 if (need_unnamed) {
...@@ -4048,27 +3995,8 @@ pub const Object = struct {...@@ -4048,27 +3995,8 @@ pub const Object = struct {
4048 }3995 }
40493996
4050 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) Allocator.Error!*llvm.Value {3997 fn lowerBigInt(o: *Object, ty: Type, bigint: std.math.big.int.Const) Allocator.Error!*llvm.Value {
4051 const mod = o.module;3998 return (try o.builder.bigIntConst(try o.builder.intType(ty.intInfo(o.module).bits), bigint))
4052 const int_info = ty.intInfo(mod);3999 .toLlvm(&o.builder);
4053 assert(int_info.bits != 0);
4054 const llvm_type = (try o.builder.intType(@intCast(int_info.bits))).toLlvm(&o.builder);
4055
4056 const unsigned_val = v: {
4057 if (bigint.limbs.len == 1) {
4058 break :v llvm_type.constInt(bigint.limbs[0], .False);
4059 }
4060 if (@sizeOf(usize) == @sizeOf(u64)) {
4061 break :v llvm_type.constIntOfArbitraryPrecision(
4062 @as(c_uint, @intCast(bigint.limbs.len)),
4063 bigint.limbs.ptr,
4064 );
4065 }
4066 @panic("TODO implement bigint to llvm int for 32-bit compiler builds");
4067 };
4068 if (!bigint.positive) {
4069 return llvm.constNeg(unsigned_val);
4070 }
4071 return unsigned_val;
4072 }4000 }
40734001
4074 const ParentPtr = struct {4002 const ParentPtr = struct {
...@@ -4106,10 +4034,9 @@ pub const Object = struct {...@@ -4106,10 +4034,9 @@ pub const Object = struct {
4106 }4034 }
41074035
4108 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;4036 const payload_offset: u8 = if (payload_ty.abiAlignment(mod) > Type.anyerror.abiSize(mod)) 2 else 1;
4109 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4110 const indices: [2]*llvm.Value = .{4037 const indices: [2]*llvm.Value = .{
4111 llvm_u32.constInt(0, .False),4038 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
4112 llvm_u32.constInt(payload_offset, .False),4039 (try o.builder.intConst(.i32, payload_offset)).toLlvm(&o.builder),
4113 };4040 };
4114 const eu_llvm_ty = (try o.lowerType(eu_ty)).toLlvm(&o.builder);4041 const eu_llvm_ty = (try o.lowerType(eu_ty)).toLlvm(&o.builder);
4115 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4042 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
...@@ -4127,11 +4054,9 @@ pub const Object = struct {...@@ -4127,11 +4054,9 @@ pub const Object = struct {
4127 return parent_llvm_ptr;4054 return parent_llvm_ptr;
4128 }4055 }
41294056
4130 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4131 const indices: [2]*llvm.Value = .{4057 const indices: [2]*llvm.Value = .{
4132 llvm_u32.constInt(0, .False),4058 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
4133 llvm_u32.constInt(0, .False),4059 } ** 2;
4134 };
4135 const opt_llvm_ty = (try o.lowerType(opt_ty)).toLlvm(&o.builder);4060 const opt_llvm_ty = (try o.lowerType(opt_ty)).toLlvm(&o.builder);
4136 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4061 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4137 },4062 },
...@@ -4139,9 +4064,8 @@ pub const Object = struct {...@@ -4139,9 +4064,8 @@ pub const Object = struct {
4139 .elem => |elem_ptr| {4064 .elem => |elem_ptr| {
4140 const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true);4065 const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true);
41414066
4142 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);
4143 const indices: [1]*llvm.Value = .{4067 const indices: [1]*llvm.Value = .{
4144 llvm_usize.constInt(elem_ptr.index, .False),4068 (try o.builder.intConst(try o.lowerType(Type.usize), elem_ptr.index)).toLlvm(&o.builder),
4145 };4069 };
4146 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);4070 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
4147 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);4071 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
...@@ -4152,7 +4076,6 @@ pub const Object = struct {...@@ -4152,7 +4076,6 @@ pub const Object = struct {
4152 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);4076 const parent_ty = mod.intern_pool.typeOf(field_ptr.base).toType().childType(mod);
41534077
4154 const field_index = @as(u32, @intCast(field_ptr.index));4078 const field_index = @as(u32, @intCast(field_ptr.index));
4155 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
4156 switch (parent_ty.zigTypeTag(mod)) {4079 switch (parent_ty.zigTypeTag(mod)) {
4157 .Union => {4080 .Union => {
4158 if (parent_ty.containerLayout(mod) == .Packed) {4081 if (parent_ty.containerLayout(mod) == .Packed) {
...@@ -4170,8 +4093,8 @@ pub const Object = struct {...@@ -4170,8 +4093,8 @@ pub const Object = struct {
4170 else4093 else
4171 @intFromBool(layout.tag_align >= layout.payload_align);4094 @intFromBool(layout.tag_align >= layout.payload_align);
4172 const indices: [2]*llvm.Value = .{4095 const indices: [2]*llvm.Value = .{
4173 llvm_u32.constInt(0, .False),4096 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
4174 llvm_u32.constInt(llvm_pl_index, .False),4097 (try o.builder.intConst(.i32, llvm_pl_index)).toLlvm(&o.builder),
4175 };4098 };
4176 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);4099 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);
4177 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4100 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
...@@ -4179,8 +4102,8 @@ pub const Object = struct {...@@ -4179,8 +4102,8 @@ pub const Object = struct {
4179 .Struct => {4102 .Struct => {
4180 if (parent_ty.containerLayout(mod) == .Packed) {4103 if (parent_ty.containerLayout(mod) == .Packed) {
4181 if (!byte_aligned) return parent_llvm_ptr;4104 if (!byte_aligned) return parent_llvm_ptr;
4182 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);4105 const llvm_usize = try o.lowerType(Type.usize);
4183 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);4106 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize.toLlvm(&o.builder));
4184 // count bits of fields before this one4107 // count bits of fields before this one
4185 const prev_bits = b: {4108 const prev_bits = b: {
4186 var b: usize = 0;4109 var b: usize = 0;
...@@ -4190,7 +4113,7 @@ pub const Object = struct {...@@ -4190,7 +4113,7 @@ pub const Object = struct {
4190 }4113 }
4191 break :b b;4114 break :b b;
4192 };4115 };
4193 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);4116 const byte_offset = (try o.builder.intConst(llvm_usize, prev_bits / 8)).toLlvm(&o.builder);
4194 const field_addr = base_addr.constAdd(byte_offset);4117 const field_addr = base_addr.constAdd(byte_offset);
4195 const final_llvm_ty = o.context.pointerType(0);4118 const final_llvm_ty = o.context.pointerType(0);
4196 return field_addr.constIntToPtr(final_llvm_ty);4119 return field_addr.constIntToPtr(final_llvm_ty);
...@@ -4199,21 +4122,22 @@ pub const Object = struct {...@@ -4199,21 +4122,22 @@ pub const Object = struct {
4199 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);4122 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);
4200 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {4123 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
4201 const indices: [2]*llvm.Value = .{4124 const indices: [2]*llvm.Value = .{
4202 llvm_u32.constInt(0, .False),4125 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
4203 llvm_u32.constInt(llvm_field.index, .False),4126 (try o.builder.intConst(.i32, llvm_field.index)).toLlvm(&o.builder),
4204 };4127 };
4205 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4128 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4206 } else {4129 } else {
4207 const llvm_index = llvm_u32.constInt(@intFromBool(parent_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);4130 const indices: [1]*llvm.Value = .{
4208 const indices: [1]*llvm.Value = .{llvm_index};4131 (try o.builder.intConst(.i32, @intFromBool(parent_ty.hasRuntimeBitsIgnoreComptime(mod)))).toLlvm(&o.builder),
4132 };
4209 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4133 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4210 }4134 }
4211 },4135 },
4212 .Pointer => {4136 .Pointer => {
4213 assert(parent_ty.isSlice(mod));4137 assert(parent_ty.isSlice(mod));
4214 const indices: [2]*llvm.Value = .{4138 const indices: [2]*llvm.Value = .{
4215 llvm_u32.constInt(0, .False),4139 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
4216 llvm_u32.constInt(field_index, .False),4140 (try o.builder.intConst(.i32, field_index)).toLlvm(&o.builder),
4217 };4141 };
4218 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);4142 const parent_llvm_ty = (try o.lowerType(parent_ty)).toLlvm(&o.builder);
4219 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4143 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
...@@ -4284,10 +4208,10 @@ pub const Object = struct {...@@ -4284,10 +4208,10 @@ pub const Object = struct {
4284 // The value cannot be undefined, because we use the `nonnull` annotation4208 // The value cannot be undefined, because we use the `nonnull` annotation
4285 // for non-optional pointers. We also need to respect the alignment, even though4209 // for non-optional pointers. We also need to respect the alignment, even though
4286 // the address will never be dereferenced.4210 // the address will never be dereferenced.
4287 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);4211 const llvm_usize = try o.lowerType(Type.usize);
4288 const llvm_ptr_ty = (try o.lowerType(ptr_ty)).toLlvm(&o.builder);4212 const llvm_ptr_ty = (try o.lowerType(ptr_ty)).toLlvm(&o.builder);
4289 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {4213 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
4290 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);4214 return (try o.builder.intConst(llvm_usize, alignment)).toLlvm(&o.builder).constIntToPtr(llvm_ptr_ty);
4291 }4215 }
4292 // Note that these 0xaa values are appropriate even in release-optimized builds4216 // Note that these 0xaa values are appropriate even in release-optimized builds
4293 // because we need a well-defined value that is not null, and LLVM does not4217 // because we need a well-defined value that is not null, and LLVM does not
...@@ -4295,13 +4219,13 @@ pub const Object = struct {...@@ -4295,13 +4219,13 @@ pub const Object = struct {
4295 // instruction is followed by a `wrap_optional`, it will return this value4219 // instruction is followed by a `wrap_optional`, it will return this value
4296 // verbatim, and the result should test as non-null.4220 // verbatim, and the result should test as non-null.
4297 const target = mod.getTarget();4221 const target = mod.getTarget();
4298 const int = switch (target.ptrBitWidth()) {4222 const int = try o.builder.intConst(llvm_usize, @as(u64, switch (target.ptrBitWidth()) {
4299 16 => llvm_usize.constInt(0xaaaa, .False),4223 16 => 0xaaaa,
4300 32 => llvm_usize.constInt(0xaaaaaaaa, .False),4224 32 => 0xaaaaaaaa,
4301 64 => llvm_usize.constInt(0xaaaaaaaa_aaaaaaaa, .False),4225 64 => 0xaaaaaaaa_aaaaaaaa,
4302 else => unreachable,4226 else => unreachable,
4303 };4227 }));
4304 return int.constIntToPtr(llvm_ptr_ty);4228 return int.toLlvm(&o.builder).constIntToPtr(llvm_ptr_ty);
4305 }4229 }
43064230
4307 fn addAttr(o: *Object, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {4231 fn addAttr(o: *Object, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void {
...@@ -5118,11 +5042,11 @@ pub const FuncGen = struct {...@@ -5118,11 +5042,11 @@ pub const FuncGen = struct {
5118 llvm_arg = store_inst;5042 llvm_arg = store_inst;
5119 }5043 }
51205044
5121 const float_ty = (try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?)).toLlvm(&o.builder);5045 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
5122 const array_llvm_ty = float_ty.arrayType(count);5046 const array_ty = try o.builder.arrayType(count, float_ty);
51235047
5124 const alignment = arg_ty.abiAlignment(mod);5048 const alignment = arg_ty.abiAlignment(mod);
5125 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");5049 const load_inst = self.builder.buildLoad(array_ty.toLlvm(&o.builder), llvm_arg, "");
5126 load_inst.setAlignment(alignment);5050 load_inst.setAlignment(alignment);
5127 try llvm_args.append(load_inst);5051 try llvm_args.append(load_inst);
5128 },5052 },
...@@ -5138,9 +5062,9 @@ pub const FuncGen = struct {...@@ -5138,9 +5062,9 @@ pub const FuncGen = struct {
5138 llvm_arg = store_inst;5062 llvm_arg = store_inst;
5139 }5063 }
51405064
5141 const array_llvm_ty = (try o.builder.intType(@intCast(elem_size))).toLlvm(&o.builder).arrayType(arr_len);5065 const array_ty = try o.builder.arrayType(arr_len, try o.builder.intType(@intCast(elem_size)));
5142 const alignment = arg_ty.abiAlignment(mod);5066 const alignment = arg_ty.abiAlignment(mod);
5143 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");5067 const load_inst = self.builder.buildLoad(array_ty.toLlvm(&o.builder), llvm_arg, "");
5144 load_inst.setAlignment(alignment);5068 load_inst.setAlignment(alignment);
5145 try llvm_args.append(load_inst);5069 try llvm_args.append(load_inst);
5146 },5070 },
...@@ -5279,7 +5203,7 @@ pub const FuncGen = struct {...@@ -5279,7 +5203,7 @@ pub const FuncGen = struct {
5279 });5203 });
5280 const null_opt_addr_global = try o.getNullOptAddr();5204 const null_opt_addr_global = try o.getNullOptAddr();
5281 const target = mod.getTarget();5205 const target = mod.getTarget();
5282 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);5206 const llvm_usize = try o.lowerType(Type.usize);
5283 // example:5207 // example:
5284 // call fastcc void @test2.panic(5208 // call fastcc void @test2.panic(
5285 // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr5209 // ptr @builtin.panic_messages.integer_overflow__anon_987, ; msg.ptr
...@@ -5289,7 +5213,7 @@ pub const FuncGen = struct {...@@ -5289,7 +5213,7 @@ pub const FuncGen = struct {
5289 // )5213 // )
5290 const args = [4]*llvm.Value{5214 const args = [4]*llvm.Value{
5291 msg_ptr,5215 msg_ptr,
5292 llvm_usize.constInt(msg_len, .False),5216 (try o.builder.intConst(llvm_usize, msg_len)).toLlvm(&o.builder),
5293 fg.context.pointerType(0).constNull(),5217 fg.context.pointerType(0).constNull(),
5294 null_opt_addr_global,5218 null_opt_addr_global,
5295 };5219 };
...@@ -5327,8 +5251,8 @@ pub const FuncGen = struct {...@@ -5327,8 +5251,8 @@ pub const FuncGen = struct {
5327 // Functions with an empty error set are emitted with an error code5251 // Functions with an empty error set are emitted with an error code
5328 // return type and return zero so they can be function pointers coerced5252 // return type and return zero so they can be function pointers coerced
5329 // to functions that return anyerror.5253 // to functions that return anyerror.
5330 const err_int = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder);5254 const int = try o.builder.intConst(Builder.Type.err_int, 0);
5331 _ = self.builder.buildRet(err_int.constInt(0, .False));5255 _ = self.builder.buildRet(int.toLlvm(&o.builder));
5332 } else {5256 } else {
5333 _ = self.builder.buildRetVoid();5257 _ = self.builder.buildRetVoid();
5334 }5258 }
...@@ -5375,8 +5299,8 @@ pub const FuncGen = struct {...@@ -5375,8 +5299,8 @@ pub const FuncGen = struct {
5375 // Functions with an empty error set are emitted with an error code5299 // Functions with an empty error set are emitted with an error code
5376 // return type and return zero so they can be function pointers coerced5300 // return type and return zero so they can be function pointers coerced
5377 // to functions that return anyerror.5301 // to functions that return anyerror.
5378 const err_int = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder);5302 const int = try o.builder.intConst(Builder.Type.err_int, 0);
5379 _ = self.builder.buildRet(err_int.constInt(0, .False));5303 _ = self.builder.buildRet(int.toLlvm(&o.builder));
5380 } else {5304 } else {
5381 _ = self.builder.buildRetVoid();5305 _ = self.builder.buildRetVoid();
5382 }5306 }
...@@ -5531,22 +5455,22 @@ pub const FuncGen = struct {...@@ -5531,22 +5455,22 @@ pub const FuncGen = struct {
5531 // of optionals that are not pointers.5455 // of optionals that are not pointers.
5532 const is_by_ref = isByRef(scalar_ty, mod);5456 const is_by_ref = isByRef(scalar_ty, mod);
5533 const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);5457 const opt_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
5534 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);5458 const lhs_non_null = try self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
5535 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);5459 const rhs_non_null = try self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
5536 const llvm_i2 = (try o.builder.intType(2)).toLlvm(&o.builder);5460 const llvm_i2 = try o.builder.intType(2);
5537 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");5461 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2.toLlvm(&o.builder), "");
5538 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");5462 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2.toLlvm(&o.builder), "");
5539 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, llvm_i2.constInt(1, .False), "");5463 const lhs_shifted = self.builder.buildShl(lhs_non_null_i2, (try o.builder.intConst(llvm_i2, 1)).toLlvm(&o.builder), "");
5540 const lhs_rhs_ored = self.builder.buildOr(lhs_shifted, rhs_non_null_i2, "");5464 const lhs_rhs_ored = self.builder.buildOr(lhs_shifted, rhs_non_null_i2, "");
5541 const both_null_block = self.context.appendBasicBlock(self.llvm_func, "BothNull");5465 const both_null_block = self.context.appendBasicBlock(self.llvm_func, "BothNull");
5542 const mixed_block = self.context.appendBasicBlock(self.llvm_func, "Mixed");5466 const mixed_block = self.context.appendBasicBlock(self.llvm_func, "Mixed");
5543 const both_pl_block = self.context.appendBasicBlock(self.llvm_func, "BothNonNull");5467 const both_pl_block = self.context.appendBasicBlock(self.llvm_func, "BothNonNull");
5544 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");5468 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
5545 const llvm_switch = self.builder.buildSwitch(lhs_rhs_ored, mixed_block, 2);5469 const llvm_switch = self.builder.buildSwitch(lhs_rhs_ored, mixed_block, 2);
5546 const llvm_i2_00 = llvm_i2.constInt(0b00, .False);5470 const llvm_i2_00 = try o.builder.intConst(llvm_i2, 0b00);
5547 const llvm_i2_11 = llvm_i2.constInt(0b11, .False);5471 const llvm_i2_11 = try o.builder.intConst(llvm_i2, 0b11);
5548 llvm_switch.addCase(llvm_i2_00, both_null_block);5472 llvm_switch.addCase(llvm_i2_00.toLlvm(&o.builder), both_null_block);
5549 llvm_switch.addCase(llvm_i2_11, both_pl_block);5473 llvm_switch.addCase(llvm_i2_11.toLlvm(&o.builder), both_pl_block);
55505474
5551 self.builder.positionBuilderAtEnd(both_null_block);5475 self.builder.positionBuilderAtEnd(both_null_block);
5552 _ = self.builder.buildBr(end_block);5476 _ = self.builder.buildBr(end_block);
...@@ -5567,9 +5491,8 @@ pub const FuncGen = struct {...@@ -5567,9 +5491,8 @@ pub const FuncGen = struct {
5567 mixed_block,5491 mixed_block,
5568 both_pl_block_end,5492 both_pl_block_end,
5569 };5493 };
5570 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);5494 const llvm_i1_0 = Builder.Constant.false.toLlvm(&o.builder);
5571 const llvm_i1_0 = llvm_i1.constInt(0, .False);5495 const llvm_i1_1 = Builder.Constant.true.toLlvm(&o.builder);
5572 const llvm_i1_1 = llvm_i1.constInt(1, .False);
5573 const incoming_values: [3]*llvm.Value = .{5496 const incoming_values: [3]*llvm.Value = .{
5574 switch (op) {5497 switch (op) {
5575 .eq => llvm_i1_1,5498 .eq => llvm_i1_1,
...@@ -5584,7 +5507,7 @@ pub const FuncGen = struct {...@@ -5584,7 +5507,7 @@ pub const FuncGen = struct {
5584 payload_cmp,5507 payload_cmp,
5585 };5508 };
55865509
5587 const phi_node = self.builder.buildPhi(llvm_i1, "");5510 const phi_node = self.builder.buildPhi(Builder.Type.i1.toLlvm(&o.builder), "");
5588 comptime assert(incoming_values.len == incoming_blocks.len);5511 comptime assert(incoming_values.len == incoming_blocks.len);
5589 phi_node.addIncoming(5512 phi_node.addIncoming(
5590 &incoming_values,5513 &incoming_values,
...@@ -5882,8 +5805,8 @@ pub const FuncGen = struct {...@@ -5882,8 +5805,8 @@ pub const FuncGen = struct {
5882 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5805 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5883 const operand_ty = self.typeOf(ty_op.operand);5806 const operand_ty = self.typeOf(ty_op.operand);
5884 const array_ty = operand_ty.childType(mod);5807 const array_ty = operand_ty.childType(mod);
5885 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);5808 const llvm_usize = try o.lowerType(Type.usize);
5886 const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False);5809 const len = (try o.builder.intConst(llvm_usize, array_ty.arrayLen(mod))).toLlvm(&o.builder);
5887 const slice_llvm_ty = (try o.lowerType(self.typeOfIndex(inst))).toLlvm(&o.builder);5810 const slice_llvm_ty = (try o.lowerType(self.typeOfIndex(inst))).toLlvm(&o.builder);
5888 const operand = try self.resolveInst(ty_op.operand);5811 const operand = try self.resolveInst(ty_op.operand);
5889 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5812 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -5891,8 +5814,8 @@ pub const FuncGen = struct {...@@ -5891,8 +5814,8 @@ pub const FuncGen = struct {
5891 return self.builder.buildInsertValue(partial, len, 1, "");5814 return self.builder.buildInsertValue(partial, len, 1, "");
5892 }5815 }
5893 const indices: [2]*llvm.Value = .{5816 const indices: [2]*llvm.Value = .{
5894 llvm_usize.constNull(), llvm_usize.constNull(),5817 (try o.builder.intConst(llvm_usize, 0)).toLlvm(&o.builder),
5895 };5818 } ** 2;
5896 const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder);5819 const array_llvm_ty = (try o.lowerType(array_ty)).toLlvm(&o.builder);
5897 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");5820 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");
5898 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");5821 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
...@@ -6024,21 +5947,21 @@ pub const FuncGen = struct {...@@ -6024,21 +5947,21 @@ pub const FuncGen = struct {
6024 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) Allocator.Error!*llvm.Value {5947 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: *llvm.Value, ty: Type) Allocator.Error!*llvm.Value {
6025 const o = fg.dg.object;5948 const o = fg.dg.object;
6026 const mod = o.module;5949 const mod = o.module;
6027 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);5950 const llvm_usize = try o.lowerType(Type.usize);
6028 switch (ty.ptrSize(mod)) {5951 switch (ty.ptrSize(mod)) {
6029 .Slice => {5952 .Slice => {
6030 const len = fg.builder.buildExtractValue(ptr, 1, "");5953 const len = fg.builder.buildExtractValue(ptr, 1, "");
6031 const elem_ty = ty.childType(mod);5954 const elem_ty = ty.childType(mod);
6032 const abi_size = elem_ty.abiSize(mod);5955 const abi_size = elem_ty.abiSize(mod);
6033 if (abi_size == 1) return len;5956 if (abi_size == 1) return len;
6034 const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False);5957 const abi_size_llvm_val = try o.builder.intConst(llvm_usize, abi_size);
6035 return fg.builder.buildMul(len, abi_size_llvm_val, "");5958 return fg.builder.buildMul(len, abi_size_llvm_val.toLlvm(&o.builder), "");
6036 },5959 },
6037 .One => {5960 .One => {
6038 const array_ty = ty.childType(mod);5961 const array_ty = ty.childType(mod);
6039 const elem_ty = array_ty.childType(mod);5962 const elem_ty = array_ty.childType(mod);
6040 const abi_size = elem_ty.abiSize(mod);5963 const abi_size = elem_ty.abiSize(mod);
6041 return llvm_usize_ty.constInt(array_ty.arrayLen(mod) * abi_size, .False);5964 return (try o.builder.intConst(llvm_usize, array_ty.arrayLen(mod) * abi_size)).toLlvm(&o.builder);
6042 },5965 },
6043 .Many, .C => unreachable,5966 .Many, .C => unreachable,
6044 }5967 }
...@@ -6340,10 +6263,10 @@ pub const FuncGen = struct {...@@ -6340,10 +6263,10 @@ pub const FuncGen = struct {
6340 if (field_offset == 0) {6263 if (field_offset == 0) {
6341 return field_ptr;6264 return field_ptr;
6342 }6265 }
6343 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);6266 const llvm_usize = try o.lowerType(Type.usize);
63446267
6345 const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize_ty, "");6268 const field_ptr_int = self.builder.buildPtrToInt(field_ptr, llvm_usize.toLlvm(&o.builder), "");
6346 const base_ptr_int = self.builder.buildNUWSub(field_ptr_int, llvm_usize_ty.constInt(field_offset, .False), "");6269 const base_ptr_int = self.builder.buildNUWSub(field_ptr_int, (try o.builder.intConst(llvm_usize, field_offset)).toLlvm(&o.builder), "");
6347 return self.builder.buildIntToPtr(base_ptr_int, res_ty, "");6270 return self.builder.buildIntToPtr(base_ptr_int, res_ty, "");
6348 }6271 }
63496272
...@@ -6919,12 +6842,11 @@ pub const FuncGen = struct {...@@ -6919,12 +6842,11 @@ pub const FuncGen = struct {
6919 self.builder.buildLoad(optional_llvm_ty, operand, "")6842 self.builder.buildLoad(optional_llvm_ty, operand, "")
6920 else6843 else
6921 operand;6844 operand;
6922 const llvm_i8 = Builder.Type.i8.toLlvm(&o.builder);6845 return self.builder.buildICmp(pred, loaded, (try o.builder.intConst(.i8, 0)).toLlvm(&o.builder), "");
6923 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
6924 }6846 }
69256847
6926 const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod);6848 const is_by_ref = operand_is_ptr or isByRef(optional_ty, mod);
6927 const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);6849 const non_null_bit = try self.optIsNonNull(optional_llvm_ty, operand, is_by_ref);
6928 if (pred == .EQ) {6850 if (pred == .EQ) {
6929 return self.builder.buildNot(non_null_bit, "");6851 return self.builder.buildNot(non_null_bit, "");
6930 } else {6852 } else {
...@@ -6949,12 +6871,12 @@ pub const FuncGen = struct {...@@ -6949,12 +6871,12 @@ pub const FuncGen = struct {
6949 const zero = err_set_ty.constNull();6871 const zero = err_set_ty.constNull();
69506872
6951 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {6873 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6952 const llvm_i1 = Builder.Type.i1.toLlvm(&o.builder);6874 const val: Builder.Constant = switch (op) {
6953 switch (op) {6875 .EQ => .true, // 0 == 0
6954 .EQ => return llvm_i1.constInt(1, .False), // 0 == 06876 .NE => .false, // 0 != 0
6955 .NE => return llvm_i1.constInt(0, .False), // 0 != 0
6956 else => unreachable,6877 else => unreachable,
6957 }6878 };
6879 return val.toLlvm(&o.builder);
6958 }6880 }
69596881
6960 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6882 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
...@@ -7007,7 +6929,7 @@ pub const FuncGen = struct {...@@ -7007,7 +6929,7 @@ pub const FuncGen = struct {
7007 const operand = try self.resolveInst(ty_op.operand);6929 const operand = try self.resolveInst(ty_op.operand);
7008 const optional_ty = self.typeOf(ty_op.operand).childType(mod);6930 const optional_ty = self.typeOf(ty_op.operand).childType(mod);
7009 const payload_ty = optional_ty.optionalChild(mod);6931 const payload_ty = optional_ty.optionalChild(mod);
7010 const non_null_bit = Builder.Type.i8.toLlvm(&o.builder).constInt(1, .False);6932 const non_null_bit = (try o.builder.intConst(.i8, 1)).toLlvm(&o.builder);
7011 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {6933 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
7012 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.6934 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
7013 _ = self.builder.buildStore(non_null_bit, operand);6935 _ = self.builder.buildStore(non_null_bit, operand);
...@@ -7101,11 +7023,10 @@ pub const FuncGen = struct {...@@ -7101,11 +7023,10 @@ pub const FuncGen = struct {
7101 const operand_ty = self.typeOf(ty_op.operand);7023 const operand_ty = self.typeOf(ty_op.operand);
7102 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;7024 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
7103 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {7025 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
7104 const err_llvm_ty = (try o.lowerType(Type.anyerror)).toLlvm(&o.builder);
7105 if (operand_is_ptr) {7026 if (operand_is_ptr) {
7106 return operand;7027 return operand;
7107 } else {7028 } else {
7108 return err_llvm_ty.constInt(0, .False);7029 return (try o.builder.intConst(Builder.Type.err_int, 0)).toLlvm(&o.builder);
7109 }7030 }
7110 }7031 }
71117032
...@@ -7193,7 +7114,7 @@ pub const FuncGen = struct {...@@ -7193,7 +7114,7 @@ pub const FuncGen = struct {
7193 const mod = o.module;7114 const mod = o.module;
7194 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7115 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7195 const payload_ty = self.typeOf(ty_op.operand);7116 const payload_ty = self.typeOf(ty_op.operand);
7196 const non_null_bit = Builder.Type.i8.toLlvm(&o.builder).constInt(1, .False);7117 const non_null_bit = (try o.builder.intConst(.i8, 1)).toLlvm(&o.builder);
7197 comptime assert(optional_layout_version == 3);7118 comptime assert(optional_layout_version == 3);
7198 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;7119 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return non_null_bit;
7199 const operand = try self.resolveInst(ty_op.operand);7120 const operand = try self.resolveInst(ty_op.operand);
...@@ -7278,22 +7199,24 @@ pub const FuncGen = struct {...@@ -7278,22 +7199,24 @@ pub const FuncGen = struct {
7278 }7199 }
72797200
7280 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7201 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7202 const o = self.dg.object;
7281 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7203 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7282 const index = pl_op.payload;7204 const index = pl_op.payload;
7283 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7284 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.size", &.{.i32});7205 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.size", &.{.i32});
7285 const args: [1]*llvm.Value = .{llvm_u32.constInt(index, .False)};7206 const args: [1]*llvm.Value = .{
7207 (try o.builder.intConst(.i32, index)).toLlvm(&o.builder),
7208 };
7286 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");7209 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
7287 }7210 }
72887211
7289 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {7212 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
7213 const o = self.dg.object;
7290 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7214 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7291 const index = pl_op.payload;7215 const index = pl_op.payload;
7292 const operand = try self.resolveInst(pl_op.operand);7216 const operand = try self.resolveInst(pl_op.operand);
7293 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7294 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.grow", &.{.i32});7217 const llvm_fn = try self.getIntrinsic("llvm.wasm.memory.grow", &.{.i32});
7295 const args: [2]*llvm.Value = .{7218 const args: [2]*llvm.Value = .{
7296 llvm_u32.constInt(index, .False),7219 (try o.builder.intConst(.i32, index)).toLlvm(&o.builder),
7297 operand,7220 operand,
7298 };7221 };
7299 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");7222 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, "");
...@@ -7571,24 +7494,23 @@ pub const FuncGen = struct {...@@ -7571,24 +7494,23 @@ pub const FuncGen = struct {
7571 return self.buildFloatOp(.floor, inst_ty, 1, .{result});7494 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
7572 }7495 }
7573 if (scalar_ty.isSignedInt(mod)) {7496 if (scalar_ty.isSignedInt(mod)) {
7574 const inst_llvm_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder);7497 const inst_llvm_ty = try o.lowerType(inst_ty);
7575 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;7498 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7576 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {7499 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7577 const vec_len = inst_ty.vectorLen(mod);7500 const vec_len = inst_ty.vectorLen(mod);
7578 const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
75797501
7580 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);7502 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
7581 defer self.gpa.free(shifts);7503 defer self.gpa.free(shifts);
75827504
7583 @memset(shifts, scalar_llvm_ty.constInt(scalar_bit_size_minus_one, .False));7505 @memset(shifts, (try o.builder.intConst(try o.lowerType(scalar_ty), scalar_bit_size_minus_one)).toLlvm(&o.builder));
7584 break :const_vector llvm.constVector(shifts.ptr, vec_len);7506 break :const_vector llvm.constVector(shifts.ptr, vec_len);
7585 } else inst_llvm_ty.constInt(scalar_bit_size_minus_one, .False);7507 } else (try o.builder.intConst(inst_llvm_ty, scalar_bit_size_minus_one)).toLlvm(&o.builder);
75867508
7587 const div = self.builder.buildSDiv(lhs, rhs, "");7509 const div = self.builder.buildSDiv(lhs, rhs, "");
7588 const rem = self.builder.buildSRem(lhs, rhs, "");7510 const rem = self.builder.buildSRem(lhs, rhs, "");
7589 const div_sign = self.builder.buildXor(lhs, rhs, "");7511 const div_sign = self.builder.buildXor(lhs, rhs, "");
7590 const div_sign_mask = self.builder.buildAShr(div_sign, bit_size_minus_one, "");7512 const div_sign_mask = self.builder.buildAShr(div_sign, bit_size_minus_one, "");
7591 const zero = inst_llvm_ty.constNull();7513 const zero = inst_llvm_ty.toLlvm(&o.builder).constNull();
7592 const rem_nonzero = self.builder.buildICmp(.NE, rem, zero, "");7514 const rem_nonzero = self.builder.buildICmp(.NE, rem, zero, "");
7593 const correction = self.builder.buildSelect(rem_nonzero, div_sign_mask, zero, "");7515 const correction = self.builder.buildSelect(rem_nonzero, div_sign_mask, zero, "");
7594 return self.builder.buildNSWAdd(div, correction, "");7516 return self.builder.buildNSWAdd(div, correction, "");
...@@ -7637,14 +7559,14 @@ pub const FuncGen = struct {...@@ -7637,14 +7559,14 @@ pub const FuncGen = struct {
7637 const lhs = try self.resolveInst(bin_op.lhs);7559 const lhs = try self.resolveInst(bin_op.lhs);
7638 const rhs = try self.resolveInst(bin_op.rhs);7560 const rhs = try self.resolveInst(bin_op.rhs);
7639 const inst_ty = self.typeOfIndex(inst);7561 const inst_ty = self.typeOfIndex(inst);
7640 const inst_llvm_ty = (try o.lowerType(inst_ty)).toLlvm(&o.builder);7562 const inst_llvm_ty = try o.lowerType(inst_ty);
7641 const scalar_ty = inst_ty.scalarType(mod);7563 const scalar_ty = inst_ty.scalarType(mod);
76427564
7643 if (scalar_ty.isRuntimeFloat()) {7565 if (scalar_ty.isRuntimeFloat()) {
7644 const a = try self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });7566 const a = try self.buildFloatOp(.fmod, inst_ty, 2, .{ lhs, rhs });
7645 const b = try self.buildFloatOp(.add, inst_ty, 2, .{ a, rhs });7567 const b = try self.buildFloatOp(.add, inst_ty, 2, .{ a, rhs });
7646 const c = try self.buildFloatOp(.fmod, inst_ty, 2, .{ b, rhs });7568 const c = try self.buildFloatOp(.fmod, inst_ty, 2, .{ b, rhs });
7647 const zero = inst_llvm_ty.constNull();7569 const zero = inst_llvm_ty.toLlvm(&o.builder).constNull();
7648 const ltz = try self.buildFloatCmp(.lt, inst_ty, .{ lhs, zero });7570 const ltz = try self.buildFloatCmp(.lt, inst_ty, .{ lhs, zero });
7649 return self.builder.buildSelect(ltz, c, a, "");7571 return self.builder.buildSelect(ltz, c, a, "");
7650 }7572 }
...@@ -7652,20 +7574,19 @@ pub const FuncGen = struct {...@@ -7652,20 +7574,19 @@ pub const FuncGen = struct {
7652 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;7574 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
7653 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {7575 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
7654 const vec_len = inst_ty.vectorLen(mod);7576 const vec_len = inst_ty.vectorLen(mod);
7655 const scalar_llvm_ty = (try o.lowerType(scalar_ty)).toLlvm(&o.builder);
76567577
7657 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);7578 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
7658 defer self.gpa.free(shifts);7579 defer self.gpa.free(shifts);
76597580
7660 @memset(shifts, scalar_llvm_ty.constInt(scalar_bit_size_minus_one, .False));7581 @memset(shifts, (try o.builder.intConst(try o.lowerType(scalar_ty), scalar_bit_size_minus_one)).toLlvm(&o.builder));
7661 break :const_vector llvm.constVector(shifts.ptr, vec_len);7582 break :const_vector llvm.constVector(shifts.ptr, vec_len);
7662 } else inst_llvm_ty.constInt(scalar_bit_size_minus_one, .False);7583 } else (try o.builder.intConst(inst_llvm_ty, scalar_bit_size_minus_one)).toLlvm(&o.builder);
76637584
7664 const rem = self.builder.buildSRem(lhs, rhs, "");7585 const rem = self.builder.buildSRem(lhs, rhs, "");
7665 const div_sign = self.builder.buildXor(lhs, rhs, "");7586 const div_sign = self.builder.buildXor(lhs, rhs, "");
7666 const div_sign_mask = self.builder.buildAShr(div_sign, bit_size_minus_one, "");7587 const div_sign_mask = self.builder.buildAShr(div_sign, bit_size_minus_one, "");
7667 const rhs_masked = self.builder.buildAnd(rhs, div_sign_mask, "");7588 const rhs_masked = self.builder.buildAnd(rhs, div_sign_mask, "");
7668 const zero = inst_llvm_ty.constNull();7589 const zero = inst_llvm_ty.toLlvm(&o.builder).constNull();
7669 const rem_nonzero = self.builder.buildICmp(.NE, rem, zero, "");7590 const rem_nonzero = self.builder.buildICmp(.NE, rem, zero, "");
7670 const correction = self.builder.buildSelect(rem_nonzero, rhs_masked, zero, "");7591 const correction = self.builder.buildSelect(rem_nonzero, rhs_masked, zero, "");
7671 return self.builder.buildNSWAdd(rem, correction, "");7592 return self.builder.buildNSWAdd(rem, correction, "");
...@@ -7789,14 +7710,14 @@ pub const FuncGen = struct {...@@ -7789,14 +7710,14 @@ pub const FuncGen = struct {
7789 result_vector: *llvm.Value,7710 result_vector: *llvm.Value,
7790 vector_len: usize,7711 vector_len: usize,
7791 ) !*llvm.Value {7712 ) !*llvm.Value {
7713 const o = self.dg.object;
7792 const args_len = @as(c_uint, @intCast(args_vectors.len));7714 const args_len = @as(c_uint, @intCast(args_vectors.len));
7793 const llvm_i32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
7794 assert(args_len <= 3);7715 assert(args_len <= 3);
77957716
7796 var i: usize = 0;7717 var i: usize = 0;
7797 var result = result_vector;7718 var result = result_vector;
7798 while (i < vector_len) : (i += 1) {7719 while (i < vector_len) : (i += 1) {
7799 const index_i32 = llvm_i32.constInt(i, .False);7720 const index_i32 = (try o.builder.intConst(.i32, i)).toLlvm(&o.builder);
78007721
7801 var args: [3]*llvm.Value = undefined;7722 var args: [3]*llvm.Value = undefined;
7802 for (args_vectors, 0..) |arg_vector, k| {7723 for (args_vectors, 0..) |arg_vector, k| {
...@@ -7882,7 +7803,7 @@ pub const FuncGen = struct {...@@ -7882,7 +7803,7 @@ pub const FuncGen = struct {
7882 .i32,7803 .i32,
7883 );7804 );
78847805
7885 const zero = Builder.Type.i32.toLlvm(&o.builder).constInt(0, .False);7806 const zero = (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder);
7886 const int_pred: llvm.IntPredicate = switch (pred) {7807 const int_pred: llvm.IntPredicate = switch (pred) {
7887 .eq => .EQ,7808 .eq => .EQ,
7888 .neq => .NE,7809 .neq => .NE,
...@@ -7973,17 +7894,17 @@ pub const FuncGen = struct {...@@ -7973,17 +7894,17 @@ pub const FuncGen = struct {
7973 .neg => {7894 .neg => {
7974 // In this case we can generate a softfloat negation by XORing the7895 // In this case we can generate a softfloat negation by XORing the
7975 // bits with a constant.7896 // bits with a constant.
7976 const int_llvm_ty = (try o.builder.intType(@intCast(float_bits))).toLlvm(&o.builder);7897 const int_ty = try o.builder.intType(@intCast(float_bits));
7977 const one = int_llvm_ty.constInt(1, .False);7898 const one = (try o.builder.intConst(int_ty, 1)).toLlvm(&o.builder);
7978 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);7899 const shift_amt = try o.builder.intConst(int_ty, float_bits - 1);
7979 const sign_mask = one.constShl(shift_amt);7900 const sign_mask = one.constShl(shift_amt.toLlvm(&o.builder));
7980 const result = if (ty.zigTypeTag(mod) == .Vector) blk: {7901 const result = if (ty.zigTypeTag(mod) == .Vector) blk: {
7981 const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(mod), sign_mask, "");7902 const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(mod), sign_mask, "");
7982 const cast_ty = int_llvm_ty.vectorType(ty.vectorLen(mod));7903 const cast_ty = try o.builder.vectorType(.normal, ty.vectorLen(mod), int_ty);
7983 const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, "");7904 const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty.toLlvm(&o.builder), "");
7984 break :blk self.builder.buildXor(bitcasted_operand, splat_sign_mask, "");7905 break :blk self.builder.buildXor(bitcasted_operand, splat_sign_mask, "");
7985 } else blk: {7906 } else blk: {
7986 const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, "");7907 const bitcasted_operand = self.builder.buildBitCast(params[0], int_ty.toLlvm(&o.builder), "");
7987 break :blk self.builder.buildXor(bitcasted_operand, sign_mask, "");7908 break :blk self.builder.buildXor(bitcasted_operand, sign_mask, "");
7988 };7909 };
7989 return self.builder.buildBitCast(result, llvm_ty.toLlvm(&o.builder), "");7910 return self.builder.buildBitCast(result, llvm_ty.toLlvm(&o.builder), "");
...@@ -8191,9 +8112,9 @@ pub const FuncGen = struct {...@@ -8191,9 +8112,9 @@ pub const FuncGen = struct {
8191 // poison value."8112 // poison value."
8192 // However Zig semantics says that saturating shift left can never produce8113 // However Zig semantics says that saturating shift left can never produce
8193 // undefined; instead it saturates.8114 // undefined; instead it saturates.
8194 const lhs_scalar_llvm_ty = (try o.lowerType(lhs_scalar_ty)).toLlvm(&o.builder);8115 const lhs_scalar_llvm_ty = try o.lowerType(lhs_scalar_ty);
8195 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);8116 const bits = (try o.builder.intConst(lhs_scalar_llvm_ty, lhs_bits)).toLlvm(&o.builder);
8196 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();8117 const lhs_max = (try o.builder.intConst(lhs_scalar_llvm_ty, -1)).toLlvm(&o.builder);
8197 if (rhs_ty.zigTypeTag(mod) == .Vector) {8118 if (rhs_ty.zigTypeTag(mod) == .Vector) {
8198 const vec_len = rhs_ty.vectorLen(mod);8119 const vec_len = rhs_ty.vectorLen(mod);
8199 const bits_vec = self.builder.buildVectorSplat(vec_len, bits, "");8120 const bits_vec = self.builder.buildVectorSplat(vec_len, bits, "");
...@@ -8382,17 +8303,19 @@ pub const FuncGen = struct {...@@ -8382,17 +8303,19 @@ pub const FuncGen = struct {
8382 } else {8303 } else {
8383 // If the ABI size of the element type is not evenly divisible by size in bits;8304 // If the ABI size of the element type is not evenly divisible by size in bits;
8384 // a simple bitcast will not work, and we fall back to extractelement.8305 // a simple bitcast will not work, and we fall back to extractelement.
8385 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8306 const llvm_usize = try o.lowerType(Type.usize);
8386 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);8307 const zero = try o.builder.intConst(llvm_usize, 0);
8387 const zero = llvm_usize.constNull();
8388 const vector_len = operand_ty.arrayLen(mod);8308 const vector_len = operand_ty.arrayLen(mod);
8389 var i: u64 = 0;8309 var i: u64 = 0;
8390 while (i < vector_len) : (i += 1) {8310 while (i < vector_len) : (i += 1) {
8391 const index_usize = llvm_usize.constInt(i, .False);8311 const index_usize = try o.builder.intConst(llvm_usize, i);
8392 const index_u32 = llvm_u32.constInt(i, .False);8312 const index_u32 = try o.builder.intConst(.i32, i);
8393 const indexes: [2]*llvm.Value = .{ zero, index_usize };8313 const indexes: [2]*llvm.Value = .{
8314 zero.toLlvm(&o.builder),
8315 index_usize.toLlvm(&o.builder),
8316 };
8394 const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, "");8317 const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, "");
8395 const elem = self.builder.buildExtractElement(operand, index_u32, "");8318 const elem = self.builder.buildExtractElement(operand, index_u32.toLlvm(&o.builder), "");
8396 _ = self.builder.buildStore(elem, elem_ptr);8319 _ = self.builder.buildStore(elem, elem_ptr);
8397 }8320 }
8398 }8321 }
...@@ -8416,19 +8339,21 @@ pub const FuncGen = struct {...@@ -8416,19 +8339,21 @@ pub const FuncGen = struct {
8416 // a simple bitcast will not work, and we fall back to extractelement.8339 // a simple bitcast will not work, and we fall back to extractelement.
8417 const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);8340 const array_llvm_ty = (try o.lowerType(operand_ty)).toLlvm(&o.builder);
8418 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);8341 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
8419 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8342 const llvm_usize = try o.lowerType(Type.usize);
8420 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);8343 const zero = try o.builder.intConst(llvm_usize, 0);
8421 const zero = llvm_usize.constNull();
8422 const vector_len = operand_ty.arrayLen(mod);8344 const vector_len = operand_ty.arrayLen(mod);
8423 var vector = llvm_vector_ty.getUndef();8345 var vector = llvm_vector_ty.getUndef();
8424 var i: u64 = 0;8346 var i: u64 = 0;
8425 while (i < vector_len) : (i += 1) {8347 while (i < vector_len) : (i += 1) {
8426 const index_usize = llvm_usize.constInt(i, .False);8348 const index_usize = try o.builder.intConst(llvm_usize, i);
8427 const index_u32 = llvm_u32.constInt(i, .False);8349 const index_u32 = try o.builder.intConst(.i32, i);
8428 const indexes: [2]*llvm.Value = .{ zero, index_usize };8350 const indexes: [2]*llvm.Value = .{
8351 zero.toLlvm(&o.builder),
8352 index_usize.toLlvm(&o.builder),
8353 };
8429 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indexes, indexes.len, "");8354 const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indexes, indexes.len, "");
8430 const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");8355 const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
8431 vector = self.builder.buildInsertElement(vector, elem, index_u32, "");8356 vector = self.builder.buildInsertElement(vector, elem, index_u32.toLlvm(&o.builder), "");
8432 }8357 }
84338358
8434 return vector;8359 return vector;
...@@ -8563,14 +8488,13 @@ pub const FuncGen = struct {...@@ -8563,14 +8488,13 @@ pub const FuncGen = struct {
8563 // Even if safety is disabled, we still emit a memset to undefined since it conveys8488 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8564 // extra information to LLVM. However, safety makes the difference between using8489 // extra information to LLVM. However, safety makes the difference between using
8565 // 0xaa or actual undefined for the fill byte.8490 // 0xaa or actual undefined for the fill byte.
8566 const u8_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
8567 const fill_byte = if (safety)8491 const fill_byte = if (safety)
8568 u8_llvm_ty.constInt(0xaa, .False)8492 (try o.builder.intConst(.i8, 0xaa)).toLlvm(&o.builder)
8569 else8493 else
8570 u8_llvm_ty.getUndef();8494 Builder.Type.i8.toLlvm(&o.builder).getUndef();
8571 const operand_size = operand_ty.abiSize(mod);8495 const operand_size = operand_ty.abiSize(mod);
8572 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8496 const usize_ty = try o.lowerType(Type.usize);
8573 const len = usize_llvm_ty.constInt(operand_size, .False);8497 const len = (try o.builder.intConst(usize_ty, operand_size)).toLlvm(&o.builder);
8574 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8498 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8575 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));8499 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
8576 if (safety and mod.comp.bin_file.options.valgrind) {8500 if (safety and mod.comp.bin_file.options.valgrind) {
...@@ -8855,7 +8779,6 @@ pub const FuncGen = struct {...@@ -8855,7 +8779,6 @@ pub const FuncGen = struct {
8855 const ptr_ty = self.typeOf(bin_op.lhs);8779 const ptr_ty = self.typeOf(bin_op.lhs);
8856 const elem_ty = self.typeOf(bin_op.rhs);8780 const elem_ty = self.typeOf(bin_op.rhs);
8857 const dest_ptr_align = ptr_ty.ptrAlignment(mod);8781 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
8858 const u8_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
8859 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);8782 const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty);
8860 const is_volatile = ptr_ty.isVolatilePtr(mod);8783 const is_volatile = ptr_ty.isVolatilePtr(mod);
88618784
...@@ -8873,9 +8796,9 @@ pub const FuncGen = struct {...@@ -8873,9 +8796,9 @@ pub const FuncGen = struct {
8873 // extra information to LLVM. However, safety makes the difference between using8796 // extra information to LLVM. However, safety makes the difference between using
8874 // 0xaa or actual undefined for the fill byte.8797 // 0xaa or actual undefined for the fill byte.
8875 const fill_byte = if (safety)8798 const fill_byte = if (safety)
8876 u8_llvm_ty.constInt(0xaa, .False)8799 (try o.builder.intConst(.i8, 0xaa)).toLlvm(&o.builder)
8877 else8800 else
8878 u8_llvm_ty.getUndef();8801 Builder.Type.i8.toLlvm(&o.builder).getUndef();
8879 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8802 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8880 if (intrinsic_len0_traps) {8803 if (intrinsic_len0_traps) {
8881 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8804 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);
...@@ -8946,10 +8869,10 @@ pub const FuncGen = struct {...@@ -8946,10 +8869,10 @@ pub const FuncGen = struct {
8946 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");8869 const body_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetBody");
8947 const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd");8870 const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd");
89488871
8949 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);8872 const usize_ty = try o.lowerType(Type.usize);
8950 const len = switch (ptr_ty.ptrSize(mod)) {8873 const len = switch (ptr_ty.ptrSize(mod)) {
8951 .Slice => self.builder.buildExtractValue(dest_slice, 1, ""),8874 .Slice => self.builder.buildExtractValue(dest_slice, 1, ""),
8952 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),8875 .One => (try o.builder.intConst(usize_ty, ptr_ty.childType(mod).arrayLen(mod))).toLlvm(&o.builder),
8953 .Many, .C => unreachable,8876 .Many, .C => unreachable,
8954 };8877 };
8955 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);8878 const elem_llvm_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);
...@@ -8971,7 +8894,7 @@ pub const FuncGen = struct {...@@ -8971,7 +8894,7 @@ pub const FuncGen = struct {
8971 it_ptr_alignment,8894 it_ptr_alignment,
8972 value,8895 value,
8973 elem_abi_alignment,8896 elem_abi_alignment,
8974 llvm_usize_ty.constInt(elem_abi_size, .False),8897 (try o.builder.intConst(usize_ty, elem_abi_size)).toLlvm(&o.builder),
8975 is_volatile,8898 is_volatile,
8976 );8899 );
8977 } else {8900 } else {
...@@ -8979,7 +8902,9 @@ pub const FuncGen = struct {...@@ -8979,7 +8902,9 @@ pub const FuncGen = struct {
8979 store_inst.setAlignment(it_ptr_alignment);8902 store_inst.setAlignment(it_ptr_alignment);
8980 store_inst.setVolatile(llvm.Bool.fromBool(is_volatile));8903 store_inst.setVolatile(llvm.Bool.fromBool(is_volatile));
8981 }8904 }
8982 const one_gep = [_]*llvm.Value{llvm_usize_ty.constInt(1, .False)};8905 const one_gep = [_]*llvm.Value{
8906 (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder),
8907 };
8983 const next_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, it_ptr, &one_gep, one_gep.len, "");8908 const next_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, it_ptr, &one_gep, one_gep.len, "");
8984 _ = self.builder.buildBr(loop_block);8909 _ = self.builder.buildBr(loop_block);
89858910
...@@ -9194,24 +9119,20 @@ pub const FuncGen = struct {...@@ -9194,24 +9119,20 @@ pub const FuncGen = struct {
9194 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte9119 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
9195 // The truncated result at the end will be the correct bswap9120 // The truncated result at the end will be the correct bswap
9196 const scalar_ty = try o.builder.intType(@intCast(bits + 8));9121 const scalar_ty = try o.builder.intType(@intCast(bits + 8));
9197 const scalar_llvm_ty = scalar_ty.toLlvm(&o.builder);
9198 if (operand_ty.zigTypeTag(mod) == .Vector) {9122 if (operand_ty.zigTypeTag(mod) == .Vector) {
9199 const vec_len = operand_ty.vectorLen(mod);9123 const vec_len = operand_ty.vectorLen(mod);
9200 operand_llvm_ty = try o.builder.vectorType(.normal, vec_len, scalar_ty);9124 operand_llvm_ty = try o.builder.vectorType(.normal, vec_len, scalar_ty);
92019125
9202 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);9126 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
9203 defer self.gpa.free(shifts);9127 defer self.gpa.free(shifts);
92049128 @memset(shifts, (try o.builder.intConst(scalar_ty, 8)).toLlvm(&o.builder));
9205 for (shifts) |*elem| {
9206 elem.* = scalar_llvm_ty.constInt(8, .False);
9207 }
9208 const shift_vec = llvm.constVector(shifts.ptr, vec_len);9129 const shift_vec = llvm.constVector(shifts.ptr, vec_len);
92099130
9210 const extended = self.builder.buildZExt(operand, operand_llvm_ty.toLlvm(&o.builder), "");9131 const extended = self.builder.buildZExt(operand, operand_llvm_ty.toLlvm(&o.builder), "");
9211 operand = self.builder.buildShl(extended, shift_vec, "");9132 operand = self.builder.buildShl(extended, shift_vec, "");
9212 } else {9133 } else {
9213 const extended = self.builder.buildZExt(operand, scalar_llvm_ty, "");9134 const extended = self.builder.buildZExt(operand, scalar_ty.toLlvm(&o.builder), "");
9214 operand = self.builder.buildShl(extended, scalar_llvm_ty.constInt(8, .False), "");9135 operand = self.builder.buildShl(extended, (try o.builder.intConst(scalar_ty, 8)).toLlvm(&o.builder), "");
9215 operand_llvm_ty = scalar_ty;9136 operand_llvm_ty = scalar_ty;
9216 }9137 }
9217 bits = bits + 8;9138 bits = bits + 8;
...@@ -9263,14 +9184,14 @@ pub const FuncGen = struct {...@@ -9263,14 +9184,14 @@ pub const FuncGen = struct {
92639184
9264 self.builder.positionBuilderAtEnd(end_block);9185 self.builder.positionBuilderAtEnd(end_block);
92659186
9266 const llvm_type = Builder.Type.i1.toLlvm(&o.builder);
9267 const incoming_values: [2]*llvm.Value = .{9187 const incoming_values: [2]*llvm.Value = .{
9268 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),9188 Builder.Constant.true.toLlvm(&o.builder),
9189 Builder.Constant.false.toLlvm(&o.builder),
9269 };9190 };
9270 const incoming_blocks: [2]*llvm.BasicBlock = .{9191 const incoming_blocks: [2]*llvm.BasicBlock = .{
9271 valid_block, invalid_block,9192 valid_block, invalid_block,
9272 };9193 };
9273 const phi_node = self.builder.buildPhi(llvm_type, "");9194 const phi_node = self.builder.buildPhi(Builder.Type.i1.toLlvm(&o.builder), "");
9274 phi_node.addIncoming(&incoming_values, &incoming_blocks, 2);9195 phi_node.addIncoming(&incoming_values, &incoming_blocks, 2);
9275 return phi_node;9196 return phi_node;
9276 }9197 }
...@@ -9346,10 +9267,10 @@ pub const FuncGen = struct {...@@ -9346,10 +9267,10 @@ pub const FuncGen = struct {
9346 switch_instr.addCase(this_tag_int_value, named_block);9267 switch_instr.addCase(this_tag_int_value, named_block);
9347 }9268 }
9348 self.builder.positionBuilderAtEnd(named_block);9269 self.builder.positionBuilderAtEnd(named_block);
9349 _ = self.builder.buildRet(Builder.Type.i1.toLlvm(&o.builder).constInt(1, .False));9270 _ = self.builder.buildRet(Builder.Constant.true.toLlvm(&o.builder));
93509271
9351 self.builder.positionBuilderAtEnd(unnamed_block);9272 self.builder.positionBuilderAtEnd(unnamed_block);
9352 _ = self.builder.buildRet(Builder.Type.i1.toLlvm(&o.builder).constInt(0, .False));9273 _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder));
93539274
9354 try o.builder.llvm_globals.append(self.gpa, fn_val);9275 try o.builder.llvm_globals.append(self.gpa, fn_val);
9355 _ = try o.builder.addGlobal(llvm_fn_name, global);9276 _ = try o.builder.addGlobal(llvm_fn_name, global);
...@@ -9384,7 +9305,7 @@ pub const FuncGen = struct {...@@ -9384,7 +9305,7 @@ pub const FuncGen = struct {
9384 const slice_ty = Type.slice_const_u8_sentinel_0;9305 const slice_ty = Type.slice_const_u8_sentinel_0;
9385 const ret_ty = try o.lowerType(slice_ty);9306 const ret_ty = try o.lowerType(slice_ty);
9386 const llvm_ret_ty = ret_ty.toLlvm(&o.builder);9307 const llvm_ret_ty = ret_ty.toLlvm(&o.builder);
9387 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);9308 const usize_ty = try o.lowerType(Type.usize);
9388 const slice_alignment = slice_ty.abiAlignment(mod);9309 const slice_alignment = slice_ty.abiAlignment(mod);
93899310
9390 const fn_type = try o.builder.fnType(ret_ty, &.{9311 const fn_type = try o.builder.fnType(ret_ty, &.{
...@@ -9421,9 +9342,9 @@ pub const FuncGen = struct {...@@ -9421,9 +9342,9 @@ pub const FuncGen = struct {
9421 const tag_int_value = fn_val.getParam(0);9342 const tag_int_value = fn_val.getParam(0);
9422 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @as(c_uint, @intCast(enum_type.names.len)));9343 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @as(c_uint, @intCast(enum_type.names.len)));
94239344
9424 const array_ptr_indices = [_]*llvm.Value{9345 const array_ptr_indices: [2]*llvm.Value = .{
9425 usize_llvm_ty.constNull(), usize_llvm_ty.constNull(),9346 (try o.builder.intConst(usize_ty, 0)).toLlvm(&o.builder),
9426 };9347 } ** 2;
94279348
9428 for (enum_type.names, 0..) |name_ip, field_index_usize| {9349 for (enum_type.names, 0..) |name_ip, field_index_usize| {
9429 const field_index = @as(u32, @intCast(field_index_usize));9350 const field_index = @as(u32, @intCast(field_index_usize));
...@@ -9439,7 +9360,7 @@ pub const FuncGen = struct {...@@ -9439,7 +9360,7 @@ pub const FuncGen = struct {
94399360
9440 const slice_fields = [_]*llvm.Value{9361 const slice_fields = [_]*llvm.Value{
9441 str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len),9362 str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len),
9442 usize_llvm_ty.constInt(name.len, .False),9363 (try o.builder.intConst(usize_ty, name.len)).toLlvm(&o.builder),
9443 };9364 };
9444 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);9365 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);
9445 const slice_global = o.llvm_module.addGlobal(slice_init.typeOf(), "");9366 const slice_global = o.llvm_module.addGlobal(slice_init.typeOf(), "");
...@@ -9555,16 +9476,14 @@ pub const FuncGen = struct {...@@ -9555,16 +9476,14 @@ pub const FuncGen = struct {
9555 const values = try self.gpa.alloc(*llvm.Value, mask_len);9476 const values = try self.gpa.alloc(*llvm.Value, mask_len);
9556 defer self.gpa.free(values);9477 defer self.gpa.free(values);
95579478
9558 const llvm_i32 = Builder.Type.i32.toLlvm(&o.builder);
9559
9560 for (values, 0..) |*val, i| {9479 for (values, 0..) |*val, i| {
9561 const elem = try mask.elemValue(mod, i);9480 const elem = try mask.elemValue(mod, i);
9562 if (elem.isUndef(mod)) {9481 if (elem.isUndef(mod)) {
9563 val.* = llvm_i32.getUndef();9482 val.* = Builder.Type.i32.toLlvm(&o.builder).getUndef();
9564 } else {9483 } else {
9565 const int = elem.toSignedInt(mod);9484 const int = elem.toSignedInt(mod);
9566 const unsigned = if (int >= 0) @as(u32, @intCast(int)) else @as(u32, @intCast(~int + a_len));9485 const unsigned = if (int >= 0) @as(u32, @intCast(int)) else @as(u32, @intCast(~int + a_len));
9567 val.* = llvm_i32.constInt(unsigned, .False);9486 val.* = (try o.builder.intConst(.i32, unsigned)).toLlvm(&o.builder);
9568 }9487 }
9569 }9488 }
95709489
...@@ -9592,13 +9511,13 @@ pub const FuncGen = struct {...@@ -9592,13 +9511,13 @@ pub const FuncGen = struct {
9592 accum_init: *llvm.Value,9511 accum_init: *llvm.Value,
9593 ) !*llvm.Value {9512 ) !*llvm.Value {
9594 const o = self.dg.object;9513 const o = self.dg.object;
9595 const llvm_usize_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);9514 const usize_ty = try o.lowerType(Type.usize);
9596 const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False);9515 const llvm_vector_len = try o.builder.intConst(usize_ty, vector_len);
9597 const llvm_result_ty = accum_init.typeOf();9516 const llvm_result_ty = accum_init.typeOf();
95989517
9599 // Allocate and initialize our mutable variables9518 // Allocate and initialize our mutable variables
9600 const i_ptr = try self.buildAlloca(llvm_usize_ty, null);9519 const i_ptr = try self.buildAlloca(usize_ty.toLlvm(&o.builder), null);
9601 _ = self.builder.buildStore(llvm_usize_ty.constInt(0, .False), i_ptr);9520 _ = self.builder.buildStore((try o.builder.intConst(usize_ty, 0)).toLlvm(&o.builder), i_ptr);
9602 const accum_ptr = try self.buildAlloca(llvm_result_ty, null);9521 const accum_ptr = try self.buildAlloca(llvm_result_ty, null);
9603 _ = self.builder.buildStore(accum_init, accum_ptr);9522 _ = self.builder.buildStore(accum_init, accum_ptr);
96049523
...@@ -9610,8 +9529,8 @@ pub const FuncGen = struct {...@@ -9610,8 +9529,8 @@ pub const FuncGen = struct {
9610 self.builder.positionBuilderAtEnd(loop);9529 self.builder.positionBuilderAtEnd(loop);
96119530
9612 // while (i < vec.len)9531 // while (i < vec.len)
9613 const i = self.builder.buildLoad(llvm_usize_ty, i_ptr, "");9532 const i = self.builder.buildLoad(usize_ty.toLlvm(&o.builder), i_ptr, "");
9614 const cond = self.builder.buildICmp(.ULT, i, llvm_vector_len, "");9533 const cond = self.builder.buildICmp(.ULT, i, llvm_vector_len.toLlvm(&o.builder), "");
9615 const loop_then = self.context.appendBasicBlock(self.llvm_func, "ReduceLoopThen");9534 const loop_then = self.context.appendBasicBlock(self.llvm_func, "ReduceLoopThen");
96169535
9617 _ = self.builder.buildCondBr(cond, loop_then, loop_exit);9536 _ = self.builder.buildCondBr(cond, loop_then, loop_exit);
...@@ -9627,7 +9546,7 @@ pub const FuncGen = struct {...@@ -9627,7 +9546,7 @@ pub const FuncGen = struct {
9627 _ = self.builder.buildStore(new_accum, accum_ptr);9546 _ = self.builder.buildStore(new_accum, accum_ptr);
96289547
9629 // i += 19548 // i += 1
9630 const new_i = self.builder.buildAdd(i, llvm_usize_ty.constInt(1, .False), "");9549 const new_i = self.builder.buildAdd(i, (try o.builder.intConst(usize_ty, 1)).toLlvm(&o.builder), "");
9631 _ = self.builder.buildStore(new_i, i_ptr);9550 _ = self.builder.buildStore(new_i, i_ptr);
9632 _ = self.builder.buildBr(loop);9551 _ = self.builder.buildBr(loop);
9633 }9552 }
...@@ -9731,13 +9650,11 @@ pub const FuncGen = struct {...@@ -9731,13 +9650,11 @@ pub const FuncGen = struct {
97319650
9732 switch (result_ty.zigTypeTag(mod)) {9651 switch (result_ty.zigTypeTag(mod)) {
9733 .Vector => {9652 .Vector => {
9734 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
9735
9736 var vector = llvm_result_ty.getUndef();9653 var vector = llvm_result_ty.getUndef();
9737 for (elements, 0..) |elem, i| {9654 for (elements, 0..) |elem, i| {
9738 const index_u32 = llvm_u32.constInt(i, .False);9655 const index_u32 = try o.builder.intConst(.i32, i);
9739 const llvm_elem = try self.resolveInst(elem);9656 const llvm_elem = try self.resolveInst(elem);
9740 vector = self.builder.buildInsertElement(vector, llvm_elem, index_u32, "");9657 vector = self.builder.buildInsertElement(vector, llvm_elem, index_u32.toLlvm(&o.builder), "");
9741 }9658 }
9742 return vector;9659 return vector;
9743 },9660 },
...@@ -9746,10 +9663,10 @@ pub const FuncGen = struct {...@@ -9746,10 +9663,10 @@ pub const FuncGen = struct {
9746 const struct_obj = mod.typeToStruct(result_ty).?;9663 const struct_obj = mod.typeToStruct(result_ty).?;
9747 assert(struct_obj.haveLayout());9664 assert(struct_obj.haveLayout());
9748 const big_bits = struct_obj.backing_int_ty.bitSize(mod);9665 const big_bits = struct_obj.backing_int_ty.bitSize(mod);
9749 const int_llvm_ty = (try o.builder.intType(@intCast(big_bits))).toLlvm(&o.builder);9666 const int_ty = try o.builder.intType(@intCast(big_bits));
9750 const fields = struct_obj.fields.values();9667 const fields = struct_obj.fields.values();
9751 comptime assert(Type.packed_struct_layout_version == 2);9668 comptime assert(Type.packed_struct_layout_version == 2);
9752 var running_int: *llvm.Value = int_llvm_ty.constNull();9669 var running_int = (try o.builder.intConst(int_ty, 0)).toLlvm(&o.builder);
9753 var running_bits: u16 = 0;9670 var running_bits: u16 = 0;
9754 for (elements, 0..) |elem, i| {9671 for (elements, 0..) |elem, i| {
9755 const field = fields[i];9672 const field = fields[i];
...@@ -9762,12 +9679,12 @@ pub const FuncGen = struct {...@@ -9762,12 +9679,12 @@ pub const FuncGen = struct {
9762 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9679 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9763 else9680 else
9764 self.builder.buildBitCast(non_int_val, small_int_ty, "");9681 self.builder.buildBitCast(non_int_val, small_int_ty, "");
9765 const shift_rhs = int_llvm_ty.constInt(running_bits, .False);9682 const shift_rhs = try o.builder.intConst(int_ty, running_bits);
9766 // If the field is as large as the entire packed struct, this9683 // If the field is as large as the entire packed struct, this
9767 // zext would go from, e.g. i16 to i16. This is legal with9684 // zext would go from, e.g. i16 to i16. This is legal with
9768 // constZExtOrBitCast but not legal with constZExt.9685 // constZExtOrBitCast but not legal with constZExt.
9769 const extended_int_val = self.builder.buildZExtOrBitCast(small_int_val, int_llvm_ty, "");9686 const extended_int_val = self.builder.buildZExtOrBitCast(small_int_val, int_ty.toLlvm(&o.builder), "");
9770 const shifted = self.builder.buildShl(extended_int_val, shift_rhs, "");9687 const shifted = self.builder.buildShl(extended_int_val, shift_rhs.toLlvm(&o.builder), "");
9771 running_int = self.builder.buildOr(running_int, shifted, "");9688 running_int = self.builder.buildOr(running_int, shifted, "");
9772 running_bits += ty_bit_size;9689 running_bits += ty_bit_size;
9773 }9690 }
...@@ -9775,18 +9692,20 @@ pub const FuncGen = struct {...@@ -9775,18 +9692,20 @@ pub const FuncGen = struct {
9775 }9692 }
97769693
9777 if (isByRef(result_ty, mod)) {9694 if (isByRef(result_ty, mod)) {
9778 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
9779 // TODO in debug builds init to undef so that the padding will be 0xaa9695 // TODO in debug builds init to undef so that the padding will be 0xaa
9780 // even if we fully populate the fields.9696 // even if we fully populate the fields.
9781 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9697 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
97829698
9783 var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined };9699 var indices: [2]*llvm.Value = .{
9700 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9701 undefined,
9702 };
9784 for (elements, 0..) |elem, i| {9703 for (elements, 0..) |elem, i| {
9785 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;9704 if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue;
97869705
9787 const llvm_elem = try self.resolveInst(elem);9706 const llvm_elem = try self.resolveInst(elem);
9788 const llvm_i = llvmField(result_ty, i, mod).?.index;9707 const llvm_i = llvmField(result_ty, i, mod).?.index;
9789 indices[1] = llvm_u32.constInt(llvm_i, .False);9708 indices[1] = (try o.builder.intConst(.i32, llvm_i)).toLlvm(&o.builder);
9790 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9709 const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9791 const field_ptr_ty = try mod.ptrType(.{9710 const field_ptr_ty = try mod.ptrType(.{
9792 .child = self.typeOf(elem).toIntern(),9711 .child = self.typeOf(elem).toIntern(),
...@@ -9815,7 +9734,7 @@ pub const FuncGen = struct {...@@ -9815,7 +9734,7 @@ pub const FuncGen = struct {
9815 .Array => {9734 .Array => {
9816 assert(isByRef(result_ty, mod));9735 assert(isByRef(result_ty, mod));
98179736
9818 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);9737 const usize_ty = try o.lowerType(Type.usize);
9819 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));9738 const alloca_inst = try self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
98209739
9821 const array_info = result_ty.arrayInfo(mod);9740 const array_info = result_ty.arrayInfo(mod);
...@@ -9825,8 +9744,8 @@ pub const FuncGen = struct {...@@ -9825,8 +9744,8 @@ pub const FuncGen = struct {
98259744
9826 for (elements, 0..) |elem, i| {9745 for (elements, 0..) |elem, i| {
9827 const indices: [2]*llvm.Value = .{9746 const indices: [2]*llvm.Value = .{
9828 llvm_usize.constNull(),9747 (try o.builder.intConst(usize_ty, 0)).toLlvm(&o.builder),
9829 llvm_usize.constInt(@as(c_uint, @intCast(i)), .False),9748 (try o.builder.intConst(usize_ty, i)).toLlvm(&o.builder),
9830 };9749 };
9831 const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9750 const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9832 const llvm_elem = try self.resolveInst(elem);9751 const llvm_elem = try self.resolveInst(elem);
...@@ -9834,8 +9753,8 @@ pub const FuncGen = struct {...@@ -9834,8 +9753,8 @@ pub const FuncGen = struct {
9834 }9753 }
9835 if (array_info.sentinel) |sent_val| {9754 if (array_info.sentinel) |sent_val| {
9836 const indices: [2]*llvm.Value = .{9755 const indices: [2]*llvm.Value = .{
9837 llvm_usize.constNull(),9756 (try o.builder.intConst(usize_ty, 0)).toLlvm(&o.builder),
9838 llvm_usize.constInt(@as(c_uint, @intCast(array_info.len)), .False),9757 (try o.builder.intConst(usize_ty, array_info.len)).toLlvm(&o.builder),
9839 };9758 };
9840 const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");9759 const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9841 const llvm_elem = try self.resolveValue(.{9760 const llvm_elem = try self.resolveValue(.{
...@@ -9858,7 +9777,7 @@ pub const FuncGen = struct {...@@ -9858,7 +9777,7 @@ pub const FuncGen = struct {
9858 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;9777 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
9859 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;9778 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
9860 const union_ty = self.typeOfIndex(inst);9779 const union_ty = self.typeOfIndex(inst);
9861 const union_llvm_ty = (try o.lowerType(union_ty)).toLlvm(&o.builder);9780 const union_llvm_ty = try o.lowerType(union_ty);
9862 const layout = union_ty.unionGetLayout(mod);9781 const layout = union_ty.unionGetLayout(mod);
9863 const union_obj = mod.typeToUnion(union_ty).?;9782 const union_obj = mod.typeToUnion(union_ty).?;
98649783
...@@ -9889,14 +9808,14 @@ pub const FuncGen = struct {...@@ -9889,14 +9808,14 @@ pub const FuncGen = struct {
9889 return null;9808 return null;
9890 }9809 }
9891 assert(!isByRef(union_ty, mod));9810 assert(!isByRef(union_ty, mod));
9892 return union_llvm_ty.constInt(tag_int, .False);9811 return (try o.builder.intConst(union_llvm_ty, tag_int)).toLlvm(&o.builder);
9893 }9812 }
9894 assert(isByRef(union_ty, mod));9813 assert(isByRef(union_ty, mod));
9895 // The llvm type of the alloca will be the named LLVM union type, and will not9814 // The llvm type of the alloca will be the named LLVM union type, and will not
9896 // necessarily match the format that we need, depending on which tag is active.9815 // necessarily match the format that we need, depending on which tag is active.
9897 // We must construct the correct unnamed struct type here, in order to then set9816 // We must construct the correct unnamed struct type here, in order to then set
9898 // the fields appropriately.9817 // the fields appropriately.
9899 const result_ptr = try self.buildAlloca(union_llvm_ty, layout.abi_align);9818 const result_ptr = try self.buildAlloca(union_llvm_ty.toLlvm(&o.builder), layout.abi_align);
9900 const llvm_payload = try self.resolveInst(extra.init);9819 const llvm_payload = try self.resolveInst(extra.init);
9901 assert(union_obj.haveFieldTypes());9820 assert(union_obj.haveFieldTypes());
9902 const field = union_obj.fields.values()[extra.field_index];9821 const field = union_obj.fields.values()[extra.field_index];
...@@ -9936,8 +9855,6 @@ pub const FuncGen = struct {...@@ -9936,8 +9855,6 @@ pub const FuncGen = struct {
99369855
9937 // Now we follow the layout as expressed above with GEP instructions to set the9856 // Now we follow the layout as expressed above with GEP instructions to set the
9938 // tag and the payload.9857 // tag and the payload.
9939 const index_type = Builder.Type.i32.toLlvm(&o.builder);
9940
9941 const field_ptr_ty = try mod.ptrType(.{9858 const field_ptr_ty = try mod.ptrType(.{
9942 .child = field.ty.toIntern(),9859 .child = field.ty.toIntern(),
9943 .flags = .{9860 .flags = .{
...@@ -9946,10 +9863,8 @@ pub const FuncGen = struct {...@@ -9946,10 +9863,8 @@ pub const FuncGen = struct {
9946 });9863 });
9947 if (layout.tag_size == 0) {9864 if (layout.tag_size == 0) {
9948 const indices: [3]*llvm.Value = .{9865 const indices: [3]*llvm.Value = .{
9949 index_type.constNull(),9866 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9950 index_type.constNull(),9867 } ** 3;
9951 index_type.constNull(),
9952 };
9953 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9868 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9954 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");9869 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
9955 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);9870 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
...@@ -9958,9 +9873,9 @@ pub const FuncGen = struct {...@@ -9958,9 +9873,9 @@ pub const FuncGen = struct {
99589873
9959 {9874 {
9960 const indices: [3]*llvm.Value = .{9875 const indices: [3]*llvm.Value = .{
9961 index_type.constNull(),9876 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9962 index_type.constInt(@intFromBool(layout.tag_align >= layout.payload_align), .False),9877 (try o.builder.intConst(.i32, @intFromBool(layout.tag_align >= layout.payload_align))).toLlvm(&o.builder),
9963 index_type.constNull(),9878 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9964 };9879 };
9965 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9880 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9966 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");9881 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
...@@ -9968,13 +9883,13 @@ pub const FuncGen = struct {...@@ -9968,13 +9883,13 @@ pub const FuncGen = struct {
9968 }9883 }
9969 {9884 {
9970 const indices: [2]*llvm.Value = .{9885 const indices: [2]*llvm.Value = .{
9971 index_type.constNull(),9886 (try o.builder.intConst(.i32, 0)).toLlvm(&o.builder),
9972 index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False),9887 (try o.builder.intConst(.i32, @intFromBool(layout.tag_align < layout.payload_align))).toLlvm(&o.builder),
9973 };9888 };
9974 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");9889 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
9975 const tag_llvm_ty = (try o.lowerType(union_obj.tag_ty)).toLlvm(&o.builder);9890 const tag_ty = try o.lowerType(union_obj.tag_ty);
9976 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);9891 const llvm_tag = try o.builder.intConst(tag_ty, tag_int);
9977 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);9892 const store_inst = self.builder.buildStore(llvm_tag.toLlvm(&o.builder), field_ptr);
9978 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));9893 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));
9979 }9894 }
99809895
...@@ -10031,12 +9946,11 @@ pub const FuncGen = struct {...@@ -10031,12 +9946,11 @@ pub const FuncGen = struct {
100319946
10032 const ptr = try self.resolveInst(prefetch.ptr);9947 const ptr = try self.resolveInst(prefetch.ptr);
100339948
10034 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
10035 const params = [_]*llvm.Value{9949 const params = [_]*llvm.Value{
10036 ptr,9950 ptr,
10037 llvm_u32.constInt(@intFromEnum(prefetch.rw), .False),9951 (try o.builder.intConst(.i32, @intFromEnum(prefetch.rw))).toLlvm(&o.builder),
10038 llvm_u32.constInt(prefetch.locality, .False),9952 (try o.builder.intConst(.i32, prefetch.locality)).toLlvm(&o.builder),
10039 llvm_u32.constInt(@intFromEnum(prefetch.cache), .False),9953 (try o.builder.intConst(.i32, @intFromEnum(prefetch.cache))).toLlvm(&o.builder),
10040 };9954 };
10041 _ = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");9955 _ = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
10042 return null;9956 return null;
...@@ -10053,13 +9967,11 @@ pub const FuncGen = struct {...@@ -10053,13 +9967,11 @@ pub const FuncGen = struct {
10053 }9967 }
100549968
10055 fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !?*llvm.Value {9969 fn amdgcnWorkIntrinsic(self: *FuncGen, dimension: u32, default: u32, comptime basename: []const u8) !?*llvm.Value {
10056 const llvm_u32 = Builder.Type.i32.toLlvm(&self.dg.object.builder);
10057
10058 const llvm_fn_name = switch (dimension) {9970 const llvm_fn_name = switch (dimension) {
10059 0 => basename ++ ".x",9971 0 => basename ++ ".x",
10060 1 => basename ++ ".y",9972 1 => basename ++ ".y",
10061 2 => basename ++ ".z",9973 2 => basename ++ ".z",
10062 else => return llvm_u32.constInt(default, .False),9974 else => return (try self.dg.object.builder.intConst(.i32, default)).toLlvm(&self.dg.object.builder),
10063 };9975 };
100649976
10065 const args: [0]*llvm.Value = .{};9977 const args: [0]*llvm.Value = .{};
...@@ -10084,9 +9996,8 @@ pub const FuncGen = struct {...@@ -10084,9 +9996,8 @@ pub const FuncGen = struct {
100849996
10085 const pl_op = self.air.instructions.items(.data)[inst].pl_op;9997 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
10086 const dimension = pl_op.payload;9998 const dimension = pl_op.payload;
10087 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);
10088 if (dimension >= 3) {9999 if (dimension >= 3) {
10089 return llvm_u32.constInt(1, .False);10000 return (try o.builder.intConst(.i32, 1)).toLlvm(&o.builder);
10090 }10001 }
1009110002
10092 // Fetch the dispatch pointer, which points to this structure:10003 // Fetch the dispatch pointer, which points to this structure:
...@@ -10099,7 +10010,9 @@ pub const FuncGen = struct {...@@ -10099,7 +10010,9 @@ pub const FuncGen = struct {
10099 // Load the work_group_* member from the struct as u16.10010 // Load the work_group_* member from the struct as u16.
10100 // Just treat the dispatch pointer as an array of u16 to keep things simple.10011 // Just treat the dispatch pointer as an array of u16 to keep things simple.
10101 const offset = 2 + dimension;10012 const offset = 2 + dimension;
10102 const index = [_]*llvm.Value{llvm_u32.constInt(offset, .False)};10013 const index = [_]*llvm.Value{
10014 (try o.builder.intConst(.i32, offset)).toLlvm(&o.builder),
10015 };
10103 const llvm_u16 = Builder.Type.i16.toLlvm(&o.builder);10016 const llvm_u16 = Builder.Type.i16.toLlvm(&o.builder);
10104 const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, "");10017 const workgroup_size_ptr = self.builder.buildInBoundsGEP(llvm_u16, dispatch_ptr, &index, index.len, "");
10105 const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, "");10018 const workgroup_size = self.builder.buildLoad(llvm_u16, workgroup_size_ptr, "");
...@@ -10145,18 +10058,17 @@ pub const FuncGen = struct {...@@ -10145,18 +10058,17 @@ pub const FuncGen = struct {
10145 opt_llvm_ty: *llvm.Type,10058 opt_llvm_ty: *llvm.Type,
10146 opt_handle: *llvm.Value,10059 opt_handle: *llvm.Value,
10147 is_by_ref: bool,10060 is_by_ref: bool,
10148 ) *llvm.Value {10061 ) Allocator.Error!*llvm.Value {
10149 const non_null_llvm_ty = Builder.Type.i8.toLlvm(&self.dg.object.builder);
10150 const field = b: {10062 const field = b: {
10151 if (is_by_ref) {10063 if (is_by_ref) {
10152 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");10064 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
10153 break :b self.builder.buildLoad(non_null_llvm_ty, field_ptr, "");10065 break :b self.builder.buildLoad(Builder.Type.i8.toLlvm(&self.dg.object.builder), field_ptr, "");
10154 }10066 }
10155 break :b self.builder.buildExtractValue(opt_handle, 1, "");10067 break :b self.builder.buildExtractValue(opt_handle, 1, "");
10156 };10068 };
10157 comptime assert(optional_layout_version == 3);10069 comptime assert(optional_layout_version == 3);
1015810070
10159 return self.builder.buildICmp(.NE, field, non_null_llvm_ty.constInt(0, .False), "");10071 return self.builder.buildICmp(.NE, field, (try self.dg.object.builder.intConst(.i8, 0)).toLlvm(&self.dg.object.builder), "");
10160 }10072 }
1016110073
10162 /// Assumes the optional is not pointer-like and payload has bits.10074 /// Assumes the optional is not pointer-like and payload has bits.
...@@ -10254,9 +10166,9 @@ pub const FuncGen = struct {...@@ -10254,9 +10166,9 @@ pub const FuncGen = struct {
10254 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);10166 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
10255 if (byte_offset == 0) return struct_ptr;10167 if (byte_offset == 0) return struct_ptr;
10256 const byte_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);10168 const byte_llvm_ty = Builder.Type.i8.toLlvm(&o.builder);
10257 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);10169 const usize_ty = try o.lowerType(Type.usize);
10258 const llvm_index = llvm_usize.constInt(byte_offset, .False);10170 const llvm_index = try o.builder.intConst(usize_ty, byte_offset);
10259 const indices: [1]*llvm.Value = .{llvm_index};10171 const indices: [1]*llvm.Value = .{llvm_index.toLlvm(&o.builder)};
10260 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");10172 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
10261 },10173 },
10262 else => {10174 else => {
...@@ -10269,9 +10181,8 @@ pub const FuncGen = struct {...@@ -10269,9 +10181,8 @@ pub const FuncGen = struct {
10269 // end of the struct. Treat our struct pointer as an array of two and get10181 // end of the struct. Treat our struct pointer as an array of two and get
10270 // the index to the element at index `1` to get a pointer to the end of10182 // the index to the element at index `1` to get a pointer to the end of
10271 // the struct.10183 // the struct.
10272 const llvm_u32 = Builder.Type.i32.toLlvm(&o.builder);10184 const llvm_index = try o.builder.intConst(.i32, @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)));
10273 const llvm_index = llvm_u32.constInt(@intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(mod)), .False);10185 const indices: [1]*llvm.Value = .{llvm_index.toLlvm(&o.builder)};
10274 const indices: [1]*llvm.Value = .{llvm_index};
10275 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");10186 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
10276 }10187 }
10277 },10188 },
...@@ -10311,14 +10222,14 @@ pub const FuncGen = struct {...@@ -10311,14 +10222,14 @@ pub const FuncGen = struct {
10311 const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder);10222 const pointee_llvm_ty = (try o.lowerType(pointee_type)).toLlvm(&o.builder);
10312 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));10223 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
10313 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);10224 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);
10314 const llvm_usize = (try o.lowerType(Type.usize)).toLlvm(&o.builder);10225 const usize_ty = try o.lowerType(Type.usize);
10315 const size_bytes = pointee_type.abiSize(mod);10226 const size_bytes = pointee_type.abiSize(mod);
10316 _ = fg.builder.buildMemCpy(10227 _ = fg.builder.buildMemCpy(
10317 result_ptr,10228 result_ptr,
10318 result_align,10229 result_align,
10319 ptr,10230 ptr,
10320 ptr_alignment,10231 ptr_alignment,
10321 llvm_usize.constInt(size_bytes, .False),10232 (try o.builder.intConst(usize_ty, size_bytes)).toLlvm(&o.builder),
10322 is_volatile,10233 is_volatile,
10323 );10234 );
10324 return result_ptr;10235 return result_ptr;
...@@ -10340,15 +10251,15 @@ pub const FuncGen = struct {...@@ -10340,15 +10251,15 @@ pub const FuncGen = struct {
1034010251
10341 assert(info.flags.vector_index != .runtime);10252 assert(info.flags.vector_index != .runtime);
10342 if (info.flags.vector_index != .none) {10253 if (info.flags.vector_index != .none) {
10343 const index_u32 = Builder.Type.i32.toLlvm(&o.builder).constInt(@intFromEnum(info.flags.vector_index), .False);10254 const index_u32 = try o.builder.intConst(.i32, @intFromEnum(info.flags.vector_index));
10344 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);10255 const vec_elem_ty = try o.lowerType(elem_ty);
10345 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);10256 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1034610257
10347 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");10258 const loaded_vector = self.builder.buildLoad(vec_ty.toLlvm(&o.builder), ptr, "");
10348 loaded_vector.setAlignment(ptr_alignment);10259 loaded_vector.setAlignment(ptr_alignment);
10349 loaded_vector.setVolatile(ptr_volatile);10260 loaded_vector.setVolatile(ptr_volatile);
1035010261
10351 return self.builder.buildExtractElement(loaded_vector, index_u32, "");10262 return self.builder.buildExtractElement(loaded_vector, index_u32.toLlvm(&o.builder), "");
10352 }10263 }
1035310264
10354 if (info.packed_offset.host_size == 0) {10265 if (info.packed_offset.host_size == 0) {
...@@ -10417,15 +10328,15 @@ pub const FuncGen = struct {...@@ -10417,15 +10328,15 @@ pub const FuncGen = struct {
1041710328
10418 assert(info.flags.vector_index != .runtime);10329 assert(info.flags.vector_index != .runtime);
10419 if (info.flags.vector_index != .none) {10330 if (info.flags.vector_index != .none) {
10420 const index_u32 = Builder.Type.i32.toLlvm(&o.builder).constInt(@intFromEnum(info.flags.vector_index), .False);10331 const index_u32 = try o.builder.intConst(.i32, @intFromEnum(info.flags.vector_index));
10421 const vec_elem_ty = (try o.lowerType(elem_ty)).toLlvm(&o.builder);10332 const vec_elem_ty = try o.lowerType(elem_ty);
10422 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);10333 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1042310334
10424 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");10335 const loaded_vector = self.builder.buildLoad(vec_ty.toLlvm(&o.builder), ptr, "");
10425 loaded_vector.setAlignment(ptr_alignment);10336 loaded_vector.setAlignment(ptr_alignment);
10426 loaded_vector.setVolatile(ptr_volatile);10337 loaded_vector.setVolatile(ptr_volatile);
1042710338
10428 const modified_vector = self.builder.buildInsertElement(loaded_vector, elem, index_u32, "");10339 const modified_vector = self.builder.buildInsertElement(loaded_vector, elem, index_u32.toLlvm(&o.builder), "");
1042910340
10430 const store_inst = self.builder.buildStore(modified_vector, ptr);10341 const store_inst = self.builder.buildStore(modified_vector, ptr);
10431 assert(ordering == .NotAtomic);10342 assert(ordering == .NotAtomic);
...@@ -10481,7 +10392,7 @@ pub const FuncGen = struct {...@@ -10481,7 +10392,7 @@ pub const FuncGen = struct {
10481 ptr_alignment,10392 ptr_alignment,
10482 elem,10393 elem,
10483 elem_ty.abiAlignment(mod),10394 elem_ty.abiAlignment(mod),
10484 (try o.lowerType(Type.usize)).toLlvm(&o.builder).constInt(size_bytes, .False),10395 (try o.builder.intConst(try o.lowerType(Type.usize), size_bytes)).toLlvm(&o.builder),
10485 info.flags.is_volatile,10396 info.flags.is_volatile,
10486 );10397 );
10487 }10398 }
...@@ -10489,10 +10400,10 @@ pub const FuncGen = struct {...@@ -10489,10 +10400,10 @@ pub const FuncGen = struct {
10489 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) Allocator.Error!void {10400 fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) Allocator.Error!void {
10490 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;10401 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
10491 const o = fg.dg.object;10402 const o = fg.dg.object;
10492 const usize_llvm_ty = (try o.lowerType(Type.usize)).toLlvm(&o.builder);10403 const usize_ty = try o.lowerType(Type.usize);
10493 const zero = usize_llvm_ty.constInt(0, .False);10404 const zero = (try o.builder.intConst(usize_ty, 0)).toLlvm(&o.builder);
10494 const req = usize_llvm_ty.constInt(VG_USERREQ__MAKE_MEM_UNDEFINED, .False);10405 const req = (try o.builder.intConst(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED)).toLlvm(&o.builder);
10495 const ptr_as_usize = fg.builder.buildPtrToInt(ptr, usize_llvm_ty, "");10406 const ptr_as_usize = fg.builder.buildPtrToInt(ptr, usize_ty.toLlvm(&o.builder), "");
10496 _ = try valgrindClientRequest(fg, zero, req, ptr_as_usize, len, zero, zero, zero);10407 _ = try valgrindClientRequest(fg, zero, req, ptr_as_usize, len, zero, zero, zero);
10497 }10408 }
1049810409
...@@ -10511,21 +10422,20 @@ pub const FuncGen = struct {...@@ -10511,21 +10422,20 @@ pub const FuncGen = struct {
10511 const target = mod.getTarget();10422 const target = mod.getTarget();
10512 if (!target_util.hasValgrindSupport(target)) return default_value;10423 if (!target_util.hasValgrindSupport(target)) return default_value;
1051310424
10514 const usize_ty = try o.lowerType(Type.usize);10425 const llvm_usize = try o.lowerType(Type.usize);
10515 const usize_llvm_ty = usize_ty.toLlvm(&o.builder);
10516 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));10426 const usize_alignment = @as(c_uint, @intCast(Type.usize.abiSize(mod)));
1051710427
10518 const array_llvm_ty = usize_llvm_ty.arrayType(6);10428 const array_llvm_ty = (try o.builder.arrayType(6, llvm_usize)).toLlvm(&o.builder);
10519 const array_ptr = fg.valgrind_client_request_array orelse a: {10429 const array_ptr = fg.valgrind_client_request_array orelse a: {
10520 const array_ptr = try fg.buildAlloca(array_llvm_ty, usize_alignment);10430 const array_ptr = try fg.buildAlloca(array_llvm_ty, usize_alignment);
10521 fg.valgrind_client_request_array = array_ptr;10431 fg.valgrind_client_request_array = array_ptr;
10522 break :a array_ptr;10432 break :a array_ptr;
10523 };10433 };
10524 const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 };10434 const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 };
10525 const zero = usize_llvm_ty.constInt(0, .False);10435 const zero = (try o.builder.intConst(llvm_usize, 0)).toLlvm(&o.builder);
10526 for (array_elements, 0..) |elem, i| {10436 for (array_elements, 0..) |elem, i| {
10527 const indexes = [_]*llvm.Value{10437 const indexes = [_]*llvm.Value{
10528 zero, usize_llvm_ty.constInt(@as(c_uint, @intCast(i)), .False),10438 zero, (try o.builder.intConst(llvm_usize, i)).toLlvm(&o.builder),
10529 };10439 };
10530 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");10440 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");
10531 const store_inst = fg.builder.buildStore(elem, elem_ptr);10441 const store_inst = fg.builder.buildStore(elem, elem_ptr);
...@@ -10563,8 +10473,8 @@ pub const FuncGen = struct {...@@ -10563,8 +10473,8 @@ pub const FuncGen = struct {
10563 else => unreachable,10473 else => unreachable,
10564 };10474 };
1056510475
10566 const fn_llvm_ty = (try o.builder.fnType(usize_ty, &(.{usize_ty} ** 2), .normal)).toLlvm(&o.builder);10476 const fn_llvm_ty = (try o.builder.fnType(llvm_usize, &(.{llvm_usize} ** 2), .normal)).toLlvm(&o.builder);
10567 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");10477 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, llvm_usize.toLlvm(&o.builder), "");
10568 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };10478 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };
10569 const asm_fn = llvm.getInlineAsm(10479 const asm_fn = llvm.getInlineAsm(
10570 fn_llvm_ty,10480 fn_llvm_ty,
src/codegen/llvm/Builder.zig+555-91
...@@ -6,6 +6,7 @@ llvm_module: *llvm.Module,...@@ -6,6 +6,7 @@ llvm_module: *llvm.Module,
6di_builder: ?*llvm.DIBuilder = null,6di_builder: ?*llvm.DIBuilder = null,
7llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},7llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},
8llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},8llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
9llvm_constants: std.ArrayListUnmanaged(*llvm.Value) = .{},
910
10source_filename: String = .none,11source_filename: String = .none,
11data_layout: String = .none,12data_layout: String = .none,
...@@ -29,6 +30,11 @@ aliases: std.ArrayListUnmanaged(Alias) = .{},...@@ -29,6 +30,11 @@ aliases: std.ArrayListUnmanaged(Alias) = .{},
29objects: std.ArrayListUnmanaged(Object) = .{},30objects: std.ArrayListUnmanaged(Object) = .{},
30functions: std.ArrayListUnmanaged(Function) = .{},31functions: std.ArrayListUnmanaged(Function) = .{},
3132
33constant_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
34constant_items: std.MultiArrayList(Constant.Item) = .{},
35constant_extra: std.ArrayListUnmanaged(u32) = .{},
36constant_limbs: std.ArrayListUnmanaged(std.math.big.Limb) = .{},
37
32pub const String = enum(u32) {38pub const String = enum(u32) {
33 none = std.math.maxInt(u31),39 none = std.math.maxInt(u31),
34 empty,40 empty,
...@@ -612,10 +618,6 @@ pub const Global = struct {...@@ -612,10 +618,6 @@ pub const Global = struct {
612 builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);618 builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);
613 }619 }
614 };620 };
615
616 fn deinit(self: *Global, _: Allocator) void {
617 self.* = undefined;
618 }
619};621};
620622
621pub const Alias = struct {623pub const Alias = struct {
...@@ -642,7 +644,7 @@ pub const Object = struct {...@@ -642,7 +644,7 @@ pub const Object = struct {
642 global: Global.Index,644 global: Global.Index,
643 thread_local: ThreadLocal = .default,645 thread_local: ThreadLocal = .default,
644 mutability: enum { global, constant } = .global,646 mutability: enum { global, constant } = .global,
645 init: void = {},647 init: Constant = .no_init,
646648
647 pub const Index = enum(u32) {649 pub const Index = enum(u32) {
648 _,650 _,
...@@ -664,10 +666,8 @@ pub const Object = struct {...@@ -664,10 +666,8 @@ pub const Object = struct {
664pub const Function = struct {666pub const Function = struct {
665 global: Global.Index,667 global: Global.Index,
666 body: ?void = null,668 body: ?void = null,
667669 instructions: std.ArrayListUnmanaged(Instruction) = .{},
668 fn deinit(self: *Function, _: Allocator) void {670 blocks: std.ArrayListUnmanaged(Block) = .{},
669 self.* = undefined;
670 }
671671
672 pub const Index = enum(u32) {672 pub const Index = enum(u32) {
673 _,673 _,
...@@ -684,6 +684,130 @@ pub const Function = struct {...@@ -684,6 +684,130 @@ pub const Function = struct {
684 return self.ptrConst(builder).global.toLlvm(builder);684 return self.ptrConst(builder).global.toLlvm(builder);
685 }685 }
686 };686 };
687
688 pub const Instruction = struct {
689 tag: Tag,
690
691 pub const Tag = enum {
692 arg,
693 block,
694 };
695
696 pub const Index = enum(u31) { _ };
697 };
698
699 pub const Block = struct {
700 body: std.ArrayListUnmanaged(Instruction.Index) = .{},
701
702 pub const Index = enum(u31) { _ };
703 };
704
705 pub fn deinit(self: *Function, gpa: Allocator) void {
706 self.instructions.deinit(gpa);
707 self.blocks.deinit(gpa);
708 self.* = undefined;
709 }
710};
711
712pub const Constant = enum(u32) {
713 false,
714 true,
715 none,
716 no_init = 1 << 31,
717 _,
718
719 const first_global: Constant = @enumFromInt(1 << 30);
720
721 pub const Tag = enum(u6) {
722 integer_positive,
723 integer_negative,
724 null,
725 none,
726 structure,
727 array,
728 vector,
729 zeroinitializer,
730 global,
731 undef,
732 poison,
733 blockaddress,
734 dso_local_equivalent,
735 no_cfi,
736 trunc,
737 zext,
738 sext,
739 fptrunc,
740 fpext,
741 fptoui,
742 fptosi,
743 uitofp,
744 sitofp,
745 ptrtoint,
746 inttoptr,
747 bitcast,
748 addrspacecast,
749 getelementptr,
750 icmp,
751 fcmp,
752 extractelement,
753 insertelement,
754 shufflevector,
755 add,
756 sub,
757 mul,
758 shl,
759 lshr,
760 ashr,
761 @"and",
762 @"or",
763 xor,
764 };
765
766 pub const Item = struct {
767 tag: Tag,
768 data: u32,
769 };
770
771 pub const Integer = packed struct(u64) {
772 type: Type,
773 limbs_len: u32,
774
775 pub const limbs = @divExact(@bitSizeOf(Integer), @bitSizeOf(std.math.big.Limb));
776 };
777
778 pub fn unwrap(self: Constant) union(enum) {
779 constant: u30,
780 global: Global.Index,
781 } {
782 return if (@intFromEnum(self) < @intFromEnum(first_global))
783 .{ .constant = @intCast(@intFromEnum(self)) }
784 else
785 .{ .global = @enumFromInt(@intFromEnum(self) - @intFromEnum(first_global)) };
786 }
787
788 pub fn toLlvm(self: Constant, builder: *const Builder) *llvm.Value {
789 assert(builder.useLibLlvm());
790 return switch (self.unwrap()) {
791 .constant => |constant| builder.llvm_constants.items[constant],
792 .global => |global| global.toLlvm(builder),
793 };
794 }
795};
796
797pub const Value = enum(u32) {
798 _,
799
800 const first_constant: Value = @enumFromInt(1 << 31);
801
802 pub fn unwrap(self: Value) union(enum) {
803 instruction: Function.Instruction.Index,
804 constant: Constant,
805 } {
806 return if (@intFromEnum(self) < @intFromEnum(first_constant))
807 .{ .instruction = @intFromEnum(self) }
808 else
809 .{ .constant = @enumFromInt(@intFromEnum(self) - @intFromEnum(first_constant)) };
810 }
687};811};
688812
689pub fn init(self: *Builder) Allocator.Error!void {813pub fn init(self: *Builder) Allocator.Error!void {
...@@ -711,11 +835,15 @@ pub fn init(self: *Builder) Allocator.Error!void {...@@ -711,11 +835,15 @@ pub fn init(self: *Builder) Allocator.Error!void {
711 inline for (.{0}) |addr_space|835 inline for (.{0}) |addr_space|
712 assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);836 assert(self.ptrTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
713 }837 }
838
839 assert(try self.intConst(.i1, 0) == .false);
840 assert(try self.intConst(.i1, 1) == .true);
714}841}
715842
716pub fn deinit(self: *Builder) void {843pub fn deinit(self: *Builder) void {
717 self.llvm_types.deinit(self.gpa);844 self.llvm_types.deinit(self.gpa);
718 self.llvm_globals.deinit(self.gpa);845 self.llvm_globals.deinit(self.gpa);
846 self.llvm_constants.deinit(self.gpa);
719847
720 self.string_map.deinit(self.gpa);848 self.string_map.deinit(self.gpa);
721 self.string_bytes.deinit(self.gpa);849 self.string_bytes.deinit(self.gpa);
...@@ -731,11 +859,210 @@ pub fn deinit(self: *Builder) void {...@@ -731,11 +859,210 @@ pub fn deinit(self: *Builder) void {
731 self.next_unique_global_id.deinit(self.gpa);859 self.next_unique_global_id.deinit(self.gpa);
732 self.aliases.deinit(self.gpa);860 self.aliases.deinit(self.gpa);
733 self.objects.deinit(self.gpa);861 self.objects.deinit(self.gpa);
862 for (self.functions.items) |*function| function.deinit(self.gpa);
734 self.functions.deinit(self.gpa);863 self.functions.deinit(self.gpa);
735864
865 self.constant_map.deinit(self.gpa);
866 self.constant_items.deinit(self.gpa);
867 self.constant_extra.deinit(self.gpa);
868 self.constant_limbs.deinit(self.gpa);
869
736 self.* = undefined;870 self.* = undefined;
737}871}
738872
873pub fn initializeLLVMTarget(self: *const Builder, arch: std.Target.Cpu.Arch) void {
874 if (!self.useLibLlvm()) return;
875 switch (arch) {
876 .aarch64, .aarch64_be, .aarch64_32 => {
877 llvm.LLVMInitializeAArch64Target();
878 llvm.LLVMInitializeAArch64TargetInfo();
879 llvm.LLVMInitializeAArch64TargetMC();
880 llvm.LLVMInitializeAArch64AsmPrinter();
881 llvm.LLVMInitializeAArch64AsmParser();
882 },
883 .amdgcn => {
884 llvm.LLVMInitializeAMDGPUTarget();
885 llvm.LLVMInitializeAMDGPUTargetInfo();
886 llvm.LLVMInitializeAMDGPUTargetMC();
887 llvm.LLVMInitializeAMDGPUAsmPrinter();
888 llvm.LLVMInitializeAMDGPUAsmParser();
889 },
890 .thumb, .thumbeb, .arm, .armeb => {
891 llvm.LLVMInitializeARMTarget();
892 llvm.LLVMInitializeARMTargetInfo();
893 llvm.LLVMInitializeARMTargetMC();
894 llvm.LLVMInitializeARMAsmPrinter();
895 llvm.LLVMInitializeARMAsmParser();
896 },
897 .avr => {
898 llvm.LLVMInitializeAVRTarget();
899 llvm.LLVMInitializeAVRTargetInfo();
900 llvm.LLVMInitializeAVRTargetMC();
901 llvm.LLVMInitializeAVRAsmPrinter();
902 llvm.LLVMInitializeAVRAsmParser();
903 },
904 .bpfel, .bpfeb => {
905 llvm.LLVMInitializeBPFTarget();
906 llvm.LLVMInitializeBPFTargetInfo();
907 llvm.LLVMInitializeBPFTargetMC();
908 llvm.LLVMInitializeBPFAsmPrinter();
909 llvm.LLVMInitializeBPFAsmParser();
910 },
911 .hexagon => {
912 llvm.LLVMInitializeHexagonTarget();
913 llvm.LLVMInitializeHexagonTargetInfo();
914 llvm.LLVMInitializeHexagonTargetMC();
915 llvm.LLVMInitializeHexagonAsmPrinter();
916 llvm.LLVMInitializeHexagonAsmParser();
917 },
918 .lanai => {
919 llvm.LLVMInitializeLanaiTarget();
920 llvm.LLVMInitializeLanaiTargetInfo();
921 llvm.LLVMInitializeLanaiTargetMC();
922 llvm.LLVMInitializeLanaiAsmPrinter();
923 llvm.LLVMInitializeLanaiAsmParser();
924 },
925 .mips, .mipsel, .mips64, .mips64el => {
926 llvm.LLVMInitializeMipsTarget();
927 llvm.LLVMInitializeMipsTargetInfo();
928 llvm.LLVMInitializeMipsTargetMC();
929 llvm.LLVMInitializeMipsAsmPrinter();
930 llvm.LLVMInitializeMipsAsmParser();
931 },
932 .msp430 => {
933 llvm.LLVMInitializeMSP430Target();
934 llvm.LLVMInitializeMSP430TargetInfo();
935 llvm.LLVMInitializeMSP430TargetMC();
936 llvm.LLVMInitializeMSP430AsmPrinter();
937 llvm.LLVMInitializeMSP430AsmParser();
938 },
939 .nvptx, .nvptx64 => {
940 llvm.LLVMInitializeNVPTXTarget();
941 llvm.LLVMInitializeNVPTXTargetInfo();
942 llvm.LLVMInitializeNVPTXTargetMC();
943 llvm.LLVMInitializeNVPTXAsmPrinter();
944 // There is no LLVMInitializeNVPTXAsmParser function available.
945 },
946 .powerpc, .powerpcle, .powerpc64, .powerpc64le => {
947 llvm.LLVMInitializePowerPCTarget();
948 llvm.LLVMInitializePowerPCTargetInfo();
949 llvm.LLVMInitializePowerPCTargetMC();
950 llvm.LLVMInitializePowerPCAsmPrinter();
951 llvm.LLVMInitializePowerPCAsmParser();
952 },
953 .riscv32, .riscv64 => {
954 llvm.LLVMInitializeRISCVTarget();
955 llvm.LLVMInitializeRISCVTargetInfo();
956 llvm.LLVMInitializeRISCVTargetMC();
957 llvm.LLVMInitializeRISCVAsmPrinter();
958 llvm.LLVMInitializeRISCVAsmParser();
959 },
960 .sparc, .sparc64, .sparcel => {
961 llvm.LLVMInitializeSparcTarget();
962 llvm.LLVMInitializeSparcTargetInfo();
963 llvm.LLVMInitializeSparcTargetMC();
964 llvm.LLVMInitializeSparcAsmPrinter();
965 llvm.LLVMInitializeSparcAsmParser();
966 },
967 .s390x => {
968 llvm.LLVMInitializeSystemZTarget();
969 llvm.LLVMInitializeSystemZTargetInfo();
970 llvm.LLVMInitializeSystemZTargetMC();
971 llvm.LLVMInitializeSystemZAsmPrinter();
972 llvm.LLVMInitializeSystemZAsmParser();
973 },
974 .wasm32, .wasm64 => {
975 llvm.LLVMInitializeWebAssemblyTarget();
976 llvm.LLVMInitializeWebAssemblyTargetInfo();
977 llvm.LLVMInitializeWebAssemblyTargetMC();
978 llvm.LLVMInitializeWebAssemblyAsmPrinter();
979 llvm.LLVMInitializeWebAssemblyAsmParser();
980 },
981 .x86, .x86_64 => {
982 llvm.LLVMInitializeX86Target();
983 llvm.LLVMInitializeX86TargetInfo();
984 llvm.LLVMInitializeX86TargetMC();
985 llvm.LLVMInitializeX86AsmPrinter();
986 llvm.LLVMInitializeX86AsmParser();
987 },
988 .xtensa => {
989 if (build_options.llvm_has_xtensa) {
990 llvm.LLVMInitializeXtensaTarget();
991 llvm.LLVMInitializeXtensaTargetInfo();
992 llvm.LLVMInitializeXtensaTargetMC();
993 llvm.LLVMInitializeXtensaAsmPrinter();
994 llvm.LLVMInitializeXtensaAsmParser();
995 }
996 },
997 .xcore => {
998 llvm.LLVMInitializeXCoreTarget();
999 llvm.LLVMInitializeXCoreTargetInfo();
1000 llvm.LLVMInitializeXCoreTargetMC();
1001 llvm.LLVMInitializeXCoreAsmPrinter();
1002 // There is no LLVMInitializeXCoreAsmParser function.
1003 },
1004 .m68k => {
1005 if (build_options.llvm_has_m68k) {
1006 llvm.LLVMInitializeM68kTarget();
1007 llvm.LLVMInitializeM68kTargetInfo();
1008 llvm.LLVMInitializeM68kTargetMC();
1009 llvm.LLVMInitializeM68kAsmPrinter();
1010 llvm.LLVMInitializeM68kAsmParser();
1011 }
1012 },
1013 .csky => {
1014 if (build_options.llvm_has_csky) {
1015 llvm.LLVMInitializeCSKYTarget();
1016 llvm.LLVMInitializeCSKYTargetInfo();
1017 llvm.LLVMInitializeCSKYTargetMC();
1018 // There is no LLVMInitializeCSKYAsmPrinter function.
1019 llvm.LLVMInitializeCSKYAsmParser();
1020 }
1021 },
1022 .ve => {
1023 llvm.LLVMInitializeVETarget();
1024 llvm.LLVMInitializeVETargetInfo();
1025 llvm.LLVMInitializeVETargetMC();
1026 llvm.LLVMInitializeVEAsmPrinter();
1027 llvm.LLVMInitializeVEAsmParser();
1028 },
1029 .arc => {
1030 if (build_options.llvm_has_arc) {
1031 llvm.LLVMInitializeARCTarget();
1032 llvm.LLVMInitializeARCTargetInfo();
1033 llvm.LLVMInitializeARCTargetMC();
1034 llvm.LLVMInitializeARCAsmPrinter();
1035 // There is no LLVMInitializeARCAsmParser function.
1036 }
1037 },
1038
1039 // LLVM backends that have no initialization functions.
1040 .tce,
1041 .tcele,
1042 .r600,
1043 .le32,
1044 .le64,
1045 .amdil,
1046 .amdil64,
1047 .hsail,
1048 .hsail64,
1049 .shave,
1050 .spir,
1051 .spir64,
1052 .kalimba,
1053 .renderscript32,
1054 .renderscript64,
1055 .dxil,
1056 .loongarch32,
1057 .loongarch64,
1058 => {},
1059
1060 .spu_2 => unreachable, // LLVM does not support this backend
1061 .spirv32 => unreachable, // LLVM does not support this backend
1062 .spirv64 => unreachable, // LLVM does not support this backend
1063 }
1064}
1065
739pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {1066pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {
740 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1);1067 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1);
741 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);1068 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
...@@ -899,6 +1226,112 @@ pub fn getGlobal(self: *const Builder, name: String) ?Global.Index {...@@ -899,6 +1226,112 @@ pub fn getGlobal(self: *const Builder, name: String) ?Global.Index {
899 return @enumFromInt(self.globals.getIndex(name) orelse return null);1226 return @enumFromInt(self.globals.getIndex(name) orelse return null);
900}1227}
9011228
1229pub fn intConst(self: *Builder, ty: Type, value: anytype) Allocator.Error!Constant {
1230 var limbs: [
1231 switch (@typeInfo(@TypeOf(value))) {
1232 .Int => |info| std.math.big.int.calcTwosCompLimbCount(info.bits),
1233 .ComptimeInt => std.math.big.int.calcLimbLen(value),
1234 else => @compileError("intConst expected an integral value, got " ++
1235 @typeName(@TypeOf(value))),
1236 }
1237 ]std.math.big.Limb = undefined;
1238 return self.bigIntConst(ty, std.math.big.int.Mutable.init(&limbs, value).toConst());
1239}
1240
1241pub fn bigIntConst(self: *Builder, ty: Type, value: std.math.big.int.Const) Allocator.Error!Constant {
1242 try self.constant_map.ensureUnusedCapacity(self.gpa, 1);
1243 try self.constant_items.ensureUnusedCapacity(self.gpa, 1);
1244 try self.constant_limbs.ensureUnusedCapacity(self.gpa, Constant.Integer.limbs + value.limbs.len);
1245 if (self.useLibLlvm()) try self.llvm_constants.ensureUnusedCapacity(self.gpa, 1);
1246 return self.bigIntConstAssumeCapacity(ty, value);
1247}
1248
1249pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
1250 if (self.source_filename != .none) try writer.print(
1251 \\; ModuleID = '{s}'
1252 \\source_filename = {"}
1253 \\
1254 , .{ self.source_filename.toSlice(self).?, self.source_filename.fmt(self) });
1255 if (self.data_layout != .none) try writer.print(
1256 \\target datalayout = {"}
1257 \\
1258 , .{self.data_layout.fmt(self)});
1259 if (self.target_triple != .none) try writer.print(
1260 \\target triple = {"}
1261 \\
1262 , .{self.target_triple.fmt(self)});
1263 try writer.writeByte('\n');
1264 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(
1265 \\%{} = type {}
1266 \\
1267 , .{ id.fmt(self), ty.fmt(self) });
1268 try writer.writeByte('\n');
1269 for (self.objects.items) |object| {
1270 const global = self.globals.entries.get(@intFromEnum(object.global));
1271 try writer.print(
1272 \\@{} ={}{}{}{}{}{}{}{} {s} {%}{,}
1273 \\
1274 , .{
1275 global.key.fmt(self),
1276 global.value.linkage,
1277 global.value.preemption,
1278 global.value.visibility,
1279 global.value.dll_storage_class,
1280 object.thread_local,
1281 global.value.unnamed_addr,
1282 global.value.addr_space,
1283 global.value.externally_initialized,
1284 @tagName(object.mutability),
1285 global.value.type.fmt(self),
1286 global.value.alignment,
1287 });
1288 }
1289 try writer.writeByte('\n');
1290 for (self.functions.items) |function| {
1291 const global = self.globals.entries.get(@intFromEnum(function.global));
1292 const item = self.type_items.items[@intFromEnum(global.value.type)];
1293 const extra = self.typeExtraDataTrail(Type.Function, item.data);
1294 const params: []const Type =
1295 @ptrCast(self.type_extra.items[extra.end..][0..extra.data.params_len]);
1296 try writer.print(
1297 \\{s} {}{}{}{}{} @{}(
1298 , .{
1299 if (function.body) |_| "define" else "declare",
1300 global.value.linkage,
1301 global.value.preemption,
1302 global.value.visibility,
1303 global.value.dll_storage_class,
1304 extra.data.ret.fmt(self),
1305 global.key.fmt(self),
1306 });
1307 for (params, 0..) |param, index| {
1308 if (index > 0) try writer.writeAll(", ");
1309 try writer.print("{%} %{d}", .{ param.fmt(self), index });
1310 }
1311 switch (item.tag) {
1312 .function => {},
1313 .vararg_function => {
1314 if (params.len > 0) try writer.writeAll(", ");
1315 try writer.writeAll("...");
1316 },
1317 else => unreachable,
1318 }
1319 try writer.print(") {}{}", .{
1320 global.value.unnamed_addr,
1321 global.value.alignment,
1322 });
1323 if (function.body) |_| try writer.print(
1324 \\{{
1325 \\ ret {%}
1326 \\}}
1327 \\
1328 , .{
1329 extra.data.ret.fmt(self),
1330 });
1331 try writer.writeByte('\n');
1332 }
1333}
1334
902fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {1335fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {
903 if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);1336 if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);
904 try self.string_map.ensureUnusedCapacity(self.gpa, 1);1337 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
...@@ -1002,6 +1435,7 @@ fn fnTypeAssumeCapacity(...@@ -1002,6 +1435,7 @@ fn fnTypeAssumeCapacity(
1002}1435}
10031436
1004fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {1437fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
1438 assert(bits > 0);
1005 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });1439 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
1006 if (self.useLibLlvm() and result.new)1440 if (self.useLibLlvm() and result.new)
1007 self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));1441 self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));
...@@ -1162,10 +1596,16 @@ fn structTypeAssumeCapacity(...@@ -1162,10 +1596,16 @@ fn structTypeAssumeCapacity(
1162 });1596 });
1163 self.type_extra.appendSliceAssumeCapacity(@ptrCast(fields));1597 self.type_extra.appendSliceAssumeCapacity(@ptrCast(fields));
1164 if (self.useLibLlvm()) {1598 if (self.useLibLlvm()) {
1165 const llvm_fields = try self.gpa.alloc(*llvm.Type, fields.len);1599 const ExpectedContents = [32]*llvm.Type;
1166 defer self.gpa.free(llvm_fields);1600 var stack align(@alignOf(ExpectedContents)) =
1601 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
1602 const allocator = stack.get();
1603
1604 const llvm_fields = try allocator.alloc(*llvm.Type, fields.len);
1605 defer allocator.free(llvm_fields);
1167 for (llvm_fields, fields) |*llvm_field, field|1606 for (llvm_fields, fields) |*llvm_field, field|
1168 llvm_field.* = self.llvm_types.items[@intFromEnum(field)];1607 llvm_field.* = self.llvm_types.items[@intFromEnum(field)];
1608
1169 self.llvm_types.appendAssumeCapacity(self.llvm_context.structType(1609 self.llvm_types.appendAssumeCapacity(self.llvm_context.structType(
1170 llvm_fields.ptr,1610 llvm_fields.ptr,
1171 @intCast(llvm_fields.len),1611 @intCast(llvm_fields.len),
...@@ -1277,90 +1717,114 @@ fn isValidIdentifier(id: []const u8) bool {...@@ -1277,90 +1717,114 @@ fn isValidIdentifier(id: []const u8) bool {
1277 return true;1717 return true;
1278}1718}
12791719
1280pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {1720fn bigIntConstAssumeCapacity(
1281 if (self.source_filename != .none) try writer.print(1721 self: *Builder,
1282 \\; ModuleID = '{s}'1722 ty: Type,
1283 \\source_filename = {"}1723 value: std.math.big.int.Const,
1284 \\1724) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
1285 , .{ self.source_filename.toSlice(self).?, self.source_filename.fmt(self) });1725 const type_item = self.type_items.items[@intFromEnum(ty)];
1286 if (self.data_layout != .none) try writer.print(1726 assert(type_item.tag == .integer);
1287 \\target datalayout = {"}1727 const bits = type_item.data;
1288 \\1728
1289 , .{self.data_layout.fmt(self)});1729 const ExpectedContents = extern struct {
1290 if (self.target_triple != .none) try writer.print(1730 limbs: [64 / @sizeOf(std.math.big.Limb)]std.math.big.Limb,
1291 \\target triple = {"}1731 llvm_limbs: if (build_options.have_llvm) [64 / @sizeOf(u64)]u64 else void,
1292 \\1732 };
1293 , .{self.target_triple.fmt(self)});1733 var stack align(@alignOf(ExpectedContents)) =
1294 try writer.writeByte('\n');1734 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
1295 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(1735 const allocator = stack.get();
1296 \\%{} = type {}1736
1297 \\1737 var limbs: []std.math.big.Limb = &.{};
1298 , .{ id.fmt(self), ty.fmt(self) });1738 defer allocator.free(limbs);
1299 try writer.writeByte('\n');1739 const canonical_value = if (value.fitsInTwosComp(.signed, bits)) value else canon: {
1300 for (self.objects.items) |object| {1740 assert(value.fitsInTwosComp(.unsigned, bits));
1301 const global = self.globals.entries.get(@intFromEnum(object.global));1741 limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits));
1302 try writer.print(1742 var temp_value = std.math.big.int.Mutable.init(limbs, 0);
1303 \\@{} ={}{}{}{}{}{}{}{} {s} {%}{,}1743 temp_value.truncate(value, .signed, bits);
1304 \\1744 break :canon temp_value.toConst();
1305 , .{1745 };
1306 global.key.fmt(self),1746 assert(canonical_value.fitsInTwosComp(.signed, bits));
1307 global.value.linkage,1747
1308 global.value.preemption,1748 const ExtraPtr = *align(@alignOf(std.math.big.Limb)) Constant.Integer;
1309 global.value.visibility,1749 const Key = struct { tag: Constant.Tag, type: Type, limbs: []const std.math.big.Limb };
1310 global.value.dll_storage_class,1750 const tag: Constant.Tag = switch (canonical_value.positive) {
1311 object.thread_local,1751 true => .integer_positive,
1312 global.value.unnamed_addr,1752 false => .integer_negative,
1313 global.value.addr_space,1753 };
1314 global.value.externally_initialized,1754 const Adapter = struct {
1315 @tagName(object.mutability),1755 builder: *const Builder,
1316 global.value.type.fmt(self),1756 pub fn hash(_: @This(), key: Key) u32 {
1317 global.value.alignment,1757 var hasher = std.hash.Wyhash.init(std.hash.uint32(@intFromEnum(key.tag)));
1318 });1758 hasher.update(std.mem.asBytes(&key.type));
1319 }1759 hasher.update(std.mem.sliceAsBytes(key.limbs));
1320 try writer.writeByte('\n');1760 return @truncate(hasher.final());
1321 for (self.functions.items) |function| {
1322 const global = self.globals.entries.get(@intFromEnum(function.global));
1323 const item = self.type_items.items[@intFromEnum(global.value.type)];
1324 const extra = self.typeExtraDataTrail(Type.Function, item.data);
1325 const params: []const Type =
1326 @ptrCast(self.type_extra.items[extra.end..][0..extra.data.params_len]);
1327 try writer.print(
1328 \\{s} {}{}{}{}{} @{}(
1329 , .{
1330 if (function.body) |_| "define" else "declare",
1331 global.value.linkage,
1332 global.value.preemption,
1333 global.value.visibility,
1334 global.value.dll_storage_class,
1335 extra.data.ret.fmt(self),
1336 global.key.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 }1761 }
1342 switch (item.tag) {1762 pub fn eql(ctx: @This(), lhs: Key, _: void, rhs_index: usize) bool {
1343 .function => {},1763 if (lhs.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false;
1344 .vararg_function => {1764 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
1345 if (params.len > 0) try writer.writeAll(", ");1765 const rhs_extra: ExtraPtr = @ptrCast(
1346 try writer.writeAll("...");1766 ctx.builder.constant_limbs.items[rhs_data..][0..Constant.Integer.limbs],
1347 },1767 );
1348 else => unreachable,1768 const rhs_limbs = ctx.builder.constant_limbs
1769 .items[rhs_data + Constant.Integer.limbs ..][0..rhs_extra.limbs_len];
1770 return lhs.type == rhs_extra.type and std.mem.eql(std.math.big.Limb, lhs.limbs, rhs_limbs);
1349 }1771 }
1350 try writer.print(") {}{}", .{1772 };
1351 global.value.unnamed_addr,1773
1352 global.value.alignment,1774 const data = Key{ .tag = tag, .type = ty, .limbs = canonical_value.limbs };
1353 });1775 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
1354 if (function.body) |_| try writer.print(1776 if (!gop.found_existing) {
1355 \\{{1777 gop.key_ptr.* = {};
1356 \\ ret {%}1778 gop.value_ptr.* = {};
1357 \\}}1779 self.constant_items.appendAssumeCapacity(.{
1358 \\1780 .tag = tag,
1359 , .{1781 .data = @intCast(self.constant_limbs.items.len),
1360 extra.data.ret.fmt(self),
1361 });1782 });
1362 try writer.writeByte('\n');1783 const extra: ExtraPtr = @ptrCast(
1784 self.constant_limbs.addManyAsArrayAssumeCapacity(Constant.Integer.limbs),
1785 );
1786 extra.* = .{ .type = ty, .limbs_len = @intCast(canonical_value.limbs.len) };
1787 self.constant_limbs.appendSliceAssumeCapacity(canonical_value.limbs);
1788 if (self.useLibLlvm()) {
1789 const llvm_type = ty.toLlvm(self);
1790 if (canonical_value.to(c_longlong)) |small| {
1791 self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(@bitCast(small), .True));
1792 } else |_| if (canonical_value.to(c_ulonglong)) |small| {
1793 self.llvm_constants.appendAssumeCapacity(llvm_type.constInt(small, .False));
1794 } else |_| {
1795 const llvm_limbs = try allocator.alloc(u64, std.math.divCeil(
1796 usize,
1797 canonical_value.bitCountTwosComp(),
1798 @bitSizeOf(u64),
1799 ) catch unreachable);
1800 defer allocator.free(llvm_limbs);
1801 var limb_index: usize = 0;
1802 var borrow: std.math.big.Limb = 0;
1803 for (llvm_limbs) |*result_limb| {
1804 var llvm_limb: u64 = 0;
1805 inline for (0..Constant.Integer.limbs) |shift| {
1806 const limb = if (limb_index < canonical_value.limbs.len)
1807 canonical_value.limbs[limb_index]
1808 else
1809 0;
1810 limb_index += 1;
1811 llvm_limb |= @as(u64, limb) << shift * @bitSizeOf(std.math.big.Limb);
1812 }
1813 if (!canonical_value.positive) {
1814 const overflow = @subWithOverflow(borrow, llvm_limb);
1815 llvm_limb = overflow[0];
1816 borrow -%= overflow[1];
1817 assert(borrow == 0 or borrow == std.math.maxInt(u64));
1818 }
1819 result_limb.* = llvm_limb;
1820 }
1821 self.llvm_constants.appendAssumeCapacity(
1822 llvm_type.constIntOfArbitraryPrecision(@intCast(llvm_limbs.len), llvm_limbs.ptr),
1823 );
1824 }
1825 }
1363 }1826 }
1827 return @enumFromInt(gop.index);
1364}1828}
13651829
1366inline fn useLibLlvm(self: *const Builder) bool {1830inline fn useLibLlvm(self: *const Builder) bool {
src/codegen/llvm/bindings.zig+6
...@@ -280,6 +280,9 @@ pub const Value = opaque {...@@ -280,6 +280,9 @@ pub const Value = opaque {
280280
281 pub const attachMetaData = ZigLLVMAttachMetaData;281 pub const attachMetaData = ZigLLVMAttachMetaData;
282 extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void;282 extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void;
283
284 pub const dump = LLVMDumpValue;
285 extern fn LLVMDumpValue(Val: *Value) void;
283};286};
284287
285pub const Type = opaque {288pub const Type = opaque {
...@@ -353,6 +356,9 @@ pub const Type = opaque {...@@ -353,6 +356,9 @@ pub const Type = opaque {
353 ConstantIndices: [*]const *Value,356 ConstantIndices: [*]const *Value,
354 NumIndices: c_uint,357 NumIndices: c_uint,
355 ) *Value;358 ) *Value;
359
360 pub const dump = LLVMDumpType;
361 extern fn LLVMDumpType(Ty: *Type) void;
356};362};
357363
358pub const Module = opaque {364pub const Module = opaque {