| ... | @@ -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(); |
| 613 | | 613 | |
| 614 | initializeLLVMTarget(options.target.cpu.arch); | 614 | builder.initializeLLVMTarget(options.target.cpu.arch); |
| 615 | | 615 | |
| 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 { |
| 832 | | 832 | |
| 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 | // } |
| 875 | | 875 | |
| 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 | } |
| 881 | | 881 | |
| ... | @@ -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 values | 3476 | => 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(), |
| 3561 | | 3559 | .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)) { |
| 3564 | | 3562 | 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); |
| 3567 | | 3565 | }, |
| 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); |
| 3662 | | 3614 | |
| 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 { |
| 3802 | | 3749 | |
| 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 debug | 3753 | // 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 | } |
| 3810 | | 3757 | |
| 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 | } |
| 3831 | | 3778 | |
| ... | @@ -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 | else | 3816 | 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, this | 3819 | // 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 with | 3820 | // 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 { |
| 3899 | | 3846 | |
| 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 debug | 3850 | // 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 | } |
| 3907 | | 3854 | |
| 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 | } |
| 3928 | | 3875 | |
| ... | @@ -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 | } |
| 4049 | | 3996 | |
| 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 | } |
| 4073 | | 4001 | |
| 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 | } |
| 4107 | | 4035 | |
| 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 | } |
| 4129 | | 4056 | |
| 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); |
| 4141 | | 4066 | |
| 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); |
| 4153 | | 4077 | |
| 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 | else | 4093 | 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 one | 4107 | // 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` annotation | 4208 | // The value cannot be undefined, because we use the `nonnull` annotation |
| 4285 | // for non-optional pointers. We also need to respect the alignment, even though | 4209 | // 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 builds | 4216 | // 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 not | 4217 | // 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 value | 4219 | // 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 | } |
| 4306 | | 4230 | |
| 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 | } |
| 5120 | | 5044 | |
| 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); |
| 5123 | | 5047 | |
| 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 | } |
| 5140 | | 5064 | |
| 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.ptr | 5209 | // 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 code | 5251 | // Functions with an empty error set are emitted with an error code |
| 5328 | // return type and return zero so they can be function pointers coerced | 5252 | // 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 code | 5299 | // Functions with an empty error set are emitted with an error code |
| 5376 | // return type and return zero so they can be function pointers coerced | 5300 | // 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); |
| 5550 | | 5474 | |
| 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 | }; |
| 5586 | | 5509 | |
| 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); |
| 6344 | | 6267 | |
| 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 | } |
| 6349 | | 6272 | |
| ... | @@ -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 | else | 6843 | 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 | } |
| 6925 | | 6847 | |
| 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(); |
| 6950 | | 6872 | |
| 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 == 0 | 6876 | .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 | } |
| 6959 | | 6881 | |
| 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 | } |
| 7111 | | 7032 | |
| ... | @@ -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 | } |
| 7279 | | 7200 | |
| 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 | } |
| 7288 | | 7211 | |
| 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); | | |
| 7579 | | 7501 | |
| 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); |
| 7582 | | 7504 | |
| 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); |
| 7586 | | 7508 | |
| 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); |
| 7642 | | 7564 | |
| 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); | | |
| 7656 | | 7577 | |
| 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); |
| 7659 | | 7580 | |
| 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); |
| 7663 | | 7584 | |
| 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); |
| 7795 | | 7716 | |
| 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); |
| 7800 | | 7721 | |
| 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 | ); |
| 7884 | | 7805 | |
| 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 the | 7895 | // 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 produce | 8113 | // 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 | } |
| 8433 | | 8358 | |
| 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 conveys | 8488 | // 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 using | 8489 | // 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 | else | 8493 | 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); |
| 8861 | | 8784 | |
| ... | @@ -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 using | 8796 | // 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 | else | 8800 | 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"); |
| 8948 | | 8871 | |
| 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); |
| 8985 | | 8910 | |
| ... | @@ -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 byte | 9119 | // 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 bswap | 9120 | // 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); |
| 9201 | | 9125 | |
| 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); |
| 9204 | | 9128 | @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); |
| 9209 | | 9130 | |
| 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 { |
| 9263 | | 9184 | |
| 9264 | self.builder.positionBuilderAtEnd(end_block); | 9185 | self.builder.positionBuilderAtEnd(end_block); |
| 9265 | | 9186 | |
| 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)); |
| 9350 | | 9271 | |
| 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)); |
| 9353 | | 9274 | |
| 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); |
| 9389 | | 9310 | |
| 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))); |
| 9423 | | 9344 | |
| 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; |
| 9427 | | 9348 | |
| 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 { |
| 9439 | | 9360 | |
| 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); |
| 9557 | | 9478 | |
| 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 | } |
| 9570 | | 9489 | |
| ... | @@ -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(); |
| 9598 | | 9517 | |
| 9599 | // Allocate and initialize our mutable variables | 9518 | // 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); |
| 9604 | | 9523 | |
| ... | @@ -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); |
| 9611 | | 9530 | |
| 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"); |
| 9616 | | 9535 | |
| 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); |
| 9628 | | 9547 | |
| 9629 | // i += 1 | 9548 | // 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 { |
| 9731 | | 9650 | |
| 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 | else | 9680 | 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, this | 9683 | // 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 with | 9684 | // 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 | } |
| 9776 | | 9693 | |
| 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 0xaa | 9695 | // 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)); |
| 9782 | | 9698 | |
| 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; |
| 9786 | | 9705 | |
| 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)); |
| 9817 | | 9736 | |
| 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)); |
| 9820 | | 9739 | |
| 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 { |
| 9825 | | 9744 | |
| 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).?; |
| 9864 | | 9783 | |
| ... | @@ -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 not | 9814 | // 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 set | 9816 | // 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 { |
| 9936 | | 9855 | |
| 9937 | // Now we follow the layout as expressed above with GEP instructions to set the | 9856 | // 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 { |
| 9958 | | 9873 | |
| 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 | } |
| 9980 | | 9895 | |
| ... | @@ -10031,12 +9946,11 @@ pub const FuncGen = struct { | ... | @@ -10031,12 +9946,11 @@ pub const FuncGen = struct { |
| 10031 | | 9946 | |
| 10032 | const ptr = try self.resolveInst(prefetch.ptr); | 9947 | const ptr = try self.resolveInst(prefetch.ptr); |
| 10033 | | 9948 | |
| 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 | } |
| 10054 | | 9968 | |
| 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 | }; |
| 10064 | | 9976 | |
| 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 { |
| 10084 | | 9996 | |
| 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 | } |
| 10091 | | 10002 | |
| 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); |
| 10158 | | 10070 | |
| 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 | } |
| 10161 | | 10073 | |
| 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 get | 10181 | // 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 of | 10182 | // 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 { |
| 10340 | | 10251 | |
| 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); |
| 10346 | | 10257 | |
| 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); |
| 10350 | | 10261 | |
| 10351 | return self.builder.buildExtractElement(loaded_vector, index_u32, ""); | 10262 | return self.builder.buildExtractElement(loaded_vector, index_u32.toLlvm(&o.builder), ""); |
| 10352 | } | 10263 | } |
| 10353 | | 10264 | |
| 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 { |
| 10417 | | 10328 | |
| 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); |
| 10423 | | 10334 | |
| 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); |
| 10427 | | 10338 | |
| 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), ""); |
| 10429 | | 10340 | |
| 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 | } |
| 10498 | | 10409 | |
| ... | @@ -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; |
| 10513 | | 10424 | |
| 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))); |
| 10517 | | 10427 | |
| 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 | }; |
| 10565 | | 10475 | |
| 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, |