| ... | ... | @@ -841,7 +841,8 @@ pub const Object = struct { |
| 841 | 841 | args.appendAssumeCapacity(param); |
| 842 | 842 | } else { |
| 843 | 843 | const alignment = param_ty.abiAlignment(target); |
| 844 | | const load_inst = builder.buildLoad(param, ""); |
| 844 | const param_llvm_ty = try dg.lowerType(param_ty); |
| 845 | const load_inst = builder.buildLoad(param_llvm_ty, param, ""); |
| 845 | 846 | load_inst.setAlignment(alignment); |
| 846 | 847 | args.appendAssumeCapacity(load_inst); |
| 847 | 848 | } |
| ... | ... | @@ -870,7 +871,7 @@ pub const Object = struct { |
| 870 | 871 | if (isByRef(param_ty)) { |
| 871 | 872 | args.appendAssumeCapacity(arg_ptr); |
| 872 | 873 | } else { |
| 873 | | const load_inst = builder.buildLoad(arg_ptr, ""); |
| 874 | const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, ""); |
| 874 | 875 | load_inst.setAlignment(alignment); |
| 875 | 876 | args.appendAssumeCapacity(load_inst); |
| 876 | 877 | } |
| ... | ... | @@ -921,14 +922,14 @@ pub const Object = struct { |
| 921 | 922 | for (llvm_ints) |_, i_usize| { |
| 922 | 923 | const i = @intCast(c_uint, i_usize); |
| 923 | 924 | const param = llvm_func.getParam(i); |
| 924 | | const field_ptr = builder.buildStructGEP(casted_ptr, i, ""); |
| 925 | const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, ""); |
| 925 | 926 | const store_inst = builder.buildStore(param, field_ptr); |
| 926 | 927 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 927 | 928 | } |
| 928 | 929 | |
| 929 | 930 | const is_by_ref = isByRef(param_ty); |
| 930 | 931 | const loaded = if (is_by_ref) arg_ptr else l: { |
| 931 | | const load_inst = builder.buildLoad(arg_ptr, ""); |
| 932 | const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, ""); |
| 932 | 933 | load_inst.setAlignment(param_alignment); |
| 933 | 934 | break :l load_inst; |
| 934 | 935 | }; |
| ... | ... | @@ -3663,7 +3664,8 @@ pub const DeclGen = struct { |
| 3663 | 3664 | llvm_u32.constInt(0, .False), |
| 3664 | 3665 | llvm_u32.constInt(llvm_pl_index, .False), |
| 3665 | 3666 | }; |
| 3666 | | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3667 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 3668 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3667 | 3669 | }, |
| 3668 | 3670 | .Struct => { |
| 3669 | 3671 | const field_ty = parent_ty.structFieldType(field_index); |
| ... | ... | @@ -3693,7 +3695,8 @@ pub const DeclGen = struct { |
| 3693 | 3695 | llvm_u32.constInt(0, .False), |
| 3694 | 3696 | llvm_u32.constInt(llvm_field_index, .False), |
| 3695 | 3697 | }; |
| 3696 | | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3698 | const parent_llvm_ty = try dg.lowerType(parent_ty); |
| 3699 | break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3697 | 3700 | }, |
| 3698 | 3701 | else => unreachable, |
| 3699 | 3702 | } |
| ... | ... | @@ -3707,7 +3710,8 @@ pub const DeclGen = struct { |
| 3707 | 3710 | const indices: [1]*const llvm.Value = .{ |
| 3708 | 3711 | llvm_usize.constInt(elem_ptr.index, .False), |
| 3709 | 3712 | }; |
| 3710 | | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3713 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); |
| 3714 | break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3711 | 3715 | }, |
| 3712 | 3716 | .opt_payload_ptr => blk: { |
| 3713 | 3717 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; |
| ... | ... | @@ -3730,7 +3734,8 @@ pub const DeclGen = struct { |
| 3730 | 3734 | llvm_u32.constInt(0, .False), |
| 3731 | 3735 | llvm_u32.constInt(0, .False), |
| 3732 | 3736 | }; |
| 3733 | | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3737 | const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty); |
| 3738 | break :blk opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3734 | 3739 | }, |
| 3735 | 3740 | .eu_payload_ptr => blk: { |
| 3736 | 3741 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; |
| ... | ... | @@ -3751,7 +3756,8 @@ pub const DeclGen = struct { |
| 3751 | 3756 | llvm_u32.constInt(0, .False), |
| 3752 | 3757 | llvm_u32.constInt(payload_offset, .False), |
| 3753 | 3758 | }; |
| 3754 | | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3759 | const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty); |
| 3760 | break :blk eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len); |
| 3755 | 3761 | }, |
| 3756 | 3762 | else => unreachable, |
| 3757 | 3763 | }; |
| ... | ... | @@ -4303,9 +4309,10 @@ pub const FuncGen = struct { |
| 4303 | 4309 | const arg = args[it.zig_index - 1]; |
| 4304 | 4310 | const param_ty = self.air.typeOf(arg); |
| 4305 | 4311 | const llvm_arg = try self.resolveInst(arg); |
| 4312 | const llvm_param_ty = try self.dg.lowerType(param_ty); |
| 4306 | 4313 | if (isByRef(param_ty)) { |
| 4307 | 4314 | const alignment = param_ty.abiAlignment(target); |
| 4308 | | const load_inst = self.builder.buildLoad(llvm_arg, ""); |
| 4315 | const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, ""); |
| 4309 | 4316 | load_inst.setAlignment(alignment); |
| 4310 | 4317 | try llvm_args.append(load_inst); |
| 4311 | 4318 | } else { |
| ... | ... | @@ -4315,7 +4322,6 @@ pub const FuncGen = struct { |
| 4315 | 4322 | // which is always lowered to an LLVM type of `*i8`. |
| 4316 | 4323 | // 2. The argument is a global which does act as a pointer, however |
| 4317 | 4324 | // a bitcast is needed in order for the LLVM types to match. |
| 4318 | | const llvm_param_ty = try self.dg.lowerType(param_ty); |
| 4319 | 4325 | const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, ""); |
| 4320 | 4326 | try llvm_args.append(casted_ptr); |
| 4321 | 4327 | } else { |
| ... | ... | @@ -4350,7 +4356,7 @@ pub const FuncGen = struct { |
| 4350 | 4356 | if (isByRef(param_ty)) { |
| 4351 | 4357 | const alignment = param_ty.abiAlignment(target); |
| 4352 | 4358 | const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, ""); |
| 4353 | | const load_inst = self.builder.buildLoad(casted_ptr, ""); |
| 4359 | const load_inst = self.builder.buildLoad(int_llvm_ty, casted_ptr, ""); |
| 4354 | 4360 | load_inst.setAlignment(alignment); |
| 4355 | 4361 | try llvm_args.append(load_inst); |
| 4356 | 4362 | } else { |
| ... | ... | @@ -4366,7 +4372,7 @@ pub const FuncGen = struct { |
| 4366 | 4372 | const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), ""); |
| 4367 | 4373 | const store_inst = self.builder.buildStore(llvm_arg, casted_ptr); |
| 4368 | 4374 | store_inst.setAlignment(alignment); |
| 4369 | | const load_inst = self.builder.buildLoad(int_ptr, ""); |
| 4375 | const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, ""); |
| 4370 | 4376 | load_inst.setAlignment(alignment); |
| 4371 | 4377 | try llvm_args.append(load_inst); |
| 4372 | 4378 | } |
| ... | ... | @@ -4403,8 +4409,8 @@ pub const FuncGen = struct { |
| 4403 | 4409 | try llvm_args.ensureUnusedCapacity(it.llvm_types_len); |
| 4404 | 4410 | for (llvm_ints) |_, i_usize| { |
| 4405 | 4411 | const i = @intCast(c_uint, i_usize); |
| 4406 | | const field_ptr = self.builder.buildStructGEP(casted_ptr, i, ""); |
| 4407 | | const load_inst = self.builder.buildLoad(field_ptr, ""); |
| 4412 | const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, ""); |
| 4413 | const load_inst = self.builder.buildLoad(field_types[i], field_ptr, ""); |
| 4408 | 4414 | load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 4409 | 4415 | llvm_args.appendAssumeCapacity(load_inst); |
| 4410 | 4416 | } |
| ... | ... | @@ -4418,6 +4424,7 @@ pub const FuncGen = struct { |
| 4418 | 4424 | }; |
| 4419 | 4425 | |
| 4420 | 4426 | const call = self.builder.buildCall( |
| 4427 | try self.dg.lowerType(zig_fn_ty), |
| 4421 | 4428 | llvm_fn, |
| 4422 | 4429 | llvm_args.items.ptr, |
| 4423 | 4430 | @intCast(c_uint, llvm_args.items.len), |
| ... | ... | @@ -4443,7 +4450,7 @@ pub const FuncGen = struct { |
| 4443 | 4450 | return rp; |
| 4444 | 4451 | } else { |
| 4445 | 4452 | // our by-ref status disagrees with sret so we must load. |
| 4446 | | const loaded = self.builder.buildLoad(rp, ""); |
| 4453 | const loaded = self.builder.buildLoad(llvm_ret_ty, rp, ""); |
| 4447 | 4454 | loaded.setAlignment(return_type.abiAlignment(target)); |
| 4448 | 4455 | return loaded; |
| 4449 | 4456 | } |
| ... | ... | @@ -4465,7 +4472,7 @@ pub const FuncGen = struct { |
| 4465 | 4472 | if (isByRef(return_type)) { |
| 4466 | 4473 | return rp; |
| 4467 | 4474 | } else { |
| 4468 | | const load_inst = self.builder.buildLoad(rp, ""); |
| 4475 | const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, ""); |
| 4469 | 4476 | load_inst.setAlignment(alignment); |
| 4470 | 4477 | return load_inst; |
| 4471 | 4478 | } |
| ... | ... | @@ -4523,7 +4530,7 @@ pub const FuncGen = struct { |
| 4523 | 4530 | // operand is a pointer however self.ret_ptr is null so that means |
| 4524 | 4531 | // we need to return a value. |
| 4525 | 4532 | const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, ""); |
| 4526 | | const load_inst = self.builder.buildLoad(casted_ptr, ""); |
| 4533 | const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); |
| 4527 | 4534 | load_inst.setAlignment(alignment); |
| 4528 | 4535 | _ = self.builder.buildRet(load_inst); |
| 4529 | 4536 | return null; |
| ... | ... | @@ -4540,7 +4547,7 @@ pub const FuncGen = struct { |
| 4540 | 4547 | const store_inst = self.builder.buildStore(operand, rp); |
| 4541 | 4548 | store_inst.setAlignment(alignment); |
| 4542 | 4549 | const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, ""); |
| 4543 | | const load_inst = self.builder.buildLoad(casted_ptr, ""); |
| 4550 | const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); |
| 4544 | 4551 | load_inst.setAlignment(alignment); |
| 4545 | 4552 | _ = self.builder.buildRet(load_inst); |
| 4546 | 4553 | return null; |
| ... | ... | @@ -4575,7 +4582,7 @@ pub const FuncGen = struct { |
| 4575 | 4582 | const ptr_abi_ty = abi_ret_ty.pointerType(0); |
| 4576 | 4583 | break :p self.builder.buildBitCast(ptr, ptr_abi_ty, ""); |
| 4577 | 4584 | }; |
| 4578 | | const loaded = self.builder.buildLoad(casted_ptr, ""); |
| 4585 | const loaded = self.builder.buildLoad(abi_ret_ty, casted_ptr, ""); |
| 4579 | 4586 | loaded.setAlignment(ret_ty.abiAlignment(target)); |
| 4580 | 4587 | _ = self.builder.buildRet(loaded); |
| 4581 | 4588 | return null; |
| ... | ... | @@ -4615,7 +4622,7 @@ pub const FuncGen = struct { |
| 4615 | 4622 | const operand = try self.resolveInst(un_op); |
| 4616 | 4623 | const llvm_fn = try self.getCmpLtErrorsLenFunction(); |
| 4617 | 4624 | const args: [1]*const llvm.Value = .{operand}; |
| 4618 | | return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 4625 | return self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 4619 | 4626 | } |
| 4620 | 4627 | |
| 4621 | 4628 | fn cmp( |
| ... | ... | @@ -4642,8 +4649,9 @@ pub const FuncGen = struct { |
| 4642 | 4649 | // We need to emit instructions to check for equality/inequality |
| 4643 | 4650 | // of optionals that are not pointers. |
| 4644 | 4651 | const is_by_ref = isByRef(scalar_ty); |
| 4645 | | const lhs_non_null = self.optIsNonNull(lhs, is_by_ref); |
| 4646 | | const rhs_non_null = self.optIsNonNull(rhs, is_by_ref); |
| 4652 | const opt_llvm_ty = try self.dg.lowerType(scalar_ty); |
| 4653 | const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref); |
| 4654 | const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref); |
| 4647 | 4655 | const llvm_i2 = self.context.intType(2); |
| 4648 | 4656 | const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, ""); |
| 4649 | 4657 | const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, ""); |
| ... | ... | @@ -4666,8 +4674,8 @@ pub const FuncGen = struct { |
| 4666 | 4674 | _ = self.builder.buildBr(end_block); |
| 4667 | 4675 | |
| 4668 | 4676 | self.builder.positionBuilderAtEnd(both_pl_block); |
| 4669 | | const lhs_payload = self.optPayloadHandle(lhs, scalar_ty); |
| 4670 | | const rhs_payload = self.optPayloadHandle(rhs, scalar_ty); |
| 4677 | const lhs_payload = self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty); |
| 4678 | const rhs_payload = self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty); |
| 4671 | 4679 | const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op); |
| 4672 | 4680 | _ = self.builder.buildBr(end_block); |
| 4673 | 4681 | const both_pl_block_end = self.builder.getInsertBlock(); |
| ... | ... | @@ -4832,10 +4840,18 @@ pub const FuncGen = struct { |
| 4832 | 4840 | return lowerTry(self, err_union_ptr, body, err_union_ty, true, result_ty); |
| 4833 | 4841 | } |
| 4834 | 4842 | |
| 4835 | | fn lowerTry(fg: *FuncGen, err_union: *const llvm.Value, body: []const Air.Inst.Index, err_union_ty: Type, operand_is_ptr: bool, result_ty: Type) !?*const llvm.Value { |
| 4843 | fn lowerTry( |
| 4844 | fg: *FuncGen, |
| 4845 | err_union: *const llvm.Value, |
| 4846 | body: []const Air.Inst.Index, |
| 4847 | err_union_ty: Type, |
| 4848 | operand_is_ptr: bool, |
| 4849 | result_ty: Type, |
| 4850 | ) !?*const llvm.Value { |
| 4836 | 4851 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 4837 | 4852 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| 4838 | 4853 | const target = fg.dg.module.getTarget(); |
| 4854 | const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty); |
| 4839 | 4855 | |
| 4840 | 4856 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 4841 | 4857 | const is_err = err: { |
| ... | ... | @@ -4843,14 +4859,17 @@ pub const FuncGen = struct { |
| 4843 | 4859 | const zero = err_set_ty.constNull(); |
| 4844 | 4860 | if (!payload_has_bits) { |
| 4845 | 4861 | // TODO add alignment to this load |
| 4846 | | const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union; |
| 4862 | const loaded = if (operand_is_ptr) |
| 4863 | fg.builder.buildLoad(err_set_ty, err_union, "") |
| 4864 | else |
| 4865 | err_union; |
| 4847 | 4866 | break :err fg.builder.buildICmp(.NE, loaded, zero, ""); |
| 4848 | 4867 | } |
| 4849 | 4868 | const err_field_index = errUnionErrorOffset(payload_ty, target); |
| 4850 | 4869 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| 4851 | | const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, ""); |
| 4870 | const err_field_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, err_field_index, ""); |
| 4852 | 4871 | // TODO add alignment to this load |
| 4853 | | const loaded = fg.builder.buildLoad(err_field_ptr, ""); |
| 4872 | const loaded = fg.builder.buildLoad(err_set_ty, err_field_ptr, ""); |
| 4854 | 4873 | break :err fg.builder.buildICmp(.NE, loaded, zero, ""); |
| 4855 | 4874 | } |
| 4856 | 4875 | const loaded = fg.builder.buildExtractValue(err_union, err_field_index, ""); |
| ... | ... | @@ -4876,13 +4895,13 @@ pub const FuncGen = struct { |
| 4876 | 4895 | } |
| 4877 | 4896 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 4878 | 4897 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4879 | | return fg.builder.buildStructGEP(err_union, offset, ""); |
| 4898 | return fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, ""); |
| 4880 | 4899 | } else if (isByRef(err_union_ty)) { |
| 4881 | | const payload_ptr = fg.builder.buildStructGEP(err_union, offset, ""); |
| 4900 | const payload_ptr = fg.builder.buildStructGEP(err_union_llvm_ty, err_union, offset, ""); |
| 4882 | 4901 | if (isByRef(payload_ty)) { |
| 4883 | 4902 | return payload_ptr; |
| 4884 | 4903 | } |
| 4885 | | const load_inst = fg.builder.buildLoad(payload_ptr, ""); |
| 4904 | const load_inst = fg.builder.buildLoad(payload_ptr.getGEPSourceElementType(), payload_ptr, ""); |
| 4886 | 4905 | load_inst.setAlignment(payload_ty.abiAlignment(target)); |
| 4887 | 4906 | return load_inst; |
| 4888 | 4907 | } |
| ... | ... | @@ -4977,7 +4996,8 @@ pub const FuncGen = struct { |
| 4977 | 4996 | const indices: [2]*const llvm.Value = .{ |
| 4978 | 4997 | llvm_usize.constNull(), llvm_usize.constNull(), |
| 4979 | 4998 | }; |
| 4980 | | const ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 4999 | const elem_llvm_ty = try self.dg.lowerType(array_ty.childType()); |
| 5000 | const ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, operand, &indices, indices.len, ""); |
| 4981 | 5001 | const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, ""); |
| 4982 | 5002 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 4983 | 5003 | } |
| ... | ... | @@ -5038,7 +5058,7 @@ pub const FuncGen = struct { |
| 5038 | 5058 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 5039 | 5059 | const params = [1]*const llvm.Value{extended}; |
| 5040 | 5060 | |
| 5041 | | return self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 5061 | return self.builder.buildCall(libc_fn.typeOf(), libc_fn, &params, params.len, .C, .Auto, ""); |
| 5042 | 5062 | } |
| 5043 | 5063 | |
| 5044 | 5064 | fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { |
| ... | ... | @@ -5093,7 +5113,7 @@ pub const FuncGen = struct { |
| 5093 | 5113 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 5094 | 5114 | const params = [1]*const llvm.Value{operand}; |
| 5095 | 5115 | |
| 5096 | | var result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 5116 | var result = self.builder.buildCall(libc_fn.typeOf(), libc_fn, &params, params.len, .C, .Auto, ""); |
| 5097 | 5117 | |
| 5098 | 5118 | if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, ""); |
| 5099 | 5119 | if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, ""); |
| ... | ... | @@ -5113,8 +5133,9 @@ pub const FuncGen = struct { |
| 5113 | 5133 | |
| 5114 | 5134 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5115 | 5135 | const slice_ptr = try self.resolveInst(ty_op.operand); |
| 5136 | const slice_llvm_ty = try self.dg.lowerType(self.air.typeOf(ty_op.operand).childType()); |
| 5116 | 5137 | |
| 5117 | | return self.builder.buildStructGEP(slice_ptr, index, ""); |
| 5138 | return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); |
| 5118 | 5139 | } |
| 5119 | 5140 | |
| 5120 | 5141 | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5124,7 +5145,10 @@ pub const FuncGen = struct { |
| 5124 | 5145 | |
| 5125 | 5146 | const slice = try self.resolveInst(bin_op.lhs); |
| 5126 | 5147 | const index = try self.resolveInst(bin_op.rhs); |
| 5127 | | const ptr = self.sliceElemPtr(slice, index); |
| 5148 | const llvm_elem_ty = try self.dg.lowerType(slice_ty.childType()); |
| 5149 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 5150 | const indices: [1]*const llvm.Value = .{index}; |
| 5151 | const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5128 | 5152 | return self.load(ptr, slice_ty); |
| 5129 | 5153 | } |
| 5130 | 5154 | |
| ... | ... | @@ -5132,10 +5156,14 @@ pub const FuncGen = struct { |
| 5132 | 5156 | if (self.liveness.isUnused(inst)) return null; |
| 5133 | 5157 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5134 | 5158 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 5159 | const slice_ty = self.air.typeOf(bin_op.lhs); |
| 5135 | 5160 | |
| 5136 | 5161 | const slice = try self.resolveInst(bin_op.lhs); |
| 5137 | 5162 | const index = try self.resolveInst(bin_op.rhs); |
| 5138 | | return self.sliceElemPtr(slice, index); |
| 5163 | const llvm_elem_ty = try self.dg.lowerType(slice_ty.childType()); |
| 5164 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 5165 | const indices: [1]*const llvm.Value = .{index}; |
| 5166 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5139 | 5167 | } |
| 5140 | 5168 | |
| 5141 | 5169 | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5146,13 +5174,14 @@ pub const FuncGen = struct { |
| 5146 | 5174 | const array_llvm_val = try self.resolveInst(bin_op.lhs); |
| 5147 | 5175 | const rhs = try self.resolveInst(bin_op.rhs); |
| 5148 | 5176 | if (isByRef(array_ty)) { |
| 5149 | | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5150 | | const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_val, &indices, indices.len, ""); |
| 5151 | 5177 | const elem_ty = array_ty.childType(); |
| 5178 | const elem_llvm_ty = try self.dg.lowerType(elem_ty); |
| 5179 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5180 | const elem_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, array_llvm_val, &indices, indices.len, ""); |
| 5152 | 5181 | if (isByRef(elem_ty)) { |
| 5153 | 5182 | return elem_ptr; |
| 5154 | 5183 | } else { |
| 5155 | | return self.builder.buildLoad(elem_ptr, ""); |
| 5184 | return self.builder.buildLoad(elem_llvm_ty, elem_ptr, ""); |
| 5156 | 5185 | } |
| 5157 | 5186 | } |
| 5158 | 5187 | |
| ... | ... | @@ -5165,15 +5194,16 @@ pub const FuncGen = struct { |
| 5165 | 5194 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 5166 | 5195 | if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; |
| 5167 | 5196 | |
| 5197 | const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType()); |
| 5168 | 5198 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 5169 | 5199 | const rhs = try self.resolveInst(bin_op.rhs); |
| 5170 | 5200 | const ptr = if (ptr_ty.isSinglePointer()) ptr: { |
| 5171 | 5201 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 5172 | 5202 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5173 | | break :ptr self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 5203 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5174 | 5204 | } else ptr: { |
| 5175 | 5205 | const indices: [1]*const llvm.Value = .{rhs}; |
| 5176 | | break :ptr self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 5206 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5177 | 5207 | }; |
| 5178 | 5208 | return self.load(ptr, ptr_ty); |
| 5179 | 5209 | } |
| ... | ... | @@ -5189,13 +5219,14 @@ pub const FuncGen = struct { |
| 5189 | 5219 | |
| 5190 | 5220 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 5191 | 5221 | const rhs = try self.resolveInst(bin_op.rhs); |
| 5222 | const llvm_elem_ty = try self.dg.lowerType(elem_ty); |
| 5192 | 5223 | if (ptr_ty.isSinglePointer()) { |
| 5193 | 5224 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 5194 | 5225 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5195 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 5226 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5196 | 5227 | } else { |
| 5197 | 5228 | const indices: [1]*const llvm.Value = .{rhs}; |
| 5198 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 5229 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5199 | 5230 | } |
| 5200 | 5231 | } |
| 5201 | 5232 | |
| ... | ... | @@ -5279,20 +5310,22 @@ pub const FuncGen = struct { |
| 5279 | 5310 | assert(struct_ty.containerLayout() != .Packed); |
| 5280 | 5311 | var ptr_ty_buf: Type.Payload.Pointer = undefined; |
| 5281 | 5312 | const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?; |
| 5282 | | const field_ptr = self.builder.buildStructGEP(struct_llvm_val, llvm_field_index, ""); |
| 5313 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); |
| 5314 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, ""); |
| 5283 | 5315 | const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base); |
| 5284 | 5316 | return self.load(field_ptr, field_ptr_ty); |
| 5285 | 5317 | }, |
| 5286 | 5318 | .Union => { |
| 5287 | | const llvm_field_ty = try self.dg.lowerType(field_ty); |
| 5319 | const union_llvm_ty = try self.dg.lowerType(struct_ty); |
| 5288 | 5320 | const layout = struct_ty.unionGetLayout(target); |
| 5289 | 5321 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); |
| 5290 | | const union_field_ptr = self.builder.buildStructGEP(struct_llvm_val, payload_index, ""); |
| 5322 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 5323 | const llvm_field_ty = try self.dg.lowerType(field_ty); |
| 5291 | 5324 | const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), ""); |
| 5292 | 5325 | if (isByRef(field_ty)) { |
| 5293 | 5326 | return field_ptr; |
| 5294 | 5327 | } else { |
| 5295 | | return self.builder.buildLoad(field_ptr, ""); |
| 5328 | return self.builder.buildLoad(llvm_field_ty, field_ptr, ""); |
| 5296 | 5329 | } |
| 5297 | 5330 | }, |
| 5298 | 5331 | else => unreachable, |
| ... | ... | @@ -5605,10 +5638,11 @@ pub const FuncGen = struct { |
| 5605 | 5638 | llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf(); |
| 5606 | 5639 | } else { |
| 5607 | 5640 | const alignment = arg_ty.abiAlignment(target); |
| 5608 | | const load_inst = self.builder.buildLoad(arg_llvm_value, ""); |
| 5641 | const arg_llvm_ty = try self.dg.lowerType(arg_ty); |
| 5642 | const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, ""); |
| 5609 | 5643 | load_inst.setAlignment(alignment); |
| 5610 | 5644 | llvm_param_values[llvm_param_i] = load_inst; |
| 5611 | | llvm_param_types[llvm_param_i] = load_inst.typeOf(); |
| 5645 | llvm_param_types[llvm_param_i] = arg_llvm_ty; |
| 5612 | 5646 | } |
| 5613 | 5647 | } else { |
| 5614 | 5648 | if (constraintAllowsRegister(constraint)) { |
| ... | ... | @@ -5769,6 +5803,7 @@ pub const FuncGen = struct { |
| 5769 | 5803 | .False, |
| 5770 | 5804 | ); |
| 5771 | 5805 | const call = self.builder.buildCall( |
| 5806 | asm_fn.typeOf(), |
| 5772 | 5807 | asm_fn, |
| 5773 | 5808 | llvm_param_values.ptr, |
| 5774 | 5809 | @intCast(c_uint, param_count), |
| ... | ... | @@ -5819,9 +5854,12 @@ pub const FuncGen = struct { |
| 5819 | 5854 | const operand = try self.resolveInst(un_op); |
| 5820 | 5855 | const operand_ty = self.air.typeOf(un_op); |
| 5821 | 5856 | const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5857 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 5822 | 5858 | if (optional_ty.optionalReprIsPayload()) { |
| 5823 | | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 5824 | | const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; |
| 5859 | const loaded = if (operand_is_ptr) |
| 5860 | self.builder.buildLoad(optional_llvm_ty, operand, "") |
| 5861 | else |
| 5862 | operand; |
| 5825 | 5863 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| 5826 | 5864 | } |
| 5827 | 5865 | |
| ... | ... | @@ -5830,13 +5868,16 @@ pub const FuncGen = struct { |
| 5830 | 5868 | var buf: Type.Payload.ElemType = undefined; |
| 5831 | 5869 | const payload_ty = optional_ty.optionalChild(&buf); |
| 5832 | 5870 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 5833 | | const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; |
| 5871 | const loaded = if (operand_is_ptr) |
| 5872 | self.builder.buildLoad(optional_llvm_ty, operand, "") |
| 5873 | else |
| 5874 | operand; |
| 5834 | 5875 | const llvm_i8 = self.dg.context.intType(8); |
| 5835 | 5876 | return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), ""); |
| 5836 | 5877 | } |
| 5837 | 5878 | |
| 5838 | 5879 | const is_by_ref = operand_is_ptr or isByRef(optional_ty); |
| 5839 | | const non_null_bit = self.optIsNonNull(operand, is_by_ref); |
| 5880 | const non_null_bit = self.optIsNonNull(optional_llvm_ty, operand, is_by_ref); |
| 5840 | 5881 | if (pred == .EQ) { |
| 5841 | 5882 | return self.builder.buildNot(non_null_bit, ""); |
| 5842 | 5883 | } else { |
| ... | ... | @@ -5857,7 +5898,7 @@ pub const FuncGen = struct { |
| 5857 | 5898 | const operand_ty = self.air.typeOf(un_op); |
| 5858 | 5899 | const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5859 | 5900 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 5860 | | const err_set_ty = try self.dg.lowerType(Type.initTag(.anyerror)); |
| 5901 | const err_set_ty = try self.dg.lowerType(Type.anyerror); |
| 5861 | 5902 | const zero = err_set_ty.constNull(); |
| 5862 | 5903 | |
| 5863 | 5904 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| ... | ... | @@ -5870,7 +5911,10 @@ pub const FuncGen = struct { |
| 5870 | 5911 | } |
| 5871 | 5912 | |
| 5872 | 5913 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 5873 | | const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; |
| 5914 | const loaded = if (operand_is_ptr) |
| 5915 | self.builder.buildLoad(try self.dg.lowerType(err_union_ty), operand, "") |
| 5916 | else |
| 5917 | operand; |
| 5874 | 5918 | return self.builder.buildICmp(op, loaded, zero, ""); |
| 5875 | 5919 | } |
| 5876 | 5920 | |
| ... | ... | @@ -5878,8 +5922,9 @@ pub const FuncGen = struct { |
| 5878 | 5922 | const err_field_index = errUnionErrorOffset(payload_ty, target); |
| 5879 | 5923 | |
| 5880 | 5924 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| 5881 | | const err_field_ptr = self.builder.buildStructGEP(operand, err_field_index, ""); |
| 5882 | | const loaded = self.builder.buildLoad(err_field_ptr, ""); |
| 5925 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| 5926 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, ""); |
| 5927 | const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, ""); |
| 5883 | 5928 | return self.builder.buildICmp(op, loaded, zero, ""); |
| 5884 | 5929 | } |
| 5885 | 5930 | |
| ... | ... | @@ -5900,7 +5945,7 @@ pub const FuncGen = struct { |
| 5900 | 5945 | // We have a pointer to a zero-bit value and we need to return |
| 5901 | 5946 | // a pointer to a zero-bit value. |
| 5902 | 5947 | |
| 5903 | | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| 5948 | // TODO once we update to LLVM 16 this bitcast won't be necessary. |
| 5904 | 5949 | const res_ptr_ty = try self.dg.lowerType(result_ty); |
| 5905 | 5950 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| 5906 | 5951 | } |
| ... | ... | @@ -5908,7 +5953,8 @@ pub const FuncGen = struct { |
| 5908 | 5953 | // The payload and the optional are the same value. |
| 5909 | 5954 | return operand; |
| 5910 | 5955 | } |
| 5911 | | return self.builder.buildStructGEP(operand, 0, ""); |
| 5956 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 5957 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 5912 | 5958 | } |
| 5913 | 5959 | |
| 5914 | 5960 | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5925,7 +5971,7 @@ pub const FuncGen = struct { |
| 5925 | 5971 | // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. |
| 5926 | 5972 | _ = self.builder.buildStore(non_null_bit, operand); |
| 5927 | 5973 | |
| 5928 | | // TODO once we update to LLVM 14 this bitcast won't be necessary. |
| 5974 | // TODO once we update to LLVM 16 this bitcast won't be necessary. |
| 5929 | 5975 | const res_ptr_ty = try self.dg.lowerType(result_ty); |
| 5930 | 5976 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| 5931 | 5977 | } |
| ... | ... | @@ -5936,7 +5982,8 @@ pub const FuncGen = struct { |
| 5936 | 5982 | } |
| 5937 | 5983 | |
| 5938 | 5984 | // First set the non-null bit. |
| 5939 | | const non_null_ptr = self.builder.buildStructGEP(operand, 1, ""); |
| 5985 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 5986 | const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, ""); |
| 5940 | 5987 | // TODO set alignment on this store |
| 5941 | 5988 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| 5942 | 5989 | |
| ... | ... | @@ -5944,7 +5991,7 @@ pub const FuncGen = struct { |
| 5944 | 5991 | if (self.liveness.isUnused(inst)) |
| 5945 | 5992 | return null; |
| 5946 | 5993 | |
| 5947 | | return self.builder.buildStructGEP(operand, 0, ""); |
| 5994 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 5948 | 5995 | } |
| 5949 | 5996 | |
| 5950 | 5997 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -5961,7 +6008,8 @@ pub const FuncGen = struct { |
| 5961 | 6008 | return operand; |
| 5962 | 6009 | } |
| 5963 | 6010 | |
| 5964 | | return self.optPayloadHandle(operand, optional_ty); |
| 6011 | const opt_llvm_ty = try self.dg.lowerType(optional_ty); |
| 6012 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty); |
| 5965 | 6013 | } |
| 5966 | 6014 | |
| 5967 | 6015 | fn airErrUnionPayload( |
| ... | ... | @@ -5987,14 +6035,15 @@ pub const FuncGen = struct { |
| 5987 | 6035 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); |
| 5988 | 6036 | } |
| 5989 | 6037 | const offset = errUnionPayloadOffset(payload_ty, target); |
| 6038 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| 5990 | 6039 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 5991 | | return self.builder.buildStructGEP(operand, offset, ""); |
| 6040 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 5992 | 6041 | } else if (isByRef(err_union_ty)) { |
| 5993 | | const payload_ptr = self.builder.buildStructGEP(operand, offset, ""); |
| 6042 | const payload_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 5994 | 6043 | if (isByRef(payload_ty)) { |
| 5995 | 6044 | return payload_ptr; |
| 5996 | 6045 | } |
| 5997 | | const load_inst = self.builder.buildLoad(payload_ptr, ""); |
| 6046 | const load_inst = self.builder.buildLoad(payload_ptr.getGEPSourceElementType(), payload_ptr, ""); |
| 5998 | 6047 | load_inst.setAlignment(payload_ty.abiAlignment(target)); |
| 5999 | 6048 | return load_inst; |
| 6000 | 6049 | } |
| ... | ... | @@ -6022,18 +6071,21 @@ pub const FuncGen = struct { |
| 6022 | 6071 | } |
| 6023 | 6072 | } |
| 6024 | 6073 | |
| 6074 | const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror); |
| 6075 | |
| 6025 | 6076 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 6026 | 6077 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6027 | 6078 | if (!operand_is_ptr) return operand; |
| 6028 | | return self.builder.buildLoad(operand, ""); |
| 6079 | return self.builder.buildLoad(err_set_llvm_ty, operand, ""); |
| 6029 | 6080 | } |
| 6030 | 6081 | |
| 6031 | 6082 | const target = self.dg.module.getTarget(); |
| 6032 | 6083 | const offset = errUnionErrorOffset(payload_ty, target); |
| 6033 | 6084 | |
| 6034 | 6085 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| 6035 | | const err_field_ptr = self.builder.buildStructGEP(operand, offset, ""); |
| 6036 | | return self.builder.buildLoad(err_field_ptr, ""); |
| 6086 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| 6087 | const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, ""); |
| 6088 | return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, ""); |
| 6037 | 6089 | } |
| 6038 | 6090 | |
| 6039 | 6091 | return self.builder.buildExtractValue(operand, offset, ""); |
| ... | ... | @@ -6042,19 +6094,20 @@ pub const FuncGen = struct { |
| 6042 | 6094 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 6043 | 6095 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6044 | 6096 | const operand = try self.resolveInst(ty_op.operand); |
| 6045 | | const error_union_ty = self.air.typeOf(ty_op.operand).childType(); |
| 6097 | const err_union_ty = self.air.typeOf(ty_op.operand).childType(); |
| 6046 | 6098 | |
| 6047 | | const payload_ty = error_union_ty.errorUnionPayload(); |
| 6099 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 6048 | 6100 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero }); |
| 6049 | 6101 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 6050 | 6102 | _ = self.builder.buildStore(non_error_val, operand); |
| 6051 | 6103 | return operand; |
| 6052 | 6104 | } |
| 6053 | 6105 | const target = self.dg.module.getTarget(); |
| 6106 | const err_union_llvm_ty = try self.dg.lowerType(err_union_ty); |
| 6054 | 6107 | { |
| 6055 | 6108 | const error_offset = errUnionErrorOffset(payload_ty, target); |
| 6056 | 6109 | // First set the non-error value. |
| 6057 | | const non_null_ptr = self.builder.buildStructGEP(operand, error_offset, ""); |
| 6110 | const non_null_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, error_offset, ""); |
| 6058 | 6111 | const store_inst = self.builder.buildStore(non_error_val, non_null_ptr); |
| 6059 | 6112 | store_inst.setAlignment(Type.anyerror.abiAlignment(target)); |
| 6060 | 6113 | } |
| ... | ... | @@ -6063,7 +6116,7 @@ pub const FuncGen = struct { |
| 6063 | 6116 | return null; |
| 6064 | 6117 | |
| 6065 | 6118 | const payload_offset = errUnionPayloadOffset(payload_ty, target); |
| 6066 | | return self.builder.buildStructGEP(operand, payload_offset, ""); |
| 6119 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, ""); |
| 6067 | 6120 | } |
| 6068 | 6121 | |
| 6069 | 6122 | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -6093,14 +6146,14 @@ pub const FuncGen = struct { |
| 6093 | 6146 | const llvm_optional_ty = try self.dg.lowerType(optional_ty); |
| 6094 | 6147 | if (isByRef(optional_ty)) { |
| 6095 | 6148 | const optional_ptr = self.buildAlloca(llvm_optional_ty); |
| 6096 | | const payload_ptr = self.builder.buildStructGEP(optional_ptr, 0, ""); |
| 6149 | const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); |
| 6097 | 6150 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 6098 | 6151 | .base = .{ .tag = .single_mut_pointer }, |
| 6099 | 6152 | .data = payload_ty, |
| 6100 | 6153 | }; |
| 6101 | 6154 | const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 6102 | 6155 | self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); |
| 6103 | | const non_null_ptr = self.builder.buildStructGEP(optional_ptr, 1, ""); |
| 6156 | const non_null_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 1, ""); |
| 6104 | 6157 | _ = self.builder.buildStore(non_null_bit, non_null_ptr); |
| 6105 | 6158 | return optional_ptr; |
| 6106 | 6159 | } |
| ... | ... | @@ -6126,10 +6179,10 @@ pub const FuncGen = struct { |
| 6126 | 6179 | const error_offset = errUnionErrorOffset(payload_ty, target); |
| 6127 | 6180 | if (isByRef(inst_ty)) { |
| 6128 | 6181 | const result_ptr = self.buildAlloca(err_un_llvm_ty); |
| 6129 | | const err_ptr = self.builder.buildStructGEP(result_ptr, error_offset, ""); |
| 6182 | const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 6130 | 6183 | const store_inst = self.builder.buildStore(ok_err_code, err_ptr); |
| 6131 | 6184 | store_inst.setAlignment(Type.anyerror.abiAlignment(target)); |
| 6132 | | const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, ""); |
| 6185 | const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 6133 | 6186 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 6134 | 6187 | .base = .{ .tag = .single_mut_pointer }, |
| 6135 | 6188 | .data = payload_ty, |
| ... | ... | @@ -6160,10 +6213,10 @@ pub const FuncGen = struct { |
| 6160 | 6213 | const error_offset = errUnionErrorOffset(payload_ty, target); |
| 6161 | 6214 | if (isByRef(err_un_ty)) { |
| 6162 | 6215 | const result_ptr = self.buildAlloca(err_un_llvm_ty); |
| 6163 | | const err_ptr = self.builder.buildStructGEP(result_ptr, error_offset, ""); |
| 6216 | const err_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, error_offset, ""); |
| 6164 | 6217 | const store_inst = self.builder.buildStore(operand, err_ptr); |
| 6165 | 6218 | store_inst.setAlignment(Type.anyerror.abiAlignment(target)); |
| 6166 | | const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, ""); |
| 6219 | const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, ""); |
| 6167 | 6220 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 6168 | 6221 | .base = .{ .tag = .single_mut_pointer }, |
| 6169 | 6222 | .data = payload_ty, |
| ... | ... | @@ -6188,7 +6241,7 @@ pub const FuncGen = struct { |
| 6188 | 6241 | const llvm_u32 = self.context.intType(32); |
| 6189 | 6242 | const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32}); |
| 6190 | 6243 | const args: [1]*const llvm.Value = .{llvm_u32.constInt(index, .False)}; |
| 6191 | | return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6244 | return self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6192 | 6245 | } |
| 6193 | 6246 | |
| 6194 | 6247 | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -6201,7 +6254,7 @@ pub const FuncGen = struct { |
| 6201 | 6254 | llvm_u32.constInt(index, .False), |
| 6202 | 6255 | operand, |
| 6203 | 6256 | }; |
| 6204 | | return self.builder.buildCall(llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6257 | return self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6205 | 6258 | } |
| 6206 | 6259 | |
| 6207 | 6260 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -6504,15 +6557,16 @@ pub const FuncGen = struct { |
| 6504 | 6557 | const base_ptr = try self.resolveInst(bin_op.lhs); |
| 6505 | 6558 | const offset = try self.resolveInst(bin_op.rhs); |
| 6506 | 6559 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 6560 | const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType()); |
| 6507 | 6561 | if (ptr_ty.ptrSize() == .One) { |
| 6508 | 6562 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 6509 | 6563 | const indices: [2]*const llvm.Value = .{ |
| 6510 | 6564 | self.context.intType(32).constNull(), offset, |
| 6511 | 6565 | }; |
| 6512 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 6566 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6513 | 6567 | } else { |
| 6514 | 6568 | const indices: [1]*const llvm.Value = .{offset}; |
| 6515 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 6569 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6516 | 6570 | } |
| 6517 | 6571 | } |
| 6518 | 6572 | |
| ... | ... | @@ -6525,15 +6579,16 @@ pub const FuncGen = struct { |
| 6525 | 6579 | const offset = try self.resolveInst(bin_op.rhs); |
| 6526 | 6580 | const negative_offset = self.builder.buildNeg(offset, ""); |
| 6527 | 6581 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 6582 | const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType()); |
| 6528 | 6583 | if (ptr_ty.ptrSize() == .One) { |
| 6529 | 6584 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 6530 | 6585 | const indices: [2]*const llvm.Value = .{ |
| 6531 | 6586 | self.context.intType(32).constNull(), negative_offset, |
| 6532 | 6587 | }; |
| 6533 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 6588 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6534 | 6589 | } else { |
| 6535 | 6590 | const indices: [1]*const llvm.Value = .{negative_offset}; |
| 6536 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 6591 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6537 | 6592 | } |
| 6538 | 6593 | } |
| 6539 | 6594 | |
| ... | ... | @@ -6564,7 +6619,7 @@ pub const FuncGen = struct { |
| 6564 | 6619 | const tg = self.dg.module.getTarget(); |
| 6565 | 6620 | |
| 6566 | 6621 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); |
| 6567 | | const result_struct = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); |
| 6622 | const result_struct = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &[_]*const llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); |
| 6568 | 6623 | |
| 6569 | 6624 | const result = self.builder.buildExtractValue(result_struct, 0, ""); |
| 6570 | 6625 | const overflow_bit = self.builder.buildExtractValue(result_struct, 1, ""); |
| ... | ... | @@ -6579,12 +6634,12 @@ pub const FuncGen = struct { |
| 6579 | 6634 | const result_alignment = dest_ty.abiAlignment(target); |
| 6580 | 6635 | alloca_inst.setAlignment(result_alignment); |
| 6581 | 6636 | { |
| 6582 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, ""); |
| 6637 | const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, ""); |
| 6583 | 6638 | const store_inst = self.builder.buildStore(result, field_ptr); |
| 6584 | 6639 | store_inst.setAlignment(result_alignment); |
| 6585 | 6640 | } |
| 6586 | 6641 | { |
| 6587 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, ""); |
| 6642 | const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, overflow_index, ""); |
| 6588 | 6643 | const store_inst = self.builder.buildStore(overflow_bit, field_ptr); |
| 6589 | 6644 | store_inst.setAlignment(1); |
| 6590 | 6645 | } |
| ... | ... | @@ -6616,7 +6671,7 @@ pub const FuncGen = struct { |
| 6616 | 6671 | for (args_vectors) |arg_vector, k| { |
| 6617 | 6672 | args[k] = self.builder.buildExtractElement(arg_vector, index_i32, ""); |
| 6618 | 6673 | } |
| 6619 | | const result_elem = self.builder.buildCall(llvm_fn, &args, args_len, .C, .Auto, ""); |
| 6674 | const result_elem = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &args, args_len, .C, .Auto, ""); |
| 6620 | 6675 | result = self.builder.buildInsertElement(result, result_elem, index_i32, ""); |
| 6621 | 6676 | } |
| 6622 | 6677 | return result; |
| ... | ... | @@ -6743,7 +6798,7 @@ pub const FuncGen = struct { |
| 6743 | 6798 | return self.builder.buildICmp(int_pred, result, zero_vector, ""); |
| 6744 | 6799 | } |
| 6745 | 6800 | |
| 6746 | | const result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 6801 | const result = self.builder.buildCall(libc_fn.typeOf(), libc_fn, &params, params.len, .C, .Auto, ""); |
| 6747 | 6802 | return self.builder.buildICmp(int_pred, result, zero, ""); |
| 6748 | 6803 | } |
| 6749 | 6804 | |
| ... | ... | @@ -6871,7 +6926,7 @@ pub const FuncGen = struct { |
| 6871 | 6926 | break :b libc_fn; |
| 6872 | 6927 | }, |
| 6873 | 6928 | }; |
| 6874 | | return self.builder.buildCall(llvm_fn, &params, params_len, .C, .Auto, ""); |
| 6929 | return self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &params, params_len, .C, .Auto, ""); |
| 6875 | 6930 | } |
| 6876 | 6931 | |
| 6877 | 6932 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -6931,12 +6986,12 @@ pub const FuncGen = struct { |
| 6931 | 6986 | const result_alignment = dest_ty.abiAlignment(target); |
| 6932 | 6987 | alloca_inst.setAlignment(result_alignment); |
| 6933 | 6988 | { |
| 6934 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, ""); |
| 6989 | const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, result_index, ""); |
| 6935 | 6990 | const store_inst = self.builder.buildStore(result, field_ptr); |
| 6936 | 6991 | store_inst.setAlignment(result_alignment); |
| 6937 | 6992 | } |
| 6938 | 6993 | { |
| 6939 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, ""); |
| 6994 | const field_ptr = self.builder.buildStructGEP(llvm_dest_ty, alloca_inst, overflow_index, ""); |
| 6940 | 6995 | const store_inst = self.builder.buildStore(overflow_bit, field_ptr); |
| 6941 | 6996 | store_inst.setAlignment(1); |
| 6942 | 6997 | } |
| ... | ... | @@ -7226,7 +7281,7 @@ pub const FuncGen = struct { |
| 7226 | 7281 | const index_usize = llvm_usize.constInt(i, .False); |
| 7227 | 7282 | const index_u32 = llvm_u32.constInt(i, .False); |
| 7228 | 7283 | const indexes: [2]*const llvm.Value = .{ zero, index_usize }; |
| 7229 | | const elem_ptr = self.builder.buildInBoundsGEP(array_ptr, &indexes, indexes.len, ""); |
| 7284 | const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, ""); |
| 7230 | 7285 | const elem = self.builder.buildExtractElement(operand, index_u32, ""); |
| 7231 | 7286 | _ = self.builder.buildStore(elem, elem_ptr); |
| 7232 | 7287 | } |
| ... | ... | @@ -7243,7 +7298,7 @@ pub const FuncGen = struct { |
| 7243 | 7298 | if (bitcast_ok) { |
| 7244 | 7299 | const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0); |
| 7245 | 7300 | const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, ""); |
| 7246 | | const vector = self.builder.buildLoad(casted_ptr, ""); |
| 7301 | const vector = self.builder.buildLoad(llvm_vector_ty, casted_ptr, ""); |
| 7247 | 7302 | // The array is aligned to the element's alignment, while the vector might have a completely |
| 7248 | 7303 | // different alignment. This means we need to enforce the alignment of this load. |
| 7249 | 7304 | vector.setAlignment(elem_ty.abiAlignment(target)); |
| ... | ... | @@ -7251,6 +7306,7 @@ pub const FuncGen = struct { |
| 7251 | 7306 | } else { |
| 7252 | 7307 | // If the ABI size of the element type is not evenly divisible by size in bits; |
| 7253 | 7308 | // a simple bitcast will not work, and we fall back to extractelement. |
| 7309 | const elem_llvm_ty = try self.dg.lowerType(elem_ty); |
| 7254 | 7310 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 7255 | 7311 | const llvm_u32 = self.context.intType(32); |
| 7256 | 7312 | const zero = llvm_usize.constNull(); |
| ... | ... | @@ -7261,8 +7317,8 @@ pub const FuncGen = struct { |
| 7261 | 7317 | const index_usize = llvm_usize.constInt(i, .False); |
| 7262 | 7318 | const index_u32 = llvm_u32.constInt(i, .False); |
| 7263 | 7319 | const indexes: [2]*const llvm.Value = .{ zero, index_usize }; |
| 7264 | | const elem_ptr = self.builder.buildInBoundsGEP(operand, &indexes, indexes.len, ""); |
| 7265 | | const elem = self.builder.buildLoad(elem_ptr, ""); |
| 7320 | const elem_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, operand, &indexes, indexes.len, ""); |
| 7321 | const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, ""); |
| 7266 | 7322 | vector = self.builder.buildInsertElement(vector, elem, index_u32, ""); |
| 7267 | 7323 | } |
| 7268 | 7324 | |
| ... | ... | @@ -7273,7 +7329,7 @@ pub const FuncGen = struct { |
| 7273 | 7329 | if (operand_is_ref) { |
| 7274 | 7330 | // Bitcast the operand pointer, then load. |
| 7275 | 7331 | const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); |
| 7276 | | const load_inst = self.builder.buildLoad(casted_ptr, ""); |
| 7332 | const load_inst = self.builder.buildLoad(llvm_dest_ty, casted_ptr, ""); |
| 7277 | 7333 | load_inst.setAlignment(operand_ty.abiAlignment(target)); |
| 7278 | 7334 | return load_inst; |
| 7279 | 7335 | } |
| ... | ... | @@ -7301,7 +7357,7 @@ pub const FuncGen = struct { |
| 7301 | 7357 | const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), ""); |
| 7302 | 7358 | const store_inst = self.builder.buildStore(operand, casted_ptr); |
| 7303 | 7359 | store_inst.setAlignment(alignment); |
| 7304 | | const load_inst = self.builder.buildLoad(result_ptr, ""); |
| 7360 | const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, ""); |
| 7305 | 7361 | load_inst.setAlignment(alignment); |
| 7306 | 7362 | return load_inst; |
| 7307 | 7363 | } |
| ... | ... | @@ -7481,7 +7537,7 @@ pub const FuncGen = struct { |
| 7481 | 7537 | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 7482 | 7538 | _ = inst; |
| 7483 | 7539 | const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{}); |
| 7484 | | _ = self.builder.buildCall(llvm_fn, undefined, 0, .C, .Auto, ""); |
| 7540 | _ = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, undefined, 0, .C, .Auto, ""); |
| 7485 | 7541 | return null; |
| 7486 | 7542 | } |
| 7487 | 7543 | |
| ... | ... | @@ -7498,7 +7554,7 @@ pub const FuncGen = struct { |
| 7498 | 7554 | const llvm_i32 = self.context.intType(32); |
| 7499 | 7555 | const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{}); |
| 7500 | 7556 | const params = [_]*const llvm.Value{llvm_i32.constNull()}; |
| 7501 | | const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7557 | const ptr_val = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7502 | 7558 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 7503 | 7559 | } |
| 7504 | 7560 | |
| ... | ... | @@ -7515,7 +7571,7 @@ pub const FuncGen = struct { |
| 7515 | 7571 | }; |
| 7516 | 7572 | |
| 7517 | 7573 | const params = [_]*const llvm.Value{llvm_i32.constNull()}; |
| 7518 | | const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7574 | const ptr_val = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7519 | 7575 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 7520 | 7576 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 7521 | 7577 | } |
| ... | ... | @@ -7740,8 +7796,9 @@ pub const FuncGen = struct { |
| 7740 | 7796 | _ = self.builder.buildStore(new_tag, union_ptr); |
| 7741 | 7797 | return null; |
| 7742 | 7798 | } |
| 7799 | const un_llvm_ty = try self.dg.lowerType(un_ty); |
| 7743 | 7800 | const tag_index = @boolToInt(layout.tag_align < layout.payload_align); |
| 7744 | | const tag_field_ptr = self.builder.buildStructGEP(union_ptr, tag_index, ""); |
| 7801 | const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, ""); |
| 7745 | 7802 | // TODO alignment on this store |
| 7746 | 7803 | _ = self.builder.buildStore(new_tag, tag_field_ptr); |
| 7747 | 7804 | return null; |
| ... | ... | @@ -7757,12 +7814,13 @@ pub const FuncGen = struct { |
| 7757 | 7814 | if (layout.tag_size == 0) return null; |
| 7758 | 7815 | const union_handle = try self.resolveInst(ty_op.operand); |
| 7759 | 7816 | if (isByRef(un_ty)) { |
| 7817 | const llvm_un_ty = try self.dg.lowerType(un_ty); |
| 7760 | 7818 | if (layout.payload_size == 0) { |
| 7761 | | return self.builder.buildLoad(union_handle, ""); |
| 7819 | return self.builder.buildLoad(llvm_un_ty, union_handle, ""); |
| 7762 | 7820 | } |
| 7763 | 7821 | const tag_index = @boolToInt(layout.tag_align < layout.payload_align); |
| 7764 | | const tag_field_ptr = self.builder.buildStructGEP(union_handle, tag_index, ""); |
| 7765 | | return self.builder.buildLoad(tag_field_ptr, ""); |
| 7822 | const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, ""); |
| 7823 | return self.builder.buildLoad(tag_field_ptr.getGEPSourceElementType(), tag_field_ptr, ""); |
| 7766 | 7824 | } else { |
| 7767 | 7825 | if (layout.payload_size == 0) { |
| 7768 | 7826 | return union_handle; |
| ... | ... | @@ -7805,7 +7863,7 @@ pub const FuncGen = struct { |
| 7805 | 7863 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 7806 | 7864 | |
| 7807 | 7865 | const params = [_]*const llvm.Value{ operand, llvm_i1.constNull() }; |
| 7808 | | const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, ""); |
| 7866 | const wrong_size_result = self.builder.buildCall(fn_val.typeOf(), fn_val, &params, params.len, .C, .Auto, ""); |
| 7809 | 7867 | const result_ty = self.air.typeOfIndex(inst); |
| 7810 | 7868 | const result_llvm_ty = try self.dg.lowerType(result_ty); |
| 7811 | 7869 | |
| ... | ... | @@ -7832,7 +7890,7 @@ pub const FuncGen = struct { |
| 7832 | 7890 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); |
| 7833 | 7891 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 7834 | 7892 | |
| 7835 | | const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, ""); |
| 7893 | const wrong_size_result = self.builder.buildCall(fn_val.typeOf(), fn_val, &params, params.len, .C, .Auto, ""); |
| 7836 | 7894 | const result_ty = self.air.typeOfIndex(inst); |
| 7837 | 7895 | const result_llvm_ty = try self.dg.lowerType(result_ty); |
| 7838 | 7896 | |
| ... | ... | @@ -7889,7 +7947,7 @@ pub const FuncGen = struct { |
| 7889 | 7947 | const params = [_]*const llvm.Value{operand}; |
| 7890 | 7948 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 7891 | 7949 | |
| 7892 | | const wrong_size_result = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, ""); |
| 7950 | const wrong_size_result = self.builder.buildCall(fn_val.typeOf(), fn_val, &params, params.len, .C, .Auto, ""); |
| 7893 | 7951 | |
| 7894 | 7952 | const result_ty = self.air.typeOfIndex(inst); |
| 7895 | 7953 | const result_llvm_ty = try self.dg.lowerType(result_ty); |
| ... | ... | @@ -7912,7 +7970,7 @@ pub const FuncGen = struct { |
| 7912 | 7970 | |
| 7913 | 7971 | const llvm_fn = try self.getEnumTagNameFunction(enum_ty); |
| 7914 | 7972 | const params = [_]*const llvm.Value{operand}; |
| 7915 | | return self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7973 | return self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7916 | 7974 | } |
| 7917 | 7975 | |
| 7918 | 7976 | fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value { |
| ... | ... | @@ -7973,7 +8031,8 @@ pub const FuncGen = struct { |
| 7973 | 8031 | |
| 7974 | 8032 | for (fields.keys()) |name, field_index| { |
| 7975 | 8033 | const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False); |
| 7976 | | const str_global = self.dg.object.llvm_module.addGlobal(str_init.typeOf(), ""); |
| 8034 | const str_init_llvm_ty = str_init.typeOf(); |
| 8035 | const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, ""); |
| 7977 | 8036 | str_global.setInitializer(str_init); |
| 7978 | 8037 | str_global.setLinkage(.Private); |
| 7979 | 8038 | str_global.setGlobalConstant(.True); |
| ... | ... | @@ -7981,7 +8040,7 @@ pub const FuncGen = struct { |
| 7981 | 8040 | str_global.setAlignment(1); |
| 7982 | 8041 | |
| 7983 | 8042 | const slice_fields = [_]*const llvm.Value{ |
| 7984 | | str_global.constInBoundsGEP(&array_ptr_indices, array_ptr_indices.len), |
| 8043 | str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len), |
| 7985 | 8044 | usize_llvm_ty.constInt(name.len, .False), |
| 7986 | 8045 | }; |
| 7987 | 8046 | const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len); |
| ... | ... | @@ -8006,7 +8065,7 @@ pub const FuncGen = struct { |
| 8006 | 8065 | switch_instr.addCase(this_tag_int_value, return_block); |
| 8007 | 8066 | |
| 8008 | 8067 | self.builder.positionBuilderAtEnd(return_block); |
| 8009 | | const loaded = self.builder.buildLoad(slice_global, ""); |
| 8068 | const loaded = self.builder.buildLoad(llvm_ret_ty, slice_global, ""); |
| 8010 | 8069 | loaded.setAlignment(slice_alignment); |
| 8011 | 8070 | _ = self.builder.buildRet(loaded); |
| 8012 | 8071 | } |
| ... | ... | @@ -8040,12 +8099,15 @@ pub const FuncGen = struct { |
| 8040 | 8099 | |
| 8041 | 8100 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 8042 | 8101 | const operand = try self.resolveInst(un_op); |
| 8102 | const slice_ty = self.air.typeOfIndex(inst); |
| 8103 | const slice_llvm_ty = try self.dg.lowerType(slice_ty); |
| 8043 | 8104 | |
| 8044 | 8105 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 8045 | | const error_name_table = self.builder.buildLoad(error_name_table_ptr, ""); |
| 8106 | const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0); |
| 8107 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); |
| 8046 | 8108 | const indices = [_]*const llvm.Value{operand}; |
| 8047 | | const error_name_ptr = self.builder.buildInBoundsGEP(error_name_table, &indices, indices.len, ""); |
| 8048 | | return self.builder.buildLoad(error_name_ptr, ""); |
| 8109 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); |
| 8110 | return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, ""); |
| 8049 | 8111 | } |
| 8050 | 8112 | |
| 8051 | 8113 | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | ... | @@ -8222,7 +8284,7 @@ pub const FuncGen = struct { |
| 8222 | 8284 | const llvm_elem = try self.resolveInst(elem); |
| 8223 | 8285 | const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?; |
| 8224 | 8286 | indices[1] = llvm_u32.constInt(llvm_i, .False); |
| 8225 | | const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 8287 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 8226 | 8288 | var field_ptr_payload: Type.Payload.Pointer = .{ |
| 8227 | 8289 | .data = .{ |
| 8228 | 8290 | .pointee_type = self.air.typeOf(elem), |
| ... | ... | @@ -8268,7 +8330,7 @@ pub const FuncGen = struct { |
| 8268 | 8330 | llvm_usize.constNull(), |
| 8269 | 8331 | llvm_usize.constInt(@intCast(c_uint, i), .False), |
| 8270 | 8332 | }; |
| 8271 | | const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 8333 | const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 8272 | 8334 | const llvm_elem = try self.resolveInst(elem); |
| 8273 | 8335 | self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic); |
| 8274 | 8336 | } |
| ... | ... | @@ -8277,7 +8339,7 @@ pub const FuncGen = struct { |
| 8277 | 8339 | llvm_usize.constNull(), |
| 8278 | 8340 | llvm_usize.constInt(@intCast(c_uint, array_info.len), .False), |
| 8279 | 8341 | }; |
| 8280 | | const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 8342 | const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 8281 | 8343 | const llvm_elem = try self.dg.lowerValue(.{ |
| 8282 | 8344 | .ty = array_info.elem_type, |
| 8283 | 8345 | .val = sent_val, |
| ... | ... | @@ -8377,7 +8439,7 @@ pub const FuncGen = struct { |
| 8377 | 8439 | index_type.constNull(), |
| 8378 | 8440 | }; |
| 8379 | 8441 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; |
| 8380 | | const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); |
| 8442 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, ""); |
| 8381 | 8443 | self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 8382 | 8444 | return result_ptr; |
| 8383 | 8445 | } |
| ... | ... | @@ -8389,7 +8451,7 @@ pub const FuncGen = struct { |
| 8389 | 8451 | index_type.constNull(), |
| 8390 | 8452 | }; |
| 8391 | 8453 | const len: c_uint = if (field_size == layout.payload_size) 2 else 3; |
| 8392 | | const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, len, ""); |
| 8454 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, ""); |
| 8393 | 8455 | self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 8394 | 8456 | } |
| 8395 | 8457 | { |
| ... | ... | @@ -8397,7 +8459,7 @@ pub const FuncGen = struct { |
| 8397 | 8459 | index_type.constNull(), |
| 8398 | 8460 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), |
| 8399 | 8461 | }; |
| 8400 | | const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, ""); |
| 8462 | const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, ""); |
| 8401 | 8463 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); |
| 8402 | 8464 | const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False); |
| 8403 | 8465 | const store_inst = self.builder.buildStore(llvm_tag, field_ptr); |
| ... | ... | @@ -8464,7 +8526,7 @@ pub const FuncGen = struct { |
| 8464 | 8526 | llvm_u32.constInt(prefetch.locality, .False), |
| 8465 | 8527 | llvm_u32.constInt(@enumToInt(prefetch.cache), .False), |
| 8466 | 8528 | }; |
| 8467 | | _ = self.builder.buildCall(fn_val, &params, params.len, .C, .Auto, ""); |
| 8529 | _ = self.builder.buildCall(fn_val.typeOf(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8468 | 8530 | return null; |
| 8469 | 8531 | } |
| 8470 | 8532 | |
| ... | ... | @@ -8544,7 +8606,7 @@ pub const FuncGen = struct { |
| 8544 | 8606 | }; |
| 8545 | 8607 | |
| 8546 | 8608 | var args: [1]*const llvm.Value = .{arg}; |
| 8547 | | const result = self.builder.buildCall(llvm_fn, &args, args.len, .C, .Auto, ""); |
| 8609 | const result = self.builder.buildCall(llvm_fn.typeOf(), llvm_fn, &args, args.len, .C, .Auto, ""); |
| 8548 | 8610 | const final_cast_llvm_ty = final_cast orelse return result; |
| 8549 | 8611 | return self.builder.buildBitCast(result, final_cast_llvm_ty, ""); |
| 8550 | 8612 | } |
| ... | ... | @@ -8571,22 +8633,29 @@ pub const FuncGen = struct { |
| 8571 | 8633 | } |
| 8572 | 8634 | |
| 8573 | 8635 | /// Assumes the optional is not pointer-like and payload has bits. |
| 8574 | | fn optIsNonNull(self: *FuncGen, opt_handle: *const llvm.Value, is_by_ref: bool) *const llvm.Value { |
| 8636 | fn optIsNonNull( |
| 8637 | self: *FuncGen, |
| 8638 | opt_llvm_ty: *const llvm.Type, |
| 8639 | opt_handle: *const llvm.Value, |
| 8640 | is_by_ref: bool, |
| 8641 | ) *const llvm.Value { |
| 8642 | const non_null_llvm_ty = self.context.intType(8); |
| 8575 | 8643 | const field = b: { |
| 8576 | 8644 | if (is_by_ref) { |
| 8577 | | const field_ptr = self.builder.buildStructGEP(opt_handle, 1, ""); |
| 8578 | | break :b self.builder.buildLoad(field_ptr, ""); |
| 8645 | const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, ""); |
| 8646 | break :b self.builder.buildLoad(non_null_llvm_ty, field_ptr, ""); |
| 8579 | 8647 | } |
| 8580 | 8648 | break :b self.builder.buildExtractValue(opt_handle, 1, ""); |
| 8581 | 8649 | }; |
| 8582 | 8650 | comptime assert(optional_layout_version == 3); |
| 8583 | 8651 | |
| 8584 | | return self.builder.buildICmp(.NE, field, self.context.intType(8).constInt(0, .False), ""); |
| 8652 | return self.builder.buildICmp(.NE, field, non_null_llvm_ty.constInt(0, .False), ""); |
| 8585 | 8653 | } |
| 8586 | 8654 | |
| 8587 | 8655 | /// Assumes the optional is not pointer-like and payload has bits. |
| 8588 | 8656 | fn optPayloadHandle( |
| 8589 | 8657 | fg: *FuncGen, |
| 8658 | opt_llvm_ty: *const llvm.Type, |
| 8590 | 8659 | opt_handle: *const llvm.Value, |
| 8591 | 8660 | opt_ty: Type, |
| 8592 | 8661 | ) *const llvm.Value { |
| ... | ... | @@ -8595,14 +8664,14 @@ pub const FuncGen = struct { |
| 8595 | 8664 | |
| 8596 | 8665 | if (isByRef(opt_ty)) { |
| 8597 | 8666 | // We have a pointer and we need to return a pointer to the first field. |
| 8598 | | const payload_ptr = fg.builder.buildStructGEP(opt_handle, 0, ""); |
| 8667 | const payload_ptr = fg.builder.buildStructGEP(opt_llvm_ty, opt_handle, 0, ""); |
| 8599 | 8668 | |
| 8600 | 8669 | if (isByRef(payload_ty)) { |
| 8601 | 8670 | return payload_ptr; |
| 8602 | 8671 | } |
| 8603 | 8672 | const target = fg.dg.module.getTarget(); |
| 8604 | 8673 | const payload_alignment = payload_ty.abiAlignment(target); |
| 8605 | | const load_inst = fg.builder.buildLoad(payload_ptr, ""); |
| 8674 | const load_inst = fg.builder.buildLoad(payload_ptr.getGEPSourceElementType(), payload_ptr, ""); |
| 8606 | 8675 | load_inst.setAlignment(payload_alignment); |
| 8607 | 8676 | return load_inst; |
| 8608 | 8677 | } |
| ... | ... | @@ -8627,12 +8696,12 @@ pub const FuncGen = struct { |
| 8627 | 8696 | alloca_inst.setAlignment(payload_alignment); |
| 8628 | 8697 | |
| 8629 | 8698 | { |
| 8630 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, ""); |
| 8699 | const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, ""); |
| 8631 | 8700 | const store_inst = self.builder.buildStore(payload, field_ptr); |
| 8632 | 8701 | store_inst.setAlignment(payload_alignment); |
| 8633 | 8702 | } |
| 8634 | 8703 | { |
| 8635 | | const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, ""); |
| 8704 | const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 1, ""); |
| 8636 | 8705 | const store_inst = self.builder.buildStore(non_null_field, field_ptr); |
| 8637 | 8706 | store_inst.setAlignment(1); |
| 8638 | 8707 | } |
| ... | ... | @@ -8678,18 +8747,20 @@ pub const FuncGen = struct { |
| 8678 | 8747 | if (byte_offset == 0) { |
| 8679 | 8748 | return self.builder.buildBitCast(struct_ptr, result_llvm_ty, ""); |
| 8680 | 8749 | } |
| 8681 | | const llvm_bytes_ptr_ty = self.context.intType(8).pointerType(0); |
| 8682 | | const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, llvm_bytes_ptr_ty, ""); |
| 8750 | const byte_llvm_ty = self.context.intType(8); |
| 8751 | const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), ""); |
| 8683 | 8752 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 8684 | 8753 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 8685 | 8754 | const indices: [1]*const llvm.Value = .{llvm_index}; |
| 8686 | | const new_ptr = self.builder.buildInBoundsGEP(ptr_as_bytes, &indices, indices.len, ""); |
| 8755 | const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, ""); |
| 8687 | 8756 | return self.builder.buildBitCast(new_ptr, result_llvm_ty, ""); |
| 8688 | 8757 | }, |
| 8689 | 8758 | else => { |
| 8759 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); |
| 8760 | |
| 8690 | 8761 | var ty_buf: Type.Payload.Pointer = undefined; |
| 8691 | 8762 | if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| { |
| 8692 | | return self.builder.buildStructGEP(struct_ptr, llvm_field_index, ""); |
| 8763 | return self.builder.buildStructGEP(struct_llvm_ty, struct_ptr, llvm_field_index, ""); |
| 8693 | 8764 | } else { |
| 8694 | 8765 | // If we found no index then this means this is a zero sized field at the |
| 8695 | 8766 | // end of the struct. Treat our struct pointer as an array of two and get |
| ... | ... | @@ -8698,7 +8769,7 @@ pub const FuncGen = struct { |
| 8698 | 8769 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 8699 | 8770 | const llvm_index = llvm_usize.constInt(1, .False); |
| 8700 | 8771 | const indices: [1]*const llvm.Value = .{llvm_index}; |
| 8701 | | return self.builder.buildInBoundsGEP(struct_ptr, &indices, indices.len, ""); |
| 8772 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 8702 | 8773 | } |
| 8703 | 8774 | }, |
| 8704 | 8775 | }, |
| ... | ... | @@ -8716,27 +8787,18 @@ pub const FuncGen = struct { |
| 8716 | 8787 | ) !?*const llvm.Value { |
| 8717 | 8788 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; |
| 8718 | 8789 | const field = &union_obj.fields.values()[field_index]; |
| 8719 | | const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst)); |
| 8720 | 8790 | if (!field.ty.hasRuntimeBitsIgnoreComptime()) { |
| 8721 | 8791 | return null; |
| 8722 | 8792 | } |
| 8723 | 8793 | const target = self.dg.module.getTarget(); |
| 8724 | 8794 | const layout = union_ty.unionGetLayout(target); |
| 8725 | 8795 | const payload_index = @boolToInt(layout.tag_align >= layout.payload_align); |
| 8726 | | const union_field_ptr = self.builder.buildStructGEP(union_ptr, payload_index, ""); |
| 8796 | const union_llvm_ty = try self.dg.lowerType(union_ty); |
| 8797 | const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, union_ptr, payload_index, ""); |
| 8798 | const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst)); |
| 8727 | 8799 | return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, ""); |
| 8728 | 8800 | } |
| 8729 | 8801 | |
| 8730 | | fn sliceElemPtr( |
| 8731 | | self: *FuncGen, |
| 8732 | | slice: *const llvm.Value, |
| 8733 | | index: *const llvm.Value, |
| 8734 | | ) *const llvm.Value { |
| 8735 | | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 8736 | | const indices: [1]*const llvm.Value = .{index}; |
| 8737 | | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 8738 | | } |
| 8739 | | |
| 8740 | 8802 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value { |
| 8741 | 8803 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); |
| 8742 | 8804 | assert(id != 0); |
| ... | ... | @@ -8754,8 +8816,8 @@ pub const FuncGen = struct { |
| 8754 | 8816 | const ptr_alignment = ptr_ty.ptrAlignment(target); |
| 8755 | 8817 | const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr()); |
| 8756 | 8818 | if (info.host_size == 0) { |
| 8819 | const elem_llvm_ty = try self.dg.lowerType(info.pointee_type); |
| 8757 | 8820 | if (isByRef(info.pointee_type)) { |
| 8758 | | const elem_llvm_ty = try self.dg.lowerType(info.pointee_type); |
| 8759 | 8821 | const result_align = info.pointee_type.abiAlignment(target); |
| 8760 | 8822 | const max_align = @maximum(result_align, ptr_alignment); |
| 8761 | 8823 | const result_ptr = self.buildAlloca(elem_llvm_ty); |
| ... | ... | @@ -8773,15 +8835,15 @@ pub const FuncGen = struct { |
| 8773 | 8835 | ); |
| 8774 | 8836 | return result_ptr; |
| 8775 | 8837 | } |
| 8776 | | const llvm_inst = self.builder.buildLoad(ptr, ""); |
| 8838 | const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, ""); |
| 8777 | 8839 | llvm_inst.setAlignment(ptr_alignment); |
| 8778 | 8840 | llvm_inst.setVolatile(ptr_volatile); |
| 8779 | 8841 | return llvm_inst; |
| 8780 | 8842 | } |
| 8781 | 8843 | |
| 8782 | | const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0); |
| 8783 | | const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, ""); |
| 8784 | | const containing_int = self.builder.buildLoad(int_ptr, ""); |
| 8844 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 8845 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); |
| 8846 | const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, ""); |
| 8785 | 8847 | containing_int.setAlignment(ptr_alignment); |
| 8786 | 8848 | containing_int.setVolatile(ptr_volatile); |
| 8787 | 8849 | |
| ... | ... | @@ -8828,9 +8890,9 @@ pub const FuncGen = struct { |
| 8828 | 8890 | const ptr_alignment = ptr_ty.ptrAlignment(target); |
| 8829 | 8891 | const ptr_volatile = llvm.Bool.fromBool(info.@"volatile"); |
| 8830 | 8892 | if (info.host_size != 0) { |
| 8831 | | const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0); |
| 8832 | | const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, ""); |
| 8833 | | const containing_int = self.builder.buildLoad(int_ptr, ""); |
| 8893 | const int_elem_ty = self.context.intType(info.host_size * 8); |
| 8894 | const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), ""); |
| 8895 | const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, ""); |
| 8834 | 8896 | assert(ordering == .NotAtomic); |
| 8835 | 8897 | containing_int.setAlignment(ptr_alignment); |
| 8836 | 8898 | containing_int.setVolatile(ptr_volatile); |