authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-01 20:55:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-01 20:55:17-07:00
logbc2aaf18c86007ffb997513a57af29692777002f
tree9de010cc9f6a50f4902c8c77e25c15525ce1f852
parent0f793840aebcc31a678e49b1e8b2ad0a0d8656f4

stage2: LLVM lowering to opaque pointers API


2 files changed, 235 insertions(+), 167 deletions(-)

src/codegen/llvm.zig+221-159
...@@ -841,7 +841,8 @@ pub const Object = struct {...@@ -841,7 +841,8 @@ pub const Object = struct {
841 args.appendAssumeCapacity(param);841 args.appendAssumeCapacity(param);
842 } else {842 } else {
843 const alignment = param_ty.abiAlignment(target);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 load_inst.setAlignment(alignment);846 load_inst.setAlignment(alignment);
846 args.appendAssumeCapacity(load_inst);847 args.appendAssumeCapacity(load_inst);
847 }848 }
...@@ -870,7 +871,7 @@ pub const Object = struct {...@@ -870,7 +871,7 @@ pub const Object = struct {
870 if (isByRef(param_ty)) {871 if (isByRef(param_ty)) {
871 args.appendAssumeCapacity(arg_ptr);872 args.appendAssumeCapacity(arg_ptr);
872 } else {873 } else {
873 const load_inst = builder.buildLoad(arg_ptr, "");874 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
874 load_inst.setAlignment(alignment);875 load_inst.setAlignment(alignment);
875 args.appendAssumeCapacity(load_inst);876 args.appendAssumeCapacity(load_inst);
876 }877 }
...@@ -921,14 +922,14 @@ pub const Object = struct {...@@ -921,14 +922,14 @@ pub const Object = struct {
921 for (llvm_ints) |_, i_usize| {922 for (llvm_ints) |_, i_usize| {
922 const i = @intCast(c_uint, i_usize);923 const i = @intCast(c_uint, i_usize);
923 const param = llvm_func.getParam(i);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 const store_inst = builder.buildStore(param, field_ptr);926 const store_inst = builder.buildStore(param, field_ptr);
926 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);927 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
927 }928 }
928929
929 const is_by_ref = isByRef(param_ty);930 const is_by_ref = isByRef(param_ty);
930 const loaded = if (is_by_ref) arg_ptr else l: {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 load_inst.setAlignment(param_alignment);933 load_inst.setAlignment(param_alignment);
933 break :l load_inst;934 break :l load_inst;
934 };935 };
...@@ -3663,7 +3664,8 @@ pub const DeclGen = struct {...@@ -3663,7 +3664,8 @@ pub const DeclGen = struct {
3663 llvm_u32.constInt(0, .False),3664 llvm_u32.constInt(0, .False),
3664 llvm_u32.constInt(llvm_pl_index, .False),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 .Struct => {3670 .Struct => {
3669 const field_ty = parent_ty.structFieldType(field_index);3671 const field_ty = parent_ty.structFieldType(field_index);
...@@ -3693,7 +3695,8 @@ pub const DeclGen = struct {...@@ -3693,7 +3695,8 @@ pub const DeclGen = struct {
3693 llvm_u32.constInt(0, .False),3695 llvm_u32.constInt(0, .False),
3694 llvm_u32.constInt(llvm_field_index, .False),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 else => unreachable,3701 else => unreachable,
3699 }3702 }
...@@ -3707,7 +3710,8 @@ pub const DeclGen = struct {...@@ -3707,7 +3710,8 @@ pub const DeclGen = struct {
3707 const indices: [1]*const llvm.Value = .{3710 const indices: [1]*const llvm.Value = .{
3708 llvm_usize.constInt(elem_ptr.index, .False),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 .opt_payload_ptr => blk: {3716 .opt_payload_ptr => blk: {
3713 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;3717 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
...@@ -3730,7 +3734,8 @@ pub const DeclGen = struct {...@@ -3730,7 +3734,8 @@ pub const DeclGen = struct {
3730 llvm_u32.constInt(0, .False),3734 llvm_u32.constInt(0, .False),
3731 llvm_u32.constInt(0, .False),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 .eu_payload_ptr => blk: {3740 .eu_payload_ptr => blk: {
3736 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;3741 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
...@@ -3751,7 +3756,8 @@ pub const DeclGen = struct {...@@ -3751,7 +3756,8 @@ pub const DeclGen = struct {
3751 llvm_u32.constInt(0, .False),3756 llvm_u32.constInt(0, .False),
3752 llvm_u32.constInt(payload_offset, .False),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 else => unreachable,3762 else => unreachable,
3757 };3763 };
...@@ -4303,9 +4309,10 @@ pub const FuncGen = struct {...@@ -4303,9 +4309,10 @@ pub const FuncGen = struct {
4303 const arg = args[it.zig_index - 1];4309 const arg = args[it.zig_index - 1];
4304 const param_ty = self.air.typeOf(arg);4310 const param_ty = self.air.typeOf(arg);
4305 const llvm_arg = try self.resolveInst(arg);4311 const llvm_arg = try self.resolveInst(arg);
4312 const llvm_param_ty = try self.dg.lowerType(param_ty);
4306 if (isByRef(param_ty)) {4313 if (isByRef(param_ty)) {
4307 const alignment = param_ty.abiAlignment(target);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 load_inst.setAlignment(alignment);4316 load_inst.setAlignment(alignment);
4310 try llvm_args.append(load_inst);4317 try llvm_args.append(load_inst);
4311 } else {4318 } else {
...@@ -4315,7 +4322,6 @@ pub const FuncGen = struct {...@@ -4315,7 +4322,6 @@ pub const FuncGen = struct {
4315 // which is always lowered to an LLVM type of `*i8`.4322 // which is always lowered to an LLVM type of `*i8`.
4316 // 2. The argument is a global which does act as a pointer, however4323 // 2. The argument is a global which does act as a pointer, however
4317 // a bitcast is needed in order for the LLVM types to match.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 const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, "");4325 const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, "");
4320 try llvm_args.append(casted_ptr);4326 try llvm_args.append(casted_ptr);
4321 } else {4327 } else {
...@@ -4350,7 +4356,7 @@ pub const FuncGen = struct {...@@ -4350,7 +4356,7 @@ pub const FuncGen = struct {
4350 if (isByRef(param_ty)) {4356 if (isByRef(param_ty)) {
4351 const alignment = param_ty.abiAlignment(target);4357 const alignment = param_ty.abiAlignment(target);
4352 const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, "");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 load_inst.setAlignment(alignment);4360 load_inst.setAlignment(alignment);
4355 try llvm_args.append(load_inst);4361 try llvm_args.append(load_inst);
4356 } else {4362 } else {
...@@ -4366,7 +4372,7 @@ pub const FuncGen = struct {...@@ -4366,7 +4372,7 @@ pub const FuncGen = struct {
4366 const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), "");4372 const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), "");
4367 const store_inst = self.builder.buildStore(llvm_arg, casted_ptr);4373 const store_inst = self.builder.buildStore(llvm_arg, casted_ptr);
4368 store_inst.setAlignment(alignment);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 load_inst.setAlignment(alignment);4376 load_inst.setAlignment(alignment);
4371 try llvm_args.append(load_inst);4377 try llvm_args.append(load_inst);
4372 }4378 }
...@@ -4403,8 +4409,8 @@ pub const FuncGen = struct {...@@ -4403,8 +4409,8 @@ pub const FuncGen = struct {
4403 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);4409 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
4404 for (llvm_ints) |_, i_usize| {4410 for (llvm_ints) |_, i_usize| {
4405 const i = @intCast(c_uint, i_usize);4411 const i = @intCast(c_uint, i_usize);
4406 const field_ptr = self.builder.buildStructGEP(casted_ptr, i, "");4412 const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
4407 const load_inst = self.builder.buildLoad(field_ptr, "");4413 const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");
4408 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);4414 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
4409 llvm_args.appendAssumeCapacity(load_inst);4415 llvm_args.appendAssumeCapacity(load_inst);
4410 }4416 }
...@@ -4418,6 +4424,7 @@ pub const FuncGen = struct {...@@ -4418,6 +4424,7 @@ pub const FuncGen = struct {
4418 };4424 };
44194425
4420 const call = self.builder.buildCall(4426 const call = self.builder.buildCall(
4427 try self.dg.lowerType(zig_fn_ty),
4421 llvm_fn,4428 llvm_fn,
4422 llvm_args.items.ptr,4429 llvm_args.items.ptr,
4423 @intCast(c_uint, llvm_args.items.len),4430 @intCast(c_uint, llvm_args.items.len),
...@@ -4443,7 +4450,7 @@ pub const FuncGen = struct {...@@ -4443,7 +4450,7 @@ pub const FuncGen = struct {
4443 return rp;4450 return rp;
4444 } else {4451 } else {
4445 // our by-ref status disagrees with sret so we must load.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 loaded.setAlignment(return_type.abiAlignment(target));4454 loaded.setAlignment(return_type.abiAlignment(target));
4448 return loaded;4455 return loaded;
4449 }4456 }
...@@ -4465,7 +4472,7 @@ pub const FuncGen = struct {...@@ -4465,7 +4472,7 @@ pub const FuncGen = struct {
4465 if (isByRef(return_type)) {4472 if (isByRef(return_type)) {
4466 return rp;4473 return rp;
4467 } else {4474 } else {
4468 const load_inst = self.builder.buildLoad(rp, "");4475 const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");
4469 load_inst.setAlignment(alignment);4476 load_inst.setAlignment(alignment);
4470 return load_inst;4477 return load_inst;
4471 }4478 }
...@@ -4523,7 +4530,7 @@ pub const FuncGen = struct {...@@ -4523,7 +4530,7 @@ pub const FuncGen = struct {
4523 // operand is a pointer however self.ret_ptr is null so that means4530 // operand is a pointer however self.ret_ptr is null so that means
4524 // we need to return a value.4531 // we need to return a value.
4525 const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");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 load_inst.setAlignment(alignment);4534 load_inst.setAlignment(alignment);
4528 _ = self.builder.buildRet(load_inst);4535 _ = self.builder.buildRet(load_inst);
4529 return null;4536 return null;
...@@ -4540,7 +4547,7 @@ pub const FuncGen = struct {...@@ -4540,7 +4547,7 @@ pub const FuncGen = struct {
4540 const store_inst = self.builder.buildStore(operand, rp);4547 const store_inst = self.builder.buildStore(operand, rp);
4541 store_inst.setAlignment(alignment);4548 store_inst.setAlignment(alignment);
4542 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");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 load_inst.setAlignment(alignment);4551 load_inst.setAlignment(alignment);
4545 _ = self.builder.buildRet(load_inst);4552 _ = self.builder.buildRet(load_inst);
4546 return null;4553 return null;
...@@ -4575,7 +4582,7 @@ pub const FuncGen = struct {...@@ -4575,7 +4582,7 @@ pub const FuncGen = struct {
4575 const ptr_abi_ty = abi_ret_ty.pointerType(0);4582 const ptr_abi_ty = abi_ret_ty.pointerType(0);
4576 break :p self.builder.buildBitCast(ptr, ptr_abi_ty, "");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 loaded.setAlignment(ret_ty.abiAlignment(target));4586 loaded.setAlignment(ret_ty.abiAlignment(target));
4580 _ = self.builder.buildRet(loaded);4587 _ = self.builder.buildRet(loaded);
4581 return null;4588 return null;
...@@ -4615,7 +4622,7 @@ pub const FuncGen = struct {...@@ -4615,7 +4622,7 @@ pub const FuncGen = struct {
4615 const operand = try self.resolveInst(un_op);4622 const operand = try self.resolveInst(un_op);
4616 const llvm_fn = try self.getCmpLtErrorsLenFunction();4623 const llvm_fn = try self.getCmpLtErrorsLenFunction();
4617 const args: [1]*const llvm.Value = .{operand};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 }
46204627
4621 fn cmp(4628 fn cmp(
...@@ -4642,8 +4649,9 @@ pub const FuncGen = struct {...@@ -4642,8 +4649,9 @@ pub const FuncGen = struct {
4642 // We need to emit instructions to check for equality/inequality4649 // We need to emit instructions to check for equality/inequality
4643 // of optionals that are not pointers.4650 // of optionals that are not pointers.
4644 const is_by_ref = isByRef(scalar_ty);4651 const is_by_ref = isByRef(scalar_ty);
4645 const lhs_non_null = self.optIsNonNull(lhs, is_by_ref);4652 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
4646 const rhs_non_null = self.optIsNonNull(rhs, is_by_ref);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 const llvm_i2 = self.context.intType(2);4655 const llvm_i2 = self.context.intType(2);
4648 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");4656 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");
4649 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");4657 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");
...@@ -4666,8 +4674,8 @@ pub const FuncGen = struct {...@@ -4666,8 +4674,8 @@ pub const FuncGen = struct {
4666 _ = self.builder.buildBr(end_block);4674 _ = self.builder.buildBr(end_block);
46674675
4668 self.builder.positionBuilderAtEnd(both_pl_block);4676 self.builder.positionBuilderAtEnd(both_pl_block);
4669 const lhs_payload = self.optPayloadHandle(lhs, scalar_ty);4677 const lhs_payload = self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty);
4670 const rhs_payload = self.optPayloadHandle(rhs, scalar_ty);4678 const rhs_payload = self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty);
4671 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);4679 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);
4672 _ = self.builder.buildBr(end_block);4680 _ = self.builder.buildBr(end_block);
4673 const both_pl_block_end = self.builder.getInsertBlock();4681 const both_pl_block_end = self.builder.getInsertBlock();
...@@ -4832,10 +4840,18 @@ pub const FuncGen = struct {...@@ -4832,10 +4840,18 @@ pub const FuncGen = struct {
4832 return lowerTry(self, err_union_ptr, body, err_union_ty, true, result_ty);4840 return lowerTry(self, err_union_ptr, body, err_union_ty, true, result_ty);
4833 }4841 }
48344842
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 const payload_ty = err_union_ty.errorUnionPayload();4851 const payload_ty = err_union_ty.errorUnionPayload();
4837 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();4852 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
4838 const target = fg.dg.module.getTarget();4853 const target = fg.dg.module.getTarget();
4854 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
48394855
4840 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {4856 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
4841 const is_err = err: {4857 const is_err = err: {
...@@ -4843,14 +4859,17 @@ pub const FuncGen = struct {...@@ -4843,14 +4859,17 @@ pub const FuncGen = struct {
4843 const zero = err_set_ty.constNull();4859 const zero = err_set_ty.constNull();
4844 if (!payload_has_bits) {4860 if (!payload_has_bits) {
4845 // TODO add alignment to this load4861 // 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 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4866 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4848 }4867 }
4849 const err_field_index = errUnionErrorOffset(payload_ty, target);4868 const err_field_index = errUnionErrorOffset(payload_ty, target);
4850 if (operand_is_ptr or isByRef(err_union_ty)) {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 // TODO add alignment to this load4871 // 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 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4873 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4855 }4874 }
4856 const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");4875 const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");
...@@ -4876,13 +4895,13 @@ pub const FuncGen = struct {...@@ -4876,13 +4895,13 @@ pub const FuncGen = struct {
4876 }4895 }
4877 const offset = errUnionPayloadOffset(payload_ty, target);4896 const offset = errUnionPayloadOffset(payload_ty, target);
4878 if (operand_is_ptr or isByRef(payload_ty)) {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 } else if (isByRef(err_union_ty)) {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 if (isByRef(payload_ty)) {4901 if (isByRef(payload_ty)) {
4883 return payload_ptr;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 load_inst.setAlignment(payload_ty.abiAlignment(target));4905 load_inst.setAlignment(payload_ty.abiAlignment(target));
4887 return load_inst;4906 return load_inst;
4888 }4907 }
...@@ -4977,7 +4996,8 @@ pub const FuncGen = struct {...@@ -4977,7 +4996,8 @@ pub const FuncGen = struct {
4977 const indices: [2]*const llvm.Value = .{4996 const indices: [2]*const llvm.Value = .{
4978 llvm_usize.constNull(), llvm_usize.constNull(),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 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");5001 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
4982 return self.builder.buildInsertValue(partial, len, 1, "");5002 return self.builder.buildInsertValue(partial, len, 1, "");
4983 }5003 }
...@@ -5038,7 +5058,7 @@ pub const FuncGen = struct {...@@ -5038,7 +5058,7 @@ pub const FuncGen = struct {
5038 const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);5058 const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
5039 const params = [1]*const llvm.Value{extended};5059 const params = [1]*const llvm.Value{extended};
50405060
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 }
50435063
5044 fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {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,7 +5113,7 @@ pub const FuncGen = struct {
5093 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);5113 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
5094 const params = [1]*const llvm.Value{operand};5114 const params = [1]*const llvm.Value{operand};
50955115
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, "");
50975117
5098 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, "");5118 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, "");
5099 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");5119 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");
...@@ -5113,8 +5133,9 @@ pub const FuncGen = struct {...@@ -5113,8 +5133,9 @@ pub const FuncGen = struct {
51135133
5114 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5134 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5115 const slice_ptr = try self.resolveInst(ty_op.operand);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());
51165137
5117 return self.builder.buildStructGEP(slice_ptr, index, "");5138 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
5118 }5139 }
51195140
5120 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {5141 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -5124,7 +5145,10 @@ pub const FuncGen = struct {...@@ -5124,7 +5145,10 @@ pub const FuncGen = struct {
51245145
5125 const slice = try self.resolveInst(bin_op.lhs);5146 const slice = try self.resolveInst(bin_op.lhs);
5126 const index = try self.resolveInst(bin_op.rhs);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 return self.load(ptr, slice_ty);5152 return self.load(ptr, slice_ty);
5129 }5153 }
51305154
...@@ -5132,10 +5156,14 @@ pub const FuncGen = struct {...@@ -5132,10 +5156,14 @@ pub const FuncGen = struct {
5132 if (self.liveness.isUnused(inst)) return null;5156 if (self.liveness.isUnused(inst)) return null;
5133 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;5157 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
5134 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;5158 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5159 const slice_ty = self.air.typeOf(bin_op.lhs);
51355160
5136 const slice = try self.resolveInst(bin_op.lhs);5161 const slice = try self.resolveInst(bin_op.lhs);
5137 const index = try self.resolveInst(bin_op.rhs);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 }
51405168
5141 fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {5169 fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -5146,13 +5174,14 @@ pub const FuncGen = struct {...@@ -5146,13 +5174,14 @@ pub const FuncGen = struct {
5146 const array_llvm_val = try self.resolveInst(bin_op.lhs);5174 const array_llvm_val = try self.resolveInst(bin_op.lhs);
5147 const rhs = try self.resolveInst(bin_op.rhs);5175 const rhs = try self.resolveInst(bin_op.rhs);
5148 if (isByRef(array_ty)) {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 const elem_ty = array_ty.childType();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 if (isByRef(elem_ty)) {5181 if (isByRef(elem_ty)) {
5153 return elem_ptr;5182 return elem_ptr;
5154 } else {5183 } else {
5155 return self.builder.buildLoad(elem_ptr, "");5184 return self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
5156 }5185 }
5157 }5186 }
51585187
...@@ -5165,15 +5194,16 @@ pub const FuncGen = struct {...@@ -5165,15 +5194,16 @@ pub const FuncGen = struct {
5165 const ptr_ty = self.air.typeOf(bin_op.lhs);5194 const ptr_ty = self.air.typeOf(bin_op.lhs);
5166 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;5195 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
51675196
5197 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
5168 const base_ptr = try self.resolveInst(bin_op.lhs);5198 const base_ptr = try self.resolveInst(bin_op.lhs);
5169 const rhs = try self.resolveInst(bin_op.rhs);5199 const rhs = try self.resolveInst(bin_op.rhs);
5170 const ptr = if (ptr_ty.isSinglePointer()) ptr: {5200 const ptr = if (ptr_ty.isSinglePointer()) ptr: {
5171 // If this is a single-item pointer to an array, we need another index in the GEP.5201 // If this is a single-item pointer to an array, we need another index in the GEP.
5172 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };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 } else ptr: {5204 } else ptr: {
5175 const indices: [1]*const llvm.Value = .{rhs};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 return self.load(ptr, ptr_ty);5208 return self.load(ptr, ptr_ty);
5179 }5209 }
...@@ -5189,13 +5219,14 @@ pub const FuncGen = struct {...@@ -5189,13 +5219,14 @@ pub const FuncGen = struct {
51895219
5190 const base_ptr = try self.resolveInst(bin_op.lhs);5220 const base_ptr = try self.resolveInst(bin_op.lhs);
5191 const rhs = try self.resolveInst(bin_op.rhs);5221 const rhs = try self.resolveInst(bin_op.rhs);
5222 const llvm_elem_ty = try self.dg.lowerType(elem_ty);
5192 if (ptr_ty.isSinglePointer()) {5223 if (ptr_ty.isSinglePointer()) {
5193 // If this is a single-item pointer to an array, we need another index in the GEP.5224 // If this is a single-item pointer to an array, we need another index in the GEP.
5194 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };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 } else {5227 } else {
5197 const indices: [1]*const llvm.Value = .{rhs};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 }
52015232
...@@ -5279,20 +5310,22 @@ pub const FuncGen = struct {...@@ -5279,20 +5310,22 @@ pub const FuncGen = struct {
5279 assert(struct_ty.containerLayout() != .Packed);5310 assert(struct_ty.containerLayout() != .Packed);
5280 var ptr_ty_buf: Type.Payload.Pointer = undefined;5311 var ptr_ty_buf: Type.Payload.Pointer = undefined;
5281 const llvm_field_index = llvmFieldIndex(struct_ty, field_index, target, &ptr_ty_buf).?;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 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);5315 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
5284 return self.load(field_ptr, field_ptr_ty);5316 return self.load(field_ptr, field_ptr_ty);
5285 },5317 },
5286 .Union => {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 const layout = struct_ty.unionGetLayout(target);5320 const layout = struct_ty.unionGetLayout(target);
5289 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);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 const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");5324 const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");
5292 if (isByRef(field_ty)) {5325 if (isByRef(field_ty)) {
5293 return field_ptr;5326 return field_ptr;
5294 } else {5327 } else {
5295 return self.builder.buildLoad(field_ptr, "");5328 return self.builder.buildLoad(llvm_field_ty, field_ptr, "");
5296 }5329 }
5297 },5330 },
5298 else => unreachable,5331 else => unreachable,
...@@ -5605,10 +5638,11 @@ pub const FuncGen = struct {...@@ -5605,10 +5638,11 @@ pub const FuncGen = struct {
5605 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();5638 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
5606 } else {5639 } else {
5607 const alignment = arg_ty.abiAlignment(target);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 load_inst.setAlignment(alignment);5643 load_inst.setAlignment(alignment);
5610 llvm_param_values[llvm_param_i] = load_inst;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 } else {5647 } else {
5614 if (constraintAllowsRegister(constraint)) {5648 if (constraintAllowsRegister(constraint)) {
...@@ -5769,6 +5803,7 @@ pub const FuncGen = struct {...@@ -5769,6 +5803,7 @@ pub const FuncGen = struct {
5769 .False,5803 .False,
5770 );5804 );
5771 const call = self.builder.buildCall(5805 const call = self.builder.buildCall(
5806 asm_fn.typeOf(),
5772 asm_fn,5807 asm_fn,
5773 llvm_param_values.ptr,5808 llvm_param_values.ptr,
5774 @intCast(c_uint, param_count),5809 @intCast(c_uint, param_count),
...@@ -5819,9 +5854,12 @@ pub const FuncGen = struct {...@@ -5819,9 +5854,12 @@ pub const FuncGen = struct {
5819 const operand = try self.resolveInst(un_op);5854 const operand = try self.resolveInst(un_op);
5820 const operand_ty = self.air.typeOf(un_op);5855 const operand_ty = self.air.typeOf(un_op);
5821 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;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 if (optional_ty.optionalReprIsPayload()) {5858 if (optional_ty.optionalReprIsPayload()) {
5823 const optional_llvm_ty = try self.dg.lowerType(optional_ty);5859 const loaded = if (operand_is_ptr)
5824 const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;5860 self.builder.buildLoad(optional_llvm_ty, operand, "")
5861 else
5862 operand;
5825 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");5863 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
5826 }5864 }
58275865
...@@ -5830,13 +5868,16 @@ pub const FuncGen = struct {...@@ -5830,13 +5868,16 @@ pub const FuncGen = struct {
5830 var buf: Type.Payload.ElemType = undefined;5868 var buf: Type.Payload.ElemType = undefined;
5831 const payload_ty = optional_ty.optionalChild(&buf);5869 const payload_ty = optional_ty.optionalChild(&buf);
5832 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {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 const llvm_i8 = self.dg.context.intType(8);5875 const llvm_i8 = self.dg.context.intType(8);
5835 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");5876 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
5836 }5877 }
58375878
5838 const is_by_ref = operand_is_ptr or isByRef(optional_ty);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 if (pred == .EQ) {5881 if (pred == .EQ) {
5841 return self.builder.buildNot(non_null_bit, "");5882 return self.builder.buildNot(non_null_bit, "");
5842 } else {5883 } else {
...@@ -5857,7 +5898,7 @@ pub const FuncGen = struct {...@@ -5857,7 +5898,7 @@ pub const FuncGen = struct {
5857 const operand_ty = self.air.typeOf(un_op);5898 const operand_ty = self.air.typeOf(un_op);
5858 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;5899 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5859 const payload_ty = err_union_ty.errorUnionPayload();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 const zero = err_set_ty.constNull();5902 const zero = err_set_ty.constNull();
58625903
5863 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {5904 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
...@@ -5870,7 +5911,10 @@ pub const FuncGen = struct {...@@ -5870,7 +5911,10 @@ pub const FuncGen = struct {
5870 }5911 }
58715912
5872 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {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 return self.builder.buildICmp(op, loaded, zero, "");5918 return self.builder.buildICmp(op, loaded, zero, "");
5875 }5919 }
58765920
...@@ -5878,8 +5922,9 @@ pub const FuncGen = struct {...@@ -5878,8 +5922,9 @@ pub const FuncGen = struct {
5878 const err_field_index = errUnionErrorOffset(payload_ty, target);5922 const err_field_index = errUnionErrorOffset(payload_ty, target);
58795923
5880 if (operand_is_ptr or isByRef(err_union_ty)) {5924 if (operand_is_ptr or isByRef(err_union_ty)) {
5881 const err_field_ptr = self.builder.buildStructGEP(operand, err_field_index, "");5925 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
5882 const loaded = self.builder.buildLoad(err_field_ptr, "");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 return self.builder.buildICmp(op, loaded, zero, "");5928 return self.builder.buildICmp(op, loaded, zero, "");
5884 }5929 }
58855930
...@@ -5900,7 +5945,7 @@ pub const FuncGen = struct {...@@ -5900,7 +5945,7 @@ pub const FuncGen = struct {
5900 // We have a pointer to a zero-bit value and we need to return5945 // We have a pointer to a zero-bit value and we need to return
5901 // a pointer to a zero-bit value.5946 // a pointer to a zero-bit value.
59025947
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 const res_ptr_ty = try self.dg.lowerType(result_ty);5949 const res_ptr_ty = try self.dg.lowerType(result_ty);
5905 return self.builder.buildBitCast(operand, res_ptr_ty, "");5950 return self.builder.buildBitCast(operand, res_ptr_ty, "");
5906 }5951 }
...@@ -5908,7 +5953,8 @@ pub const FuncGen = struct {...@@ -5908,7 +5953,8 @@ pub const FuncGen = struct {
5908 // The payload and the optional are the same value.5953 // The payload and the optional are the same value.
5909 return operand;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 }
59135959
5914 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {5960 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -5925,7 +5971,7 @@ pub const FuncGen = struct {...@@ -5925,7 +5971,7 @@ pub const FuncGen = struct {
5925 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.5971 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
5926 _ = self.builder.buildStore(non_null_bit, operand);5972 _ = self.builder.buildStore(non_null_bit, operand);
59275973
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 const res_ptr_ty = try self.dg.lowerType(result_ty);5975 const res_ptr_ty = try self.dg.lowerType(result_ty);
5930 return self.builder.buildBitCast(operand, res_ptr_ty, "");5976 return self.builder.buildBitCast(operand, res_ptr_ty, "");
5931 }5977 }
...@@ -5936,7 +5982,8 @@ pub const FuncGen = struct {...@@ -5936,7 +5982,8 @@ pub const FuncGen = struct {
5936 }5982 }
59375983
5938 // First set the non-null bit.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 // TODO set alignment on this store5987 // TODO set alignment on this store
5941 _ = self.builder.buildStore(non_null_bit, non_null_ptr);5988 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
59425989
...@@ -5944,7 +5991,7 @@ pub const FuncGen = struct {...@@ -5944,7 +5991,7 @@ pub const FuncGen = struct {
5944 if (self.liveness.isUnused(inst))5991 if (self.liveness.isUnused(inst))
5945 return null;5992 return null;
59465993
5947 return self.builder.buildStructGEP(operand, 0, "");5994 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
5948 }5995 }
59495996
5950 fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {5997 fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -5961,7 +6008,8 @@ pub const FuncGen = struct {...@@ -5961,7 +6008,8 @@ pub const FuncGen = struct {
5961 return operand;6008 return operand;
5962 }6009 }
59636010
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 }
59666014
5967 fn airErrUnionPayload(6015 fn airErrUnionPayload(
...@@ -5987,14 +6035,15 @@ pub const FuncGen = struct {...@@ -5987,14 +6035,15 @@ pub const FuncGen = struct {
5987 return self.builder.buildBitCast(operand, res_ptr_ty, "");6035 return self.builder.buildBitCast(operand, res_ptr_ty, "");
5988 }6036 }
5989 const offset = errUnionPayloadOffset(payload_ty, target);6037 const offset = errUnionPayloadOffset(payload_ty, target);
6038 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
5990 if (operand_is_ptr or isByRef(payload_ty)) {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 } else if (isByRef(err_union_ty)) {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 if (isByRef(payload_ty)) {6043 if (isByRef(payload_ty)) {
5995 return payload_ptr;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 load_inst.setAlignment(payload_ty.abiAlignment(target));6047 load_inst.setAlignment(payload_ty.abiAlignment(target));
5999 return load_inst;6048 return load_inst;
6000 }6049 }
...@@ -6022,18 +6071,21 @@ pub const FuncGen = struct {...@@ -6022,18 +6071,21 @@ pub const FuncGen = struct {
6022 }6071 }
6023 }6072 }
60246073
6074 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
6075
6025 const payload_ty = err_union_ty.errorUnionPayload();6076 const payload_ty = err_union_ty.errorUnionPayload();
6026 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6077 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6027 if (!operand_is_ptr) return operand;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 }
60306081
6031 const target = self.dg.module.getTarget();6082 const target = self.dg.module.getTarget();
6032 const offset = errUnionErrorOffset(payload_ty, target);6083 const offset = errUnionErrorOffset(payload_ty, target);
60336084
6034 if (operand_is_ptr or isByRef(err_union_ty)) {6085 if (operand_is_ptr or isByRef(err_union_ty)) {
6035 const err_field_ptr = self.builder.buildStructGEP(operand, offset, "");6086 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6036 return self.builder.buildLoad(err_field_ptr, "");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 }
60386090
6039 return self.builder.buildExtractValue(operand, offset, "");6091 return self.builder.buildExtractValue(operand, offset, "");
...@@ -6042,19 +6094,20 @@ pub const FuncGen = struct {...@@ -6042,19 +6094,20 @@ pub const FuncGen = struct {
6042 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {6094 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
6043 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6095 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6044 const operand = try self.resolveInst(ty_op.operand);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();
60466098
6047 const payload_ty = error_union_ty.errorUnionPayload();6099 const payload_ty = err_union_ty.errorUnionPayload();
6048 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });6100 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
6049 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6101 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6050 _ = self.builder.buildStore(non_error_val, operand);6102 _ = self.builder.buildStore(non_error_val, operand);
6051 return operand;6103 return operand;
6052 }6104 }
6053 const target = self.dg.module.getTarget();6105 const target = self.dg.module.getTarget();
6106 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6054 {6107 {
6055 const error_offset = errUnionErrorOffset(payload_ty, target);6108 const error_offset = errUnionErrorOffset(payload_ty, target);
6056 // First set the non-error value.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 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);6111 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
6059 store_inst.setAlignment(Type.anyerror.abiAlignment(target));6112 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
6060 }6113 }
...@@ -6063,7 +6116,7 @@ pub const FuncGen = struct {...@@ -6063,7 +6116,7 @@ pub const FuncGen = struct {
6063 return null;6116 return null;
60646117
6065 const payload_offset = errUnionPayloadOffset(payload_ty, target);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 }
60686121
6069 fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {6122 fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {
...@@ -6093,14 +6146,14 @@ pub const FuncGen = struct {...@@ -6093,14 +6146,14 @@ pub const FuncGen = struct {
6093 const llvm_optional_ty = try self.dg.lowerType(optional_ty);6146 const llvm_optional_ty = try self.dg.lowerType(optional_ty);
6094 if (isByRef(optional_ty)) {6147 if (isByRef(optional_ty)) {
6095 const optional_ptr = self.buildAlloca(llvm_optional_ty);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 var ptr_ty_payload: Type.Payload.ElemType = .{6150 var ptr_ty_payload: Type.Payload.ElemType = .{
6098 .base = .{ .tag = .single_mut_pointer },6151 .base = .{ .tag = .single_mut_pointer },
6099 .data = payload_ty,6152 .data = payload_ty,
6100 };6153 };
6101 const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base);6154 const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base);
6102 self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic);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 _ = self.builder.buildStore(non_null_bit, non_null_ptr);6157 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
6105 return optional_ptr;6158 return optional_ptr;
6106 }6159 }
...@@ -6126,10 +6179,10 @@ pub const FuncGen = struct {...@@ -6126,10 +6179,10 @@ pub const FuncGen = struct {
6126 const error_offset = errUnionErrorOffset(payload_ty, target);6179 const error_offset = errUnionErrorOffset(payload_ty, target);
6127 if (isByRef(inst_ty)) {6180 if (isByRef(inst_ty)) {
6128 const result_ptr = self.buildAlloca(err_un_llvm_ty);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 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);6183 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
6131 store_inst.setAlignment(Type.anyerror.abiAlignment(target));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 var ptr_ty_payload: Type.Payload.ElemType = .{6186 var ptr_ty_payload: Type.Payload.ElemType = .{
6134 .base = .{ .tag = .single_mut_pointer },6187 .base = .{ .tag = .single_mut_pointer },
6135 .data = payload_ty,6188 .data = payload_ty,
...@@ -6160,10 +6213,10 @@ pub const FuncGen = struct {...@@ -6160,10 +6213,10 @@ pub const FuncGen = struct {
6160 const error_offset = errUnionErrorOffset(payload_ty, target);6213 const error_offset = errUnionErrorOffset(payload_ty, target);
6161 if (isByRef(err_un_ty)) {6214 if (isByRef(err_un_ty)) {
6162 const result_ptr = self.buildAlloca(err_un_llvm_ty);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 const store_inst = self.builder.buildStore(operand, err_ptr);6217 const store_inst = self.builder.buildStore(operand, err_ptr);
6165 store_inst.setAlignment(Type.anyerror.abiAlignment(target));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 var ptr_ty_payload: Type.Payload.ElemType = .{6220 var ptr_ty_payload: Type.Payload.ElemType = .{
6168 .base = .{ .tag = .single_mut_pointer },6221 .base = .{ .tag = .single_mut_pointer },
6169 .data = payload_ty,6222 .data = payload_ty,
...@@ -6188,7 +6241,7 @@ pub const FuncGen = struct {...@@ -6188,7 +6241,7 @@ pub const FuncGen = struct {
6188 const llvm_u32 = self.context.intType(32);6241 const llvm_u32 = self.context.intType(32);
6189 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});6242 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});
6190 const args: [1]*const llvm.Value = .{llvm_u32.constInt(index, .False)};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 }
61936246
6194 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {6247 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -6201,7 +6254,7 @@ pub const FuncGen = struct {...@@ -6201,7 +6254,7 @@ pub const FuncGen = struct {
6201 llvm_u32.constInt(index, .False),6254 llvm_u32.constInt(index, .False),
6202 operand,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 }
62066259
6207 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {6260 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -6504,15 +6557,16 @@ pub const FuncGen = struct {...@@ -6504,15 +6557,16 @@ pub const FuncGen = struct {
6504 const base_ptr = try self.resolveInst(bin_op.lhs);6557 const base_ptr = try self.resolveInst(bin_op.lhs);
6505 const offset = try self.resolveInst(bin_op.rhs);6558 const offset = try self.resolveInst(bin_op.rhs);
6506 const ptr_ty = self.air.typeOf(bin_op.lhs);6559 const ptr_ty = self.air.typeOf(bin_op.lhs);
6560 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
6507 if (ptr_ty.ptrSize() == .One) {6561 if (ptr_ty.ptrSize() == .One) {
6508 // It's a pointer to an array, so according to LLVM we need an extra GEP index.6562 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
6509 const indices: [2]*const llvm.Value = .{6563 const indices: [2]*const llvm.Value = .{
6510 self.context.intType(32).constNull(), offset,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 } else {6567 } else {
6514 const indices: [1]*const llvm.Value = .{offset};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 }
65186572
...@@ -6525,15 +6579,16 @@ pub const FuncGen = struct {...@@ -6525,15 +6579,16 @@ pub const FuncGen = struct {
6525 const offset = try self.resolveInst(bin_op.rhs);6579 const offset = try self.resolveInst(bin_op.rhs);
6526 const negative_offset = self.builder.buildNeg(offset, "");6580 const negative_offset = self.builder.buildNeg(offset, "");
6527 const ptr_ty = self.air.typeOf(bin_op.lhs);6581 const ptr_ty = self.air.typeOf(bin_op.lhs);
6582 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
6528 if (ptr_ty.ptrSize() == .One) {6583 if (ptr_ty.ptrSize() == .One) {
6529 // It's a pointer to an array, so according to LLVM we need an extra GEP index.6584 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
6530 const indices: [2]*const llvm.Value = .{6585 const indices: [2]*const llvm.Value = .{
6531 self.context.intType(32).constNull(), negative_offset,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 } else {6589 } else {
6535 const indices: [1]*const llvm.Value = .{negative_offset};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 }
65396594
...@@ -6564,7 +6619,7 @@ pub const FuncGen = struct {...@@ -6564,7 +6619,7 @@ pub const FuncGen = struct {
6564 const tg = self.dg.module.getTarget();6619 const tg = self.dg.module.getTarget();
65656620
6566 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});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, "");
65686623
6569 const result = self.builder.buildExtractValue(result_struct, 0, "");6624 const result = self.builder.buildExtractValue(result_struct, 0, "");
6570 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");6625 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
...@@ -6579,12 +6634,12 @@ pub const FuncGen = struct {...@@ -6579,12 +6634,12 @@ pub const FuncGen = struct {
6579 const result_alignment = dest_ty.abiAlignment(target);6634 const result_alignment = dest_ty.abiAlignment(target);
6580 alloca_inst.setAlignment(result_alignment);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 const store_inst = self.builder.buildStore(result, field_ptr);6638 const store_inst = self.builder.buildStore(result, field_ptr);
6584 store_inst.setAlignment(result_alignment);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 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);6643 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6589 store_inst.setAlignment(1);6644 store_inst.setAlignment(1);
6590 }6645 }
...@@ -6616,7 +6671,7 @@ pub const FuncGen = struct {...@@ -6616,7 +6671,7 @@ pub const FuncGen = struct {
6616 for (args_vectors) |arg_vector, k| {6671 for (args_vectors) |arg_vector, k| {
6617 args[k] = self.builder.buildExtractElement(arg_vector, index_i32, "");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 result = self.builder.buildInsertElement(result, result_elem, index_i32, "");6675 result = self.builder.buildInsertElement(result, result_elem, index_i32, "");
6621 }6676 }
6622 return result;6677 return result;
...@@ -6743,7 +6798,7 @@ pub const FuncGen = struct {...@@ -6743,7 +6798,7 @@ pub const FuncGen = struct {
6743 return self.builder.buildICmp(int_pred, result, zero_vector, "");6798 return self.builder.buildICmp(int_pred, result, zero_vector, "");
6744 }6799 }
67456800
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 return self.builder.buildICmp(int_pred, result, zero, "");6802 return self.builder.buildICmp(int_pred, result, zero, "");
6748 }6803 }
67496804
...@@ -6871,7 +6926,7 @@ pub const FuncGen = struct {...@@ -6871,7 +6926,7 @@ pub const FuncGen = struct {
6871 break :b libc_fn;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 }
68766931
6877 fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {6932 fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -6931,12 +6986,12 @@ pub const FuncGen = struct {...@@ -6931,12 +6986,12 @@ pub const FuncGen = struct {
6931 const result_alignment = dest_ty.abiAlignment(target);6986 const result_alignment = dest_ty.abiAlignment(target);
6932 alloca_inst.setAlignment(result_alignment);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 const store_inst = self.builder.buildStore(result, field_ptr);6990 const store_inst = self.builder.buildStore(result, field_ptr);
6936 store_inst.setAlignment(result_alignment);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 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);6995 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6941 store_inst.setAlignment(1);6996 store_inst.setAlignment(1);
6942 }6997 }
...@@ -7226,7 +7281,7 @@ pub const FuncGen = struct {...@@ -7226,7 +7281,7 @@ pub const FuncGen = struct {
7226 const index_usize = llvm_usize.constInt(i, .False);7281 const index_usize = llvm_usize.constInt(i, .False);
7227 const index_u32 = llvm_u32.constInt(i, .False);7282 const index_u32 = llvm_u32.constInt(i, .False);
7228 const indexes: [2]*const llvm.Value = .{ zero, index_usize };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 const elem = self.builder.buildExtractElement(operand, index_u32, "");7285 const elem = self.builder.buildExtractElement(operand, index_u32, "");
7231 _ = self.builder.buildStore(elem, elem_ptr);7286 _ = self.builder.buildStore(elem, elem_ptr);
7232 }7287 }
...@@ -7243,7 +7298,7 @@ pub const FuncGen = struct {...@@ -7243,7 +7298,7 @@ pub const FuncGen = struct {
7243 if (bitcast_ok) {7298 if (bitcast_ok) {
7244 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);7299 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);
7245 const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, "");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 // The array is aligned to the element's alignment, while the vector might have a completely7302 // The array is aligned to the element's alignment, while the vector might have a completely
7248 // different alignment. This means we need to enforce the alignment of this load.7303 // different alignment. This means we need to enforce the alignment of this load.
7249 vector.setAlignment(elem_ty.abiAlignment(target));7304 vector.setAlignment(elem_ty.abiAlignment(target));
...@@ -7251,6 +7306,7 @@ pub const FuncGen = struct {...@@ -7251,6 +7306,7 @@ pub const FuncGen = struct {
7251 } else {7306 } else {
7252 // If the ABI size of the element type is not evenly divisible by size in bits;7307 // If the ABI size of the element type is not evenly divisible by size in bits;
7253 // a simple bitcast will not work, and we fall back to extractelement.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 const llvm_usize = try self.dg.lowerType(Type.usize);7310 const llvm_usize = try self.dg.lowerType(Type.usize);
7255 const llvm_u32 = self.context.intType(32);7311 const llvm_u32 = self.context.intType(32);
7256 const zero = llvm_usize.constNull();7312 const zero = llvm_usize.constNull();
...@@ -7261,8 +7317,8 @@ pub const FuncGen = struct {...@@ -7261,8 +7317,8 @@ pub const FuncGen = struct {
7261 const index_usize = llvm_usize.constInt(i, .False);7317 const index_usize = llvm_usize.constInt(i, .False);
7262 const index_u32 = llvm_u32.constInt(i, .False);7318 const index_u32 = llvm_u32.constInt(i, .False);
7263 const indexes: [2]*const llvm.Value = .{ zero, index_usize };7319 const indexes: [2]*const llvm.Value = .{ zero, index_usize };
7264 const elem_ptr = self.builder.buildInBoundsGEP(operand, &indexes, indexes.len, "");7320 const elem_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, operand, &indexes, indexes.len, "");
7265 const elem = self.builder.buildLoad(elem_ptr, "");7321 const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
7266 vector = self.builder.buildInsertElement(vector, elem, index_u32, "");7322 vector = self.builder.buildInsertElement(vector, elem, index_u32, "");
7267 }7323 }
72687324
...@@ -7273,7 +7329,7 @@ pub const FuncGen = struct {...@@ -7273,7 +7329,7 @@ pub const FuncGen = struct {
7273 if (operand_is_ref) {7329 if (operand_is_ref) {
7274 // Bitcast the operand pointer, then load.7330 // Bitcast the operand pointer, then load.
7275 const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");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 load_inst.setAlignment(operand_ty.abiAlignment(target));7333 load_inst.setAlignment(operand_ty.abiAlignment(target));
7278 return load_inst;7334 return load_inst;
7279 }7335 }
...@@ -7301,7 +7357,7 @@ pub const FuncGen = struct {...@@ -7301,7 +7357,7 @@ pub const FuncGen = struct {
7301 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");7357 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
7302 const store_inst = self.builder.buildStore(operand, casted_ptr);7358 const store_inst = self.builder.buildStore(operand, casted_ptr);
7303 store_inst.setAlignment(alignment);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 load_inst.setAlignment(alignment);7361 load_inst.setAlignment(alignment);
7306 return load_inst;7362 return load_inst;
7307 }7363 }
...@@ -7481,7 +7537,7 @@ pub const FuncGen = struct {...@@ -7481,7 +7537,7 @@ pub const FuncGen = struct {
7481 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {7537 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
7482 _ = inst;7538 _ = inst;
7483 const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{});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 return null;7541 return null;
7486 }7542 }
74877543
...@@ -7498,7 +7554,7 @@ pub const FuncGen = struct {...@@ -7498,7 +7554,7 @@ pub const FuncGen = struct {
7498 const llvm_i32 = self.context.intType(32);7554 const llvm_i32 = self.context.intType(32);
7499 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});7555 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
7500 const params = [_]*const llvm.Value{llvm_i32.constNull()};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 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");7558 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
7503 }7559 }
75047560
...@@ -7515,7 +7571,7 @@ pub const FuncGen = struct {...@@ -7515,7 +7571,7 @@ pub const FuncGen = struct {
7515 };7571 };
75167572
7517 const params = [_]*const llvm.Value{llvm_i32.constNull()};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 const llvm_usize = try self.dg.lowerType(Type.usize);7575 const llvm_usize = try self.dg.lowerType(Type.usize);
7520 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");7576 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
7521 }7577 }
...@@ -7740,8 +7796,9 @@ pub const FuncGen = struct {...@@ -7740,8 +7796,9 @@ pub const FuncGen = struct {
7740 _ = self.builder.buildStore(new_tag, union_ptr);7796 _ = self.builder.buildStore(new_tag, union_ptr);
7741 return null;7797 return null;
7742 }7798 }
7799 const un_llvm_ty = try self.dg.lowerType(un_ty);
7743 const tag_index = @boolToInt(layout.tag_align < layout.payload_align);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 // TODO alignment on this store7802 // TODO alignment on this store
7746 _ = self.builder.buildStore(new_tag, tag_field_ptr);7803 _ = self.builder.buildStore(new_tag, tag_field_ptr);
7747 return null;7804 return null;
...@@ -7757,12 +7814,13 @@ pub const FuncGen = struct {...@@ -7757,12 +7814,13 @@ pub const FuncGen = struct {
7757 if (layout.tag_size == 0) return null;7814 if (layout.tag_size == 0) return null;
7758 const union_handle = try self.resolveInst(ty_op.operand);7815 const union_handle = try self.resolveInst(ty_op.operand);
7759 if (isByRef(un_ty)) {7816 if (isByRef(un_ty)) {
7817 const llvm_un_ty = try self.dg.lowerType(un_ty);
7760 if (layout.payload_size == 0) {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 const tag_index = @boolToInt(layout.tag_align < layout.payload_align);7821 const tag_index = @boolToInt(layout.tag_align < layout.payload_align);
7764 const tag_field_ptr = self.builder.buildStructGEP(union_handle, tag_index, "");7822 const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, "");
7765 return self.builder.buildLoad(tag_field_ptr, "");7823 return self.builder.buildLoad(tag_field_ptr.getGEPSourceElementType(), tag_field_ptr, "");
7766 } else {7824 } else {
7767 if (layout.payload_size == 0) {7825 if (layout.payload_size == 0) {
7768 return union_handle;7826 return union_handle;
...@@ -7805,7 +7863,7 @@ pub const FuncGen = struct {...@@ -7805,7 +7863,7 @@ pub const FuncGen = struct {
7805 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});7863 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
78067864
7807 const params = [_]*const llvm.Value{ operand, llvm_i1.constNull() };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 const result_ty = self.air.typeOfIndex(inst);7867 const result_ty = self.air.typeOfIndex(inst);
7810 const result_llvm_ty = try self.dg.lowerType(result_ty);7868 const result_llvm_ty = try self.dg.lowerType(result_ty);
78117869
...@@ -7832,7 +7890,7 @@ pub const FuncGen = struct {...@@ -7832,7 +7890,7 @@ pub const FuncGen = struct {
7832 const operand_llvm_ty = try self.dg.lowerType(operand_ty);7890 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
7833 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});7891 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
78347892
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 const result_ty = self.air.typeOfIndex(inst);7894 const result_ty = self.air.typeOfIndex(inst);
7837 const result_llvm_ty = try self.dg.lowerType(result_ty);7895 const result_llvm_ty = try self.dg.lowerType(result_ty);
78387896
...@@ -7889,7 +7947,7 @@ pub const FuncGen = struct {...@@ -7889,7 +7947,7 @@ pub const FuncGen = struct {
7889 const params = [_]*const llvm.Value{operand};7947 const params = [_]*const llvm.Value{operand};
7890 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});7948 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
78917949
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, "");
78937951
7894 const result_ty = self.air.typeOfIndex(inst);7952 const result_ty = self.air.typeOfIndex(inst);
7895 const result_llvm_ty = try self.dg.lowerType(result_ty);7953 const result_llvm_ty = try self.dg.lowerType(result_ty);
...@@ -7912,7 +7970,7 @@ pub const FuncGen = struct {...@@ -7912,7 +7970,7 @@ pub const FuncGen = struct {
79127970
7913 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);7971 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
7914 const params = [_]*const llvm.Value{operand};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 }
79177975
7918 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value {7976 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value {
...@@ -7973,7 +8031,8 @@ pub const FuncGen = struct {...@@ -7973,7 +8031,8 @@ pub const FuncGen = struct {
79738031
7974 for (fields.keys()) |name, field_index| {8032 for (fields.keys()) |name, field_index| {
7975 const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False);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 str_global.setInitializer(str_init);8036 str_global.setInitializer(str_init);
7978 str_global.setLinkage(.Private);8037 str_global.setLinkage(.Private);
7979 str_global.setGlobalConstant(.True);8038 str_global.setGlobalConstant(.True);
...@@ -7981,7 +8040,7 @@ pub const FuncGen = struct {...@@ -7981,7 +8040,7 @@ pub const FuncGen = struct {
7981 str_global.setAlignment(1);8040 str_global.setAlignment(1);
79828041
7983 const slice_fields = [_]*const llvm.Value{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 usize_llvm_ty.constInt(name.len, .False),8044 usize_llvm_ty.constInt(name.len, .False),
7986 };8045 };
7987 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);8046 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);
...@@ -8006,7 +8065,7 @@ pub const FuncGen = struct {...@@ -8006,7 +8065,7 @@ pub const FuncGen = struct {
8006 switch_instr.addCase(this_tag_int_value, return_block);8065 switch_instr.addCase(this_tag_int_value, return_block);
80078066
8008 self.builder.positionBuilderAtEnd(return_block);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 loaded.setAlignment(slice_alignment);8069 loaded.setAlignment(slice_alignment);
8011 _ = self.builder.buildRet(loaded);8070 _ = self.builder.buildRet(loaded);
8012 }8071 }
...@@ -8040,12 +8099,15 @@ pub const FuncGen = struct {...@@ -8040,12 +8099,15 @@ pub const FuncGen = struct {
80408099
8041 const un_op = self.air.instructions.items(.data)[inst].un_op;8100 const un_op = self.air.instructions.items(.data)[inst].un_op;
8042 const operand = try self.resolveInst(un_op);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);
80438104
8044 const error_name_table_ptr = try self.getErrorNameTable();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 const indices = [_]*const llvm.Value{operand};8108 const indices = [_]*const llvm.Value{operand};
8047 const error_name_ptr = self.builder.buildInBoundsGEP(error_name_table, &indices, indices.len, "");8109 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
8048 return self.builder.buildLoad(error_name_ptr, "");8110 return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, "");
8049 }8111 }
80508112
8051 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {8113 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
...@@ -8222,7 +8284,7 @@ pub const FuncGen = struct {...@@ -8222,7 +8284,7 @@ pub const FuncGen = struct {
8222 const llvm_elem = try self.resolveInst(elem);8284 const llvm_elem = try self.resolveInst(elem);
8223 const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;8285 const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;
8224 indices[1] = llvm_u32.constInt(llvm_i, .False);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 var field_ptr_payload: Type.Payload.Pointer = .{8288 var field_ptr_payload: Type.Payload.Pointer = .{
8227 .data = .{8289 .data = .{
8228 .pointee_type = self.air.typeOf(elem),8290 .pointee_type = self.air.typeOf(elem),
...@@ -8268,7 +8330,7 @@ pub const FuncGen = struct {...@@ -8268,7 +8330,7 @@ pub const FuncGen = struct {
8268 llvm_usize.constNull(),8330 llvm_usize.constNull(),
8269 llvm_usize.constInt(@intCast(c_uint, i), .False),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 const llvm_elem = try self.resolveInst(elem);8334 const llvm_elem = try self.resolveInst(elem);
8273 self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);8335 self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);
8274 }8336 }
...@@ -8277,7 +8339,7 @@ pub const FuncGen = struct {...@@ -8277,7 +8339,7 @@ pub const FuncGen = struct {
8277 llvm_usize.constNull(),8339 llvm_usize.constNull(),
8278 llvm_usize.constInt(@intCast(c_uint, array_info.len), .False),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 const llvm_elem = try self.dg.lowerValue(.{8343 const llvm_elem = try self.dg.lowerValue(.{
8282 .ty = array_info.elem_type,8344 .ty = array_info.elem_type,
8283 .val = sent_val,8345 .val = sent_val,
...@@ -8377,7 +8439,7 @@ pub const FuncGen = struct {...@@ -8377,7 +8439,7 @@ pub const FuncGen = struct {
8377 index_type.constNull(),8439 index_type.constNull(),
8378 };8440 };
8379 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;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 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);8443 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
8382 return result_ptr;8444 return result_ptr;
8383 }8445 }
...@@ -8389,7 +8451,7 @@ pub const FuncGen = struct {...@@ -8389,7 +8451,7 @@ pub const FuncGen = struct {
8389 index_type.constNull(),8451 index_type.constNull(),
8390 };8452 };
8391 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;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 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);8455 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
8394 }8456 }
8395 {8457 {
...@@ -8397,7 +8459,7 @@ pub const FuncGen = struct {...@@ -8397,7 +8459,7 @@ pub const FuncGen = struct {
8397 index_type.constNull(),8459 index_type.constNull(),
8398 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),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 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);8463 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
8402 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);8464 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);
8403 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);8465 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
...@@ -8464,7 +8526,7 @@ pub const FuncGen = struct {...@@ -8464,7 +8526,7 @@ pub const FuncGen = struct {
8464 llvm_u32.constInt(prefetch.locality, .False),8526 llvm_u32.constInt(prefetch.locality, .False),
8465 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),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 return null;8530 return null;
8469 }8531 }
84708532
...@@ -8544,7 +8606,7 @@ pub const FuncGen = struct {...@@ -8544,7 +8606,7 @@ pub const FuncGen = struct {
8544 };8606 };
85458607
8546 var args: [1]*const llvm.Value = .{arg};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 const final_cast_llvm_ty = final_cast orelse return result;8610 const final_cast_llvm_ty = final_cast orelse return result;
8549 return self.builder.buildBitCast(result, final_cast_llvm_ty, "");8611 return self.builder.buildBitCast(result, final_cast_llvm_ty, "");
8550 }8612 }
...@@ -8571,22 +8633,29 @@ pub const FuncGen = struct {...@@ -8571,22 +8633,29 @@ pub const FuncGen = struct {
8571 }8633 }
85728634
8573 /// Assumes the optional is not pointer-like and payload has bits.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 const field = b: {8643 const field = b: {
8576 if (is_by_ref) {8644 if (is_by_ref) {
8577 const field_ptr = self.builder.buildStructGEP(opt_handle, 1, "");8645 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
8578 break :b self.builder.buildLoad(field_ptr, "");8646 break :b self.builder.buildLoad(non_null_llvm_ty, field_ptr, "");
8579 }8647 }
8580 break :b self.builder.buildExtractValue(opt_handle, 1, "");8648 break :b self.builder.buildExtractValue(opt_handle, 1, "");
8581 };8649 };
8582 comptime assert(optional_layout_version == 3);8650 comptime assert(optional_layout_version == 3);
85838651
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 }
85868654
8587 /// Assumes the optional is not pointer-like and payload has bits.8655 /// Assumes the optional is not pointer-like and payload has bits.
8588 fn optPayloadHandle(8656 fn optPayloadHandle(
8589 fg: *FuncGen,8657 fg: *FuncGen,
8658 opt_llvm_ty: *const llvm.Type,
8590 opt_handle: *const llvm.Value,8659 opt_handle: *const llvm.Value,
8591 opt_ty: Type,8660 opt_ty: Type,
8592 ) *const llvm.Value {8661 ) *const llvm.Value {
...@@ -8595,14 +8664,14 @@ pub const FuncGen = struct {...@@ -8595,14 +8664,14 @@ pub const FuncGen = struct {
85958664
8596 if (isByRef(opt_ty)) {8665 if (isByRef(opt_ty)) {
8597 // We have a pointer and we need to return a pointer to the first field.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, "");
85998668
8600 if (isByRef(payload_ty)) {8669 if (isByRef(payload_ty)) {
8601 return payload_ptr;8670 return payload_ptr;
8602 }8671 }
8603 const target = fg.dg.module.getTarget();8672 const target = fg.dg.module.getTarget();
8604 const payload_alignment = payload_ty.abiAlignment(target);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 load_inst.setAlignment(payload_alignment);8675 load_inst.setAlignment(payload_alignment);
8607 return load_inst;8676 return load_inst;
8608 }8677 }
...@@ -8627,12 +8696,12 @@ pub const FuncGen = struct {...@@ -8627,12 +8696,12 @@ pub const FuncGen = struct {
8627 alloca_inst.setAlignment(payload_alignment);8696 alloca_inst.setAlignment(payload_alignment);
86288697
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 const store_inst = self.builder.buildStore(payload, field_ptr);8700 const store_inst = self.builder.buildStore(payload, field_ptr);
8632 store_inst.setAlignment(payload_alignment);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 const store_inst = self.builder.buildStore(non_null_field, field_ptr);8705 const store_inst = self.builder.buildStore(non_null_field, field_ptr);
8637 store_inst.setAlignment(1);8706 store_inst.setAlignment(1);
8638 }8707 }
...@@ -8678,18 +8747,20 @@ pub const FuncGen = struct {...@@ -8678,18 +8747,20 @@ pub const FuncGen = struct {
8678 if (byte_offset == 0) {8747 if (byte_offset == 0) {
8679 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");8748 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
8680 }8749 }
8681 const llvm_bytes_ptr_ty = self.context.intType(8).pointerType(0);8750 const byte_llvm_ty = self.context.intType(8);
8682 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, llvm_bytes_ptr_ty, "");8751 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
8683 const llvm_usize = try self.dg.lowerType(Type.usize);8752 const llvm_usize = try self.dg.lowerType(Type.usize);
8684 const llvm_index = llvm_usize.constInt(byte_offset, .False);8753 const llvm_index = llvm_usize.constInt(byte_offset, .False);
8685 const indices: [1]*const llvm.Value = .{llvm_index};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 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");8756 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
8688 },8757 },
8689 else => {8758 else => {
8759 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
8760
8690 var ty_buf: Type.Payload.Pointer = undefined;8761 var ty_buf: Type.Payload.Pointer = undefined;
8691 if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| {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 } else {8764 } else {
8694 // If we found no index then this means this is a zero sized field at the8765 // If we found no index then this means this is a zero sized field at the
8695 // end of the struct. Treat our struct pointer as an array of two and get8766 // end of the struct. Treat our struct pointer as an array of two and get
...@@ -8698,7 +8769,7 @@ pub const FuncGen = struct {...@@ -8698,7 +8769,7 @@ pub const FuncGen = struct {
8698 const llvm_usize = try self.dg.lowerType(Type.usize);8769 const llvm_usize = try self.dg.lowerType(Type.usize);
8699 const llvm_index = llvm_usize.constInt(1, .False);8770 const llvm_index = llvm_usize.constInt(1, .False);
8700 const indices: [1]*const llvm.Value = .{llvm_index};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,27 +8787,18 @@ pub const FuncGen = struct {
8716 ) !?*const llvm.Value {8787 ) !?*const llvm.Value {
8717 const union_obj = union_ty.cast(Type.Payload.Union).?.data;8788 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
8718 const field = &union_obj.fields.values()[field_index];8789 const field = &union_obj.fields.values()[field_index];
8719 const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
8720 if (!field.ty.hasRuntimeBitsIgnoreComptime()) {8790 if (!field.ty.hasRuntimeBitsIgnoreComptime()) {
8721 return null;8791 return null;
8722 }8792 }
8723 const target = self.dg.module.getTarget();8793 const target = self.dg.module.getTarget();
8724 const layout = union_ty.unionGetLayout(target);8794 const layout = union_ty.unionGetLayout(target);
8725 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);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 return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");8799 return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
8728 }8800 }
87298801
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 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value {8802 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value {
8741 const id = llvm.lookupIntrinsicID(name.ptr, name.len);8803 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
8742 assert(id != 0);8804 assert(id != 0);
...@@ -8754,8 +8816,8 @@ pub const FuncGen = struct {...@@ -8754,8 +8816,8 @@ pub const FuncGen = struct {
8754 const ptr_alignment = ptr_ty.ptrAlignment(target);8816 const ptr_alignment = ptr_ty.ptrAlignment(target);
8755 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());8817 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
8756 if (info.host_size == 0) {8818 if (info.host_size == 0) {
8819 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
8757 if (isByRef(info.pointee_type)) {8820 if (isByRef(info.pointee_type)) {
8758 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
8759 const result_align = info.pointee_type.abiAlignment(target);8821 const result_align = info.pointee_type.abiAlignment(target);
8760 const max_align = @maximum(result_align, ptr_alignment);8822 const max_align = @maximum(result_align, ptr_alignment);
8761 const result_ptr = self.buildAlloca(elem_llvm_ty);8823 const result_ptr = self.buildAlloca(elem_llvm_ty);
...@@ -8773,15 +8835,15 @@ pub const FuncGen = struct {...@@ -8773,15 +8835,15 @@ pub const FuncGen = struct {
8773 );8835 );
8774 return result_ptr;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 llvm_inst.setAlignment(ptr_alignment);8839 llvm_inst.setAlignment(ptr_alignment);
8778 llvm_inst.setVolatile(ptr_volatile);8840 llvm_inst.setVolatile(ptr_volatile);
8779 return llvm_inst;8841 return llvm_inst;
8780 }8842 }
87818843
8782 const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);8844 const int_elem_ty = self.context.intType(info.host_size * 8);
8783 const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");8845 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
8784 const containing_int = self.builder.buildLoad(int_ptr, "");8846 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
8785 containing_int.setAlignment(ptr_alignment);8847 containing_int.setAlignment(ptr_alignment);
8786 containing_int.setVolatile(ptr_volatile);8848 containing_int.setVolatile(ptr_volatile);
87878849
...@@ -8828,9 +8890,9 @@ pub const FuncGen = struct {...@@ -8828,9 +8890,9 @@ pub const FuncGen = struct {
8828 const ptr_alignment = ptr_ty.ptrAlignment(target);8890 const ptr_alignment = ptr_ty.ptrAlignment(target);
8829 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");8891 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");
8830 if (info.host_size != 0) {8892 if (info.host_size != 0) {
8831 const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);8893 const int_elem_ty = self.context.intType(info.host_size * 8);
8832 const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");8894 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
8833 const containing_int = self.builder.buildLoad(int_ptr, "");8895 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
8834 assert(ordering == .NotAtomic);8896 assert(ordering == .NotAtomic);
8835 containing_int.setAlignment(ptr_alignment);8897 containing_int.setAlignment(ptr_alignment);
8836 containing_int.setVolatile(ptr_volatile);8898 containing_int.setVolatile(ptr_volatile);
src/codegen/llvm/bindings.zig+14-8
...@@ -141,14 +141,6 @@ pub const Value = opaque {...@@ -141,14 +141,6 @@ pub const Value = opaque {
141 pub const setAliasee = LLVMAliasSetAliasee;141 pub const setAliasee = LLVMAliasSetAliasee;
142 extern fn LLVMAliasSetAliasee(Alias: *const Value, Aliasee: *const Value) void;142 extern fn LLVMAliasSetAliasee(Alias: *const Value, Aliasee: *const Value) void;
143143
144 pub const constInBoundsGEP = LLVMConstInBoundsGEP2;
145 extern fn LLVMConstInBoundsGEP2(
146 Ty: *const Type,
147 ConstantVal: *const Value,
148 ConstantIndices: [*]const *const Value,
149 NumIndices: c_uint,
150 ) *const Value;
151
152 pub const constBitCast = LLVMConstBitCast;144 pub const constBitCast = LLVMConstBitCast;
153 extern fn LLVMConstBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value;145 extern fn LLVMConstBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value;
154146
...@@ -249,6 +241,9 @@ pub const Value = opaque {...@@ -249,6 +241,9 @@ pub const Value = opaque {
249241
250 pub const addFunctionAttr = ZigLLVMAddFunctionAttr;242 pub const addFunctionAttr = ZigLLVMAddFunctionAttr;
251 extern fn ZigLLVMAddFunctionAttr(Fn: *const Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void;243 extern fn ZigLLVMAddFunctionAttr(Fn: *const Value, attr_name: [*:0]const u8, attr_value: [*:0]const u8) void;
244
245 pub const getGEPSourceElementType = LLVMGetGEPSourceElementType;
246 extern fn LLVMGetGEPSourceElementType(GEP: *const Value) *const Type;
252};247};
253248
254pub const Type = opaque {249pub const Type = opaque {
...@@ -280,6 +275,9 @@ pub const Type = opaque {...@@ -280,6 +275,9 @@ pub const Type = opaque {
280 pub const getUndef = LLVMGetUndef;275 pub const getUndef = LLVMGetUndef;
281 extern fn LLVMGetUndef(Ty: *const Type) *const Value;276 extern fn LLVMGetUndef(Ty: *const Type) *const Value;
282277
278 pub const pointerType = LLVMPointerType;
279 extern fn LLVMPointerType(ElementType: *const Type, AddressSpace: c_uint) *const Type;
280
283 pub const arrayType = LLVMArrayType;281 pub const arrayType = LLVMArrayType;
284 extern fn LLVMArrayType(ElementType: *const Type, ElementCount: c_uint) *const Type;282 extern fn LLVMArrayType(ElementType: *const Type, ElementCount: c_uint) *const Type;
285283
...@@ -311,6 +309,14 @@ pub const Type = opaque {...@@ -311,6 +309,14 @@ pub const Type = opaque {
311309
312 pub const isSized = LLVMTypeIsSized;310 pub const isSized = LLVMTypeIsSized;
313 extern fn LLVMTypeIsSized(Ty: *const Type) Bool;311 extern fn LLVMTypeIsSized(Ty: *const Type) Bool;
312
313 pub const constInBoundsGEP = LLVMConstInBoundsGEP2;
314 extern fn LLVMConstInBoundsGEP2(
315 Ty: *const Type,
316 ConstantVal: *const Value,
317 ConstantIndices: [*]const *const Value,
318 NumIndices: c_uint,
319 ) *const Value;
314};320};
315321
316pub const Module = opaque {322pub const Module = opaque {