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 {
841841 args.appendAssumeCapacity(param);
842842 } else {
843843 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, "");
845846 load_inst.setAlignment(alignment);
846847 args.appendAssumeCapacity(load_inst);
847848 }
......@@ -870,7 +871,7 @@ pub const Object = struct {
870871 if (isByRef(param_ty)) {
871872 args.appendAssumeCapacity(arg_ptr);
872873 } else {
873 const load_inst = builder.buildLoad(arg_ptr, "");
874 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
874875 load_inst.setAlignment(alignment);
875876 args.appendAssumeCapacity(load_inst);
876877 }
......@@ -921,14 +922,14 @@ pub const Object = struct {
921922 for (llvm_ints) |_, i_usize| {
922923 const i = @intCast(c_uint, i_usize);
923924 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, "");
925926 const store_inst = builder.buildStore(param, field_ptr);
926927 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
927928 }
928929
929930 const is_by_ref = isByRef(param_ty);
930931 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, "");
932933 load_inst.setAlignment(param_alignment);
933934 break :l load_inst;
934935 };
......@@ -3663,7 +3664,8 @@ pub const DeclGen = struct {
36633664 llvm_u32.constInt(0, .False),
36643665 llvm_u32.constInt(llvm_pl_index, .False),
36653666 };
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);
36673669 },
36683670 .Struct => {
36693671 const field_ty = parent_ty.structFieldType(field_index);
......@@ -3693,7 +3695,8 @@ pub const DeclGen = struct {
36933695 llvm_u32.constInt(0, .False),
36943696 llvm_u32.constInt(llvm_field_index, .False),
36953697 };
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);
36973700 },
36983701 else => unreachable,
36993702 }
......@@ -3707,7 +3710,8 @@ pub const DeclGen = struct {
37073710 const indices: [1]*const llvm.Value = .{
37083711 llvm_usize.constInt(elem_ptr.index, .False),
37093712 };
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);
37113715 },
37123716 .opt_payload_ptr => blk: {
37133717 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
......@@ -3730,7 +3734,8 @@ pub const DeclGen = struct {
37303734 llvm_u32.constInt(0, .False),
37313735 llvm_u32.constInt(0, .False),
37323736 };
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);
37343739 },
37353740 .eu_payload_ptr => blk: {
37363741 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
......@@ -3751,7 +3756,8 @@ pub const DeclGen = struct {
37513756 llvm_u32.constInt(0, .False),
37523757 llvm_u32.constInt(payload_offset, .False),
37533758 };
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);
37553761 },
37563762 else => unreachable,
37573763 };
......@@ -4303,9 +4309,10 @@ pub const FuncGen = struct {
43034309 const arg = args[it.zig_index - 1];
43044310 const param_ty = self.air.typeOf(arg);
43054311 const llvm_arg = try self.resolveInst(arg);
4312 const llvm_param_ty = try self.dg.lowerType(param_ty);
43064313 if (isByRef(param_ty)) {
43074314 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, "");
43094316 load_inst.setAlignment(alignment);
43104317 try llvm_args.append(load_inst);
43114318 } else {
......@@ -4315,7 +4322,6 @@ pub const FuncGen = struct {
43154322 // which is always lowered to an LLVM type of `*i8`.
43164323 // 2. The argument is a global which does act as a pointer, however
43174324 // a bitcast is needed in order for the LLVM types to match.
4318 const llvm_param_ty = try self.dg.lowerType(param_ty);
43194325 const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, "");
43204326 try llvm_args.append(casted_ptr);
43214327 } else {
......@@ -4350,7 +4356,7 @@ pub const FuncGen = struct {
43504356 if (isByRef(param_ty)) {
43514357 const alignment = param_ty.abiAlignment(target);
43524358 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, "");
43544360 load_inst.setAlignment(alignment);
43554361 try llvm_args.append(load_inst);
43564362 } else {
......@@ -4366,7 +4372,7 @@ pub const FuncGen = struct {
43664372 const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), "");
43674373 const store_inst = self.builder.buildStore(llvm_arg, casted_ptr);
43684374 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, "");
43704376 load_inst.setAlignment(alignment);
43714377 try llvm_args.append(load_inst);
43724378 }
......@@ -4403,8 +4409,8 @@ pub const FuncGen = struct {
44034409 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
44044410 for (llvm_ints) |_, i_usize| {
44054411 const i = @intCast(c_uint, i_usize);
4406 const field_ptr = self.builder.buildStructGEP(casted_ptr, i, "");
4407 const load_inst = self.builder.buildLoad(field_ptr, "");
4412 const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");
4413 const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");
44084414 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
44094415 llvm_args.appendAssumeCapacity(load_inst);
44104416 }
......@@ -4418,6 +4424,7 @@ pub const FuncGen = struct {
44184424 };
44194425
44204426 const call = self.builder.buildCall(
4427 try self.dg.lowerType(zig_fn_ty),
44214428 llvm_fn,
44224429 llvm_args.items.ptr,
44234430 @intCast(c_uint, llvm_args.items.len),
......@@ -4443,7 +4450,7 @@ pub const FuncGen = struct {
44434450 return rp;
44444451 } else {
44454452 // 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, "");
44474454 loaded.setAlignment(return_type.abiAlignment(target));
44484455 return loaded;
44494456 }
......@@ -4465,7 +4472,7 @@ pub const FuncGen = struct {
44654472 if (isByRef(return_type)) {
44664473 return rp;
44674474 } else {
4468 const load_inst = self.builder.buildLoad(rp, "");
4475 const load_inst = self.builder.buildLoad(llvm_ret_ty, rp, "");
44694476 load_inst.setAlignment(alignment);
44704477 return load_inst;
44714478 }
......@@ -4523,7 +4530,7 @@ pub const FuncGen = struct {
45234530 // operand is a pointer however self.ret_ptr is null so that means
45244531 // we need to return a value.
45254532 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, "");
45274534 load_inst.setAlignment(alignment);
45284535 _ = self.builder.buildRet(load_inst);
45294536 return null;
......@@ -4540,7 +4547,7 @@ pub const FuncGen = struct {
45404547 const store_inst = self.builder.buildStore(operand, rp);
45414548 store_inst.setAlignment(alignment);
45424549 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, "");
45444551 load_inst.setAlignment(alignment);
45454552 _ = self.builder.buildRet(load_inst);
45464553 return null;
......@@ -4575,7 +4582,7 @@ pub const FuncGen = struct {
45754582 const ptr_abi_ty = abi_ret_ty.pointerType(0);
45764583 break :p self.builder.buildBitCast(ptr, ptr_abi_ty, "");
45774584 };
4578 const loaded = self.builder.buildLoad(casted_ptr, "");
4585 const loaded = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
45794586 loaded.setAlignment(ret_ty.abiAlignment(target));
45804587 _ = self.builder.buildRet(loaded);
45814588 return null;
......@@ -4615,7 +4622,7 @@ pub const FuncGen = struct {
46154622 const operand = try self.resolveInst(un_op);
46164623 const llvm_fn = try self.getCmpLtErrorsLenFunction();
46174624 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, "");
46194626 }
46204627
46214628 fn cmp(
......@@ -4642,8 +4649,9 @@ pub const FuncGen = struct {
46424649 // We need to emit instructions to check for equality/inequality
46434650 // of optionals that are not pointers.
46444651 const is_by_ref = isByRef(scalar_ty);
4645 const lhs_non_null = self.optIsNonNull(lhs, is_by_ref);
4646 const rhs_non_null = self.optIsNonNull(rhs, is_by_ref);
4652 const opt_llvm_ty = try self.dg.lowerType(scalar_ty);
4653 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
4654 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
46474655 const llvm_i2 = self.context.intType(2);
46484656 const lhs_non_null_i2 = self.builder.buildZExt(lhs_non_null, llvm_i2, "");
46494657 const rhs_non_null_i2 = self.builder.buildZExt(rhs_non_null, llvm_i2, "");
......@@ -4666,8 +4674,8 @@ pub const FuncGen = struct {
46664674 _ = self.builder.buildBr(end_block);
46674675
46684676 self.builder.positionBuilderAtEnd(both_pl_block);
4669 const lhs_payload = self.optPayloadHandle(lhs, scalar_ty);
4670 const rhs_payload = self.optPayloadHandle(rhs, scalar_ty);
4677 const lhs_payload = self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty);
4678 const rhs_payload = self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty);
46714679 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);
46724680 _ = self.builder.buildBr(end_block);
46734681 const both_pl_block_end = self.builder.getInsertBlock();
......@@ -4832,10 +4840,18 @@ pub const FuncGen = struct {
48324840 return lowerTry(self, err_union_ptr, body, err_union_ty, true, result_ty);
48334841 }
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 {
48364851 const payload_ty = err_union_ty.errorUnionPayload();
48374852 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
48384853 const target = fg.dg.module.getTarget();
4854 const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
48394855
48404856 if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
48414857 const is_err = err: {
......@@ -4843,14 +4859,17 @@ pub const FuncGen = struct {
48434859 const zero = err_set_ty.constNull();
48444860 if (!payload_has_bits) {
48454861 // 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;
48474866 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
48484867 }
48494868 const err_field_index = errUnionErrorOffset(payload_ty, target);
48504869 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, "");
48524871 // 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, "");
48544873 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
48554874 }
48564875 const loaded = fg.builder.buildExtractValue(err_union, err_field_index, "");
......@@ -4876,13 +4895,13 @@ pub const FuncGen = struct {
48764895 }
48774896 const offset = errUnionPayloadOffset(payload_ty, target);
48784897 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, "");
48804899 } 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, "");
48824901 if (isByRef(payload_ty)) {
48834902 return payload_ptr;
48844903 }
4885 const load_inst = fg.builder.buildLoad(payload_ptr, "");
4904 const load_inst = fg.builder.buildLoad(payload_ptr.getGEPSourceElementType(), payload_ptr, "");
48864905 load_inst.setAlignment(payload_ty.abiAlignment(target));
48874906 return load_inst;
48884907 }
......@@ -4977,7 +4996,8 @@ pub const FuncGen = struct {
49774996 const indices: [2]*const llvm.Value = .{
49784997 llvm_usize.constNull(), llvm_usize.constNull(),
49794998 };
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, "");
49815001 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
49825002 return self.builder.buildInsertValue(partial, len, 1, "");
49835003 }
......@@ -5038,7 +5058,7 @@ pub const FuncGen = struct {
50385058 const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
50395059 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, "");
50425062 }
50435063
50445064 fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value {
......@@ -5093,7 +5113,7 @@ pub const FuncGen = struct {
50935113 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
50945114 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
50985118 if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, "");
50995119 if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, "");
......@@ -5113,8 +5133,9 @@ pub const FuncGen = struct {
51135133
51145134 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
51155135 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, "");
51185139 }
51195140
51205141 fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5124,7 +5145,10 @@ pub const FuncGen = struct {
51245145
51255146 const slice = try self.resolveInst(bin_op.lhs);
51265147 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, "");
51285152 return self.load(ptr, slice_ty);
51295153 }
51305154
......@@ -5132,10 +5156,14 @@ pub const FuncGen = struct {
51325156 if (self.liveness.isUnused(inst)) return null;
51335157 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
51345158 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
5159 const slice_ty = self.air.typeOf(bin_op.lhs);
51355160
51365161 const slice = try self.resolveInst(bin_op.lhs);
51375162 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, "");
51395167 }
51405168
51415169 fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5146,13 +5174,14 @@ pub const FuncGen = struct {
51465174 const array_llvm_val = try self.resolveInst(bin_op.lhs);
51475175 const rhs = try self.resolveInst(bin_op.rhs);
51485176 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, "");
51515177 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, "");
51525181 if (isByRef(elem_ty)) {
51535182 return elem_ptr;
51545183 } else {
5155 return self.builder.buildLoad(elem_ptr, "");
5184 return self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
51565185 }
51575186 }
51585187
......@@ -5165,15 +5194,16 @@ pub const FuncGen = struct {
51655194 const ptr_ty = self.air.typeOf(bin_op.lhs);
51665195 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
51675196
5197 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
51685198 const base_ptr = try self.resolveInst(bin_op.lhs);
51695199 const rhs = try self.resolveInst(bin_op.rhs);
51705200 const ptr = if (ptr_ty.isSinglePointer()) ptr: {
51715201 // If this is a single-item pointer to an array, we need another index in the GEP.
51725202 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, "");
51745204 } else ptr: {
51755205 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, "");
51775207 };
51785208 return self.load(ptr, ptr_ty);
51795209 }
......@@ -5189,13 +5219,14 @@ pub const FuncGen = struct {
51895219
51905220 const base_ptr = try self.resolveInst(bin_op.lhs);
51915221 const rhs = try self.resolveInst(bin_op.rhs);
5222 const llvm_elem_ty = try self.dg.lowerType(elem_ty);
51925223 if (ptr_ty.isSinglePointer()) {
51935224 // If this is a single-item pointer to an array, we need another index in the GEP.
51945225 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, "");
51965227 } else {
51975228 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, "");
51995230 }
52005231 }
52015232
......@@ -5279,20 +5310,22 @@ pub const FuncGen = struct {
52795310 assert(struct_ty.containerLayout() != .Packed);
52805311 var ptr_ty_buf: Type.Payload.Pointer = undefined;
52815312 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, "");
52835315 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
52845316 return self.load(field_ptr, field_ptr_ty);
52855317 },
52865318 .Union => {
5287 const llvm_field_ty = try self.dg.lowerType(field_ty);
5319 const union_llvm_ty = try self.dg.lowerType(struct_ty);
52885320 const layout = struct_ty.unionGetLayout(target);
52895321 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);
52915324 const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");
52925325 if (isByRef(field_ty)) {
52935326 return field_ptr;
52945327 } else {
5295 return self.builder.buildLoad(field_ptr, "");
5328 return self.builder.buildLoad(llvm_field_ty, field_ptr, "");
52965329 }
52975330 },
52985331 else => unreachable,
......@@ -5605,10 +5638,11 @@ pub const FuncGen = struct {
56055638 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
56065639 } else {
56075640 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, "");
56095643 load_inst.setAlignment(alignment);
56105644 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;
56125646 }
56135647 } else {
56145648 if (constraintAllowsRegister(constraint)) {
......@@ -5769,6 +5803,7 @@ pub const FuncGen = struct {
57695803 .False,
57705804 );
57715805 const call = self.builder.buildCall(
5806 asm_fn.typeOf(),
57725807 asm_fn,
57735808 llvm_param_values.ptr,
57745809 @intCast(c_uint, param_count),
......@@ -5819,9 +5854,12 @@ pub const FuncGen = struct {
58195854 const operand = try self.resolveInst(un_op);
58205855 const operand_ty = self.air.typeOf(un_op);
58215856 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5857 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
58225858 if (optional_ty.optionalReprIsPayload()) {
5823 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
5824 const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
5859 const loaded = if (operand_is_ptr)
5860 self.builder.buildLoad(optional_llvm_ty, operand, "")
5861 else
5862 operand;
58255863 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
58265864 }
58275865
......@@ -5830,13 +5868,16 @@ pub const FuncGen = struct {
58305868 var buf: Type.Payload.ElemType = undefined;
58315869 const payload_ty = optional_ty.optionalChild(&buf);
58325870 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;
58345875 const llvm_i8 = self.dg.context.intType(8);
58355876 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
58365877 }
58375878
58385879 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);
58405881 if (pred == .EQ) {
58415882 return self.builder.buildNot(non_null_bit, "");
58425883 } else {
......@@ -5857,7 +5898,7 @@ pub const FuncGen = struct {
58575898 const operand_ty = self.air.typeOf(un_op);
58585899 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
58595900 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);
58615902 const zero = err_set_ty.constNull();
58625903
58635904 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
......@@ -5870,7 +5911,10 @@ pub const FuncGen = struct {
58705911 }
58715912
58725913 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;
58745918 return self.builder.buildICmp(op, loaded, zero, "");
58755919 }
58765920
......@@ -5878,8 +5922,9 @@ pub const FuncGen = struct {
58785922 const err_field_index = errUnionErrorOffset(payload_ty, target);
58795923
58805924 if (operand_is_ptr or isByRef(err_union_ty)) {
5881 const err_field_ptr = self.builder.buildStructGEP(operand, err_field_index, "");
5882 const loaded = self.builder.buildLoad(err_field_ptr, "");
5925 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
5926 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
5927 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
58835928 return self.builder.buildICmp(op, loaded, zero, "");
58845929 }
58855930
......@@ -5900,7 +5945,7 @@ pub const FuncGen = struct {
59005945 // We have a pointer to a zero-bit value and we need to return
59015946 // 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.
59045949 const res_ptr_ty = try self.dg.lowerType(result_ty);
59055950 return self.builder.buildBitCast(operand, res_ptr_ty, "");
59065951 }
......@@ -5908,7 +5953,8 @@ pub const FuncGen = struct {
59085953 // The payload and the optional are the same value.
59095954 return operand;
59105955 }
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, "");
59125958 }
59135959
59145960 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5925,7 +5971,7 @@ pub const FuncGen = struct {
59255971 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
59265972 _ = 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.
59295975 const res_ptr_ty = try self.dg.lowerType(result_ty);
59305976 return self.builder.buildBitCast(operand, res_ptr_ty, "");
59315977 }
......@@ -5936,7 +5982,8 @@ pub const FuncGen = struct {
59365982 }
59375983
59385984 // 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, "");
59405987 // TODO set alignment on this store
59415988 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
59425989
......@@ -5944,7 +5991,7 @@ pub const FuncGen = struct {
59445991 if (self.liveness.isUnused(inst))
59455992 return null;
59465993
5947 return self.builder.buildStructGEP(operand, 0, "");
5994 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
59485995 }
59495996
59505997 fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5961,7 +6008,8 @@ pub const FuncGen = struct {
59616008 return operand;
59626009 }
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);
59656013 }
59666014
59676015 fn airErrUnionPayload(
......@@ -5987,14 +6035,15 @@ pub const FuncGen = struct {
59876035 return self.builder.buildBitCast(operand, res_ptr_ty, "");
59886036 }
59896037 const offset = errUnionPayloadOffset(payload_ty, target);
6038 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
59906039 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, "");
59926041 } 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, "");
59946043 if (isByRef(payload_ty)) {
59956044 return payload_ptr;
59966045 }
5997 const load_inst = self.builder.buildLoad(payload_ptr, "");
6046 const load_inst = self.builder.buildLoad(payload_ptr.getGEPSourceElementType(), payload_ptr, "");
59986047 load_inst.setAlignment(payload_ty.abiAlignment(target));
59996048 return load_inst;
60006049 }
......@@ -6022,18 +6071,21 @@ pub const FuncGen = struct {
60226071 }
60236072 }
60246073
6074 const err_set_llvm_ty = try self.dg.lowerType(Type.anyerror);
6075
60256076 const payload_ty = err_union_ty.errorUnionPayload();
60266077 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
60276078 if (!operand_is_ptr) return operand;
6028 return self.builder.buildLoad(operand, "");
6079 return self.builder.buildLoad(err_set_llvm_ty, operand, "");
60296080 }
60306081
60316082 const target = self.dg.module.getTarget();
60326083 const offset = errUnionErrorOffset(payload_ty, target);
60336084
60346085 if (operand_is_ptr or isByRef(err_union_ty)) {
6035 const err_field_ptr = self.builder.buildStructGEP(operand, offset, "");
6036 return self.builder.buildLoad(err_field_ptr, "");
6086 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
6087 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
6088 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
60376089 }
60386090
60396091 return self.builder.buildExtractValue(operand, offset, "");
......@@ -6042,19 +6094,20 @@ pub const FuncGen = struct {
60426094 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
60436095 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
60446096 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();
60486100 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero });
60496101 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
60506102 _ = self.builder.buildStore(non_error_val, operand);
60516103 return operand;
60526104 }
60536105 const target = self.dg.module.getTarget();
6106 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
60546107 {
60556108 const error_offset = errUnionErrorOffset(payload_ty, target);
60566109 // 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, "");
60586111 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
60596112 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
60606113 }
......@@ -6063,7 +6116,7 @@ pub const FuncGen = struct {
60636116 return null;
60646117
60656118 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, "");
60676120 }
60686121
60696122 fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {
......@@ -6093,14 +6146,14 @@ pub const FuncGen = struct {
60936146 const llvm_optional_ty = try self.dg.lowerType(optional_ty);
60946147 if (isByRef(optional_ty)) {
60956148 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, "");
60976150 var ptr_ty_payload: Type.Payload.ElemType = .{
60986151 .base = .{ .tag = .single_mut_pointer },
60996152 .data = payload_ty,
61006153 };
61016154 const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base);
61026155 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, "");
61046157 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
61056158 return optional_ptr;
61066159 }
......@@ -6126,10 +6179,10 @@ pub const FuncGen = struct {
61266179 const error_offset = errUnionErrorOffset(payload_ty, target);
61276180 if (isByRef(inst_ty)) {
61286181 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, "");
61306183 const store_inst = self.builder.buildStore(ok_err_code, err_ptr);
61316184 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, "");
61336186 var ptr_ty_payload: Type.Payload.ElemType = .{
61346187 .base = .{ .tag = .single_mut_pointer },
61356188 .data = payload_ty,
......@@ -6160,10 +6213,10 @@ pub const FuncGen = struct {
61606213 const error_offset = errUnionErrorOffset(payload_ty, target);
61616214 if (isByRef(err_un_ty)) {
61626215 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, "");
61646217 const store_inst = self.builder.buildStore(operand, err_ptr);
61656218 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, "");
61676220 var ptr_ty_payload: Type.Payload.ElemType = .{
61686221 .base = .{ .tag = .single_mut_pointer },
61696222 .data = payload_ty,
......@@ -6188,7 +6241,7 @@ pub const FuncGen = struct {
61886241 const llvm_u32 = self.context.intType(32);
61896242 const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32});
61906243 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, "");
61926245 }
61936246
61946247 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -6201,7 +6254,7 @@ pub const FuncGen = struct {
62016254 llvm_u32.constInt(index, .False),
62026255 operand,
62036256 };
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, "");
62056258 }
62066259
62076260 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -6504,15 +6557,16 @@ pub const FuncGen = struct {
65046557 const base_ptr = try self.resolveInst(bin_op.lhs);
65056558 const offset = try self.resolveInst(bin_op.rhs);
65066559 const ptr_ty = self.air.typeOf(bin_op.lhs);
6560 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
65076561 if (ptr_ty.ptrSize() == .One) {
65086562 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
65096563 const indices: [2]*const llvm.Value = .{
65106564 self.context.intType(32).constNull(), offset,
65116565 };
6512 return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
6566 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
65136567 } else {
65146568 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, "");
65166570 }
65176571 }
65186572
......@@ -6525,15 +6579,16 @@ pub const FuncGen = struct {
65256579 const offset = try self.resolveInst(bin_op.rhs);
65266580 const negative_offset = self.builder.buildNeg(offset, "");
65276581 const ptr_ty = self.air.typeOf(bin_op.lhs);
6582 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());
65286583 if (ptr_ty.ptrSize() == .One) {
65296584 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
65306585 const indices: [2]*const llvm.Value = .{
65316586 self.context.intType(32).constNull(), negative_offset,
65326587 };
6533 return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
6588 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
65346589 } else {
65356590 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, "");
65376592 }
65386593 }
65396594
......@@ -6564,7 +6619,7 @@ pub const FuncGen = struct {
65646619 const tg = self.dg.module.getTarget();
65656620
65666621 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
65696624 const result = self.builder.buildExtractValue(result_struct, 0, "");
65706625 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
......@@ -6579,12 +6634,12 @@ pub const FuncGen = struct {
65796634 const result_alignment = dest_ty.abiAlignment(target);
65806635 alloca_inst.setAlignment(result_alignment);
65816636 {
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, "");
65836638 const store_inst = self.builder.buildStore(result, field_ptr);
65846639 store_inst.setAlignment(result_alignment);
65856640 }
65866641 {
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, "");
65886643 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
65896644 store_inst.setAlignment(1);
65906645 }
......@@ -6616,7 +6671,7 @@ pub const FuncGen = struct {
66166671 for (args_vectors) |arg_vector, k| {
66176672 args[k] = self.builder.buildExtractElement(arg_vector, index_i32, "");
66186673 }
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, "");
66206675 result = self.builder.buildInsertElement(result, result_elem, index_i32, "");
66216676 }
66226677 return result;
......@@ -6743,7 +6798,7 @@ pub const FuncGen = struct {
67436798 return self.builder.buildICmp(int_pred, result, zero_vector, "");
67446799 }
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, "");
67476802 return self.builder.buildICmp(int_pred, result, zero, "");
67486803 }
67496804
......@@ -6871,7 +6926,7 @@ pub const FuncGen = struct {
68716926 break :b libc_fn;
68726927 },
68736928 };
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, "");
68756930 }
68766931
68776932 fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -6931,12 +6986,12 @@ pub const FuncGen = struct {
69316986 const result_alignment = dest_ty.abiAlignment(target);
69326987 alloca_inst.setAlignment(result_alignment);
69336988 {
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, "");
69356990 const store_inst = self.builder.buildStore(result, field_ptr);
69366991 store_inst.setAlignment(result_alignment);
69376992 }
69386993 {
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, "");
69406995 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
69416996 store_inst.setAlignment(1);
69426997 }
......@@ -7226,7 +7281,7 @@ pub const FuncGen = struct {
72267281 const index_usize = llvm_usize.constInt(i, .False);
72277282 const index_u32 = llvm_u32.constInt(i, .False);
72287283 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, "");
72307285 const elem = self.builder.buildExtractElement(operand, index_u32, "");
72317286 _ = self.builder.buildStore(elem, elem_ptr);
72327287 }
......@@ -7243,7 +7298,7 @@ pub const FuncGen = struct {
72437298 if (bitcast_ok) {
72447299 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);
72457300 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, "");
72477302 // The array is aligned to the element's alignment, while the vector might have a completely
72487303 // different alignment. This means we need to enforce the alignment of this load.
72497304 vector.setAlignment(elem_ty.abiAlignment(target));
......@@ -7251,6 +7306,7 @@ pub const FuncGen = struct {
72517306 } else {
72527307 // If the ABI size of the element type is not evenly divisible by size in bits;
72537308 // a simple bitcast will not work, and we fall back to extractelement.
7309 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
72547310 const llvm_usize = try self.dg.lowerType(Type.usize);
72557311 const llvm_u32 = self.context.intType(32);
72567312 const zero = llvm_usize.constNull();
......@@ -7261,8 +7317,8 @@ pub const FuncGen = struct {
72617317 const index_usize = llvm_usize.constInt(i, .False);
72627318 const index_u32 = llvm_u32.constInt(i, .False);
72637319 const indexes: [2]*const llvm.Value = .{ zero, index_usize };
7264 const elem_ptr = self.builder.buildInBoundsGEP(operand, &indexes, indexes.len, "");
7265 const elem = self.builder.buildLoad(elem_ptr, "");
7320 const elem_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, operand, &indexes, indexes.len, "");
7321 const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, "");
72667322 vector = self.builder.buildInsertElement(vector, elem, index_u32, "");
72677323 }
72687324
......@@ -7273,7 +7329,7 @@ pub const FuncGen = struct {
72737329 if (operand_is_ref) {
72747330 // Bitcast the operand pointer, then load.
72757331 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, "");
72777333 load_inst.setAlignment(operand_ty.abiAlignment(target));
72787334 return load_inst;
72797335 }
......@@ -7301,7 +7357,7 @@ pub const FuncGen = struct {
73017357 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
73027358 const store_inst = self.builder.buildStore(operand, casted_ptr);
73037359 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, "");
73057361 load_inst.setAlignment(alignment);
73067362 return load_inst;
73077363 }
......@@ -7481,7 +7537,7 @@ pub const FuncGen = struct {
74817537 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
74827538 _ = inst;
74837539 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, "");
74857541 return null;
74867542 }
74877543
......@@ -7498,7 +7554,7 @@ pub const FuncGen = struct {
74987554 const llvm_i32 = self.context.intType(32);
74997555 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
75007556 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, "");
75027558 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
75037559 }
75047560
......@@ -7515,7 +7571,7 @@ pub const FuncGen = struct {
75157571 };
75167572
75177573 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, "");
75197575 const llvm_usize = try self.dg.lowerType(Type.usize);
75207576 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
75217577 }
......@@ -7740,8 +7796,9 @@ pub const FuncGen = struct {
77407796 _ = self.builder.buildStore(new_tag, union_ptr);
77417797 return null;
77427798 }
7799 const un_llvm_ty = try self.dg.lowerType(un_ty);
77437800 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, "");
77457802 // TODO alignment on this store
77467803 _ = self.builder.buildStore(new_tag, tag_field_ptr);
77477804 return null;
......@@ -7757,12 +7814,13 @@ pub const FuncGen = struct {
77577814 if (layout.tag_size == 0) return null;
77587815 const union_handle = try self.resolveInst(ty_op.operand);
77597816 if (isByRef(un_ty)) {
7817 const llvm_un_ty = try self.dg.lowerType(un_ty);
77607818 if (layout.payload_size == 0) {
7761 return self.builder.buildLoad(union_handle, "");
7819 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
77627820 }
77637821 const tag_index = @boolToInt(layout.tag_align < layout.payload_align);
7764 const tag_field_ptr = self.builder.buildStructGEP(union_handle, tag_index, "");
7765 return self.builder.buildLoad(tag_field_ptr, "");
7822 const tag_field_ptr = self.builder.buildStructGEP(llvm_un_ty, union_handle, tag_index, "");
7823 return self.builder.buildLoad(tag_field_ptr.getGEPSourceElementType(), tag_field_ptr, "");
77667824 } else {
77677825 if (layout.payload_size == 0) {
77687826 return union_handle;
......@@ -7805,7 +7863,7 @@ pub const FuncGen = struct {
78057863 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
78067864
78077865 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, "");
78097867 const result_ty = self.air.typeOfIndex(inst);
78107868 const result_llvm_ty = try self.dg.lowerType(result_ty);
78117869
......@@ -7832,7 +7890,7 @@ pub const FuncGen = struct {
78327890 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
78337891 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, "");
78367894 const result_ty = self.air.typeOfIndex(inst);
78377895 const result_llvm_ty = try self.dg.lowerType(result_ty);
78387896
......@@ -7889,7 +7947,7 @@ pub const FuncGen = struct {
78897947 const params = [_]*const llvm.Value{operand};
78907948 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
78947952 const result_ty = self.air.typeOfIndex(inst);
78957953 const result_llvm_ty = try self.dg.lowerType(result_ty);
......@@ -7912,7 +7970,7 @@ pub const FuncGen = struct {
79127970
79137971 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
79147972 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, "");
79167974 }
79177975
79187976 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value {
......@@ -7973,7 +8031,8 @@ pub const FuncGen = struct {
79738031
79748032 for (fields.keys()) |name, field_index| {
79758033 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, "");
79778036 str_global.setInitializer(str_init);
79788037 str_global.setLinkage(.Private);
79798038 str_global.setGlobalConstant(.True);
......@@ -7981,7 +8040,7 @@ pub const FuncGen = struct {
79818040 str_global.setAlignment(1);
79828041
79838042 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),
79858044 usize_llvm_ty.constInt(name.len, .False),
79868045 };
79878046 const slice_init = llvm_ret_ty.constNamedStruct(&slice_fields, slice_fields.len);
......@@ -8006,7 +8065,7 @@ pub const FuncGen = struct {
80068065 switch_instr.addCase(this_tag_int_value, return_block);
80078066
80088067 self.builder.positionBuilderAtEnd(return_block);
8009 const loaded = self.builder.buildLoad(slice_global, "");
8068 const loaded = self.builder.buildLoad(llvm_ret_ty, slice_global, "");
80108069 loaded.setAlignment(slice_alignment);
80118070 _ = self.builder.buildRet(loaded);
80128071 }
......@@ -8040,12 +8099,15 @@ pub const FuncGen = struct {
80408099
80418100 const un_op = self.air.instructions.items(.data)[inst].un_op;
80428101 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
80448105 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, "");
80468108 const indices = [_]*const llvm.Value{operand};
8047 const error_name_ptr = self.builder.buildInBoundsGEP(error_name_table, &indices, indices.len, "");
8048 return self.builder.buildLoad(error_name_ptr, "");
8109 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
8110 return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, "");
80498111 }
80508112
80518113 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -8222,7 +8284,7 @@ pub const FuncGen = struct {
82228284 const llvm_elem = try self.resolveInst(elem);
82238285 const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?;
82248286 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, "");
82268288 var field_ptr_payload: Type.Payload.Pointer = .{
82278289 .data = .{
82288290 .pointee_type = self.air.typeOf(elem),
......@@ -8268,7 +8330,7 @@ pub const FuncGen = struct {
82688330 llvm_usize.constNull(),
82698331 llvm_usize.constInt(@intCast(c_uint, i), .False),
82708332 };
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, "");
82728334 const llvm_elem = try self.resolveInst(elem);
82738335 self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);
82748336 }
......@@ -8277,7 +8339,7 @@ pub const FuncGen = struct {
82778339 llvm_usize.constNull(),
82788340 llvm_usize.constInt(@intCast(c_uint, array_info.len), .False),
82798341 };
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, "");
82818343 const llvm_elem = try self.dg.lowerValue(.{
82828344 .ty = array_info.elem_type,
82838345 .val = sent_val,
......@@ -8377,7 +8439,7 @@ pub const FuncGen = struct {
83778439 index_type.constNull(),
83788440 };
83798441 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, "");
83818443 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
83828444 return result_ptr;
83838445 }
......@@ -8389,7 +8451,7 @@ pub const FuncGen = struct {
83898451 index_type.constNull(),
83908452 };
83918453 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, "");
83938455 self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
83948456 }
83958457 {
......@@ -8397,7 +8459,7 @@ pub const FuncGen = struct {
83978459 index_type.constNull(),
83988460 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
83998461 };
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, "");
84018463 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
84028464 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);
84038465 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
......@@ -8464,7 +8526,7 @@ pub const FuncGen = struct {
84648526 llvm_u32.constInt(prefetch.locality, .False),
84658527 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
84668528 };
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, "");
84688530 return null;
84698531 }
84708532
......@@ -8544,7 +8606,7 @@ pub const FuncGen = struct {
85448606 };
85458607
85468608 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, "");
85488610 const final_cast_llvm_ty = final_cast orelse return result;
85498611 return self.builder.buildBitCast(result, final_cast_llvm_ty, "");
85508612 }
......@@ -8571,22 +8633,29 @@ pub const FuncGen = struct {
85718633 }
85728634
85738635 /// 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);
85758643 const field = b: {
85768644 if (is_by_ref) {
8577 const field_ptr = self.builder.buildStructGEP(opt_handle, 1, "");
8578 break :b self.builder.buildLoad(field_ptr, "");
8645 const field_ptr = self.builder.buildStructGEP(opt_llvm_ty, opt_handle, 1, "");
8646 break :b self.builder.buildLoad(non_null_llvm_ty, field_ptr, "");
85798647 }
85808648 break :b self.builder.buildExtractValue(opt_handle, 1, "");
85818649 };
85828650 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), "");
85858653 }
85868654
85878655 /// Assumes the optional is not pointer-like and payload has bits.
85888656 fn optPayloadHandle(
85898657 fg: *FuncGen,
8658 opt_llvm_ty: *const llvm.Type,
85908659 opt_handle: *const llvm.Value,
85918660 opt_ty: Type,
85928661 ) *const llvm.Value {
......@@ -8595,14 +8664,14 @@ pub const FuncGen = struct {
85958664
85968665 if (isByRef(opt_ty)) {
85978666 // 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
86008669 if (isByRef(payload_ty)) {
86018670 return payload_ptr;
86028671 }
86038672 const target = fg.dg.module.getTarget();
86048673 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, "");
86068675 load_inst.setAlignment(payload_alignment);
86078676 return load_inst;
86088677 }
......@@ -8627,12 +8696,12 @@ pub const FuncGen = struct {
86278696 alloca_inst.setAlignment(payload_alignment);
86288697
86298698 {
8630 const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, "");
8699 const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 0, "");
86318700 const store_inst = self.builder.buildStore(payload, field_ptr);
86328701 store_inst.setAlignment(payload_alignment);
86338702 }
86348703 {
8635 const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, "");
8704 const field_ptr = self.builder.buildStructGEP(optional_llvm_ty, alloca_inst, 1, "");
86368705 const store_inst = self.builder.buildStore(non_null_field, field_ptr);
86378706 store_inst.setAlignment(1);
86388707 }
......@@ -8678,18 +8747,20 @@ pub const FuncGen = struct {
86788747 if (byte_offset == 0) {
86798748 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
86808749 }
8681 const llvm_bytes_ptr_ty = self.context.intType(8).pointerType(0);
8682 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, llvm_bytes_ptr_ty, "");
8750 const byte_llvm_ty = self.context.intType(8);
8751 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
86838752 const llvm_usize = try self.dg.lowerType(Type.usize);
86848753 const llvm_index = llvm_usize.constInt(byte_offset, .False);
86858754 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, "");
86878756 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
86888757 },
86898758 else => {
8759 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
8760
86908761 var ty_buf: Type.Payload.Pointer = undefined;
86918762 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, "");
86938764 } else {
86948765 // If we found no index then this means this is a zero sized field at the
86958766 // end of the struct. Treat our struct pointer as an array of two and get
......@@ -8698,7 +8769,7 @@ pub const FuncGen = struct {
86988769 const llvm_usize = try self.dg.lowerType(Type.usize);
86998770 const llvm_index = llvm_usize.constInt(1, .False);
87008771 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, "");
87028773 }
87038774 },
87048775 },
......@@ -8716,27 +8787,18 @@ pub const FuncGen = struct {
87168787 ) !?*const llvm.Value {
87178788 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
87188789 const field = &union_obj.fields.values()[field_index];
8719 const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
87208790 if (!field.ty.hasRuntimeBitsIgnoreComptime()) {
87218791 return null;
87228792 }
87238793 const target = self.dg.module.getTarget();
87248794 const layout = union_ty.unionGetLayout(target);
87258795 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));
87278799 return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
87288800 }
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
87408802 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value {
87418803 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
87428804 assert(id != 0);
......@@ -8754,8 +8816,8 @@ pub const FuncGen = struct {
87548816 const ptr_alignment = ptr_ty.ptrAlignment(target);
87558817 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
87568818 if (info.host_size == 0) {
8819 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
87578820 if (isByRef(info.pointee_type)) {
8758 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
87598821 const result_align = info.pointee_type.abiAlignment(target);
87608822 const max_align = @maximum(result_align, ptr_alignment);
87618823 const result_ptr = self.buildAlloca(elem_llvm_ty);
......@@ -8773,15 +8835,15 @@ pub const FuncGen = struct {
87738835 );
87748836 return result_ptr;
87758837 }
8776 const llvm_inst = self.builder.buildLoad(ptr, "");
8838 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
87778839 llvm_inst.setAlignment(ptr_alignment);
87788840 llvm_inst.setVolatile(ptr_volatile);
87798841 return llvm_inst;
87808842 }
87818843
8782 const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);
8783 const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");
8784 const containing_int = self.builder.buildLoad(int_ptr, "");
8844 const int_elem_ty = self.context.intType(info.host_size * 8);
8845 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
8846 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
87858847 containing_int.setAlignment(ptr_alignment);
87868848 containing_int.setVolatile(ptr_volatile);
87878849
......@@ -8828,9 +8890,9 @@ pub const FuncGen = struct {
88288890 const ptr_alignment = ptr_ty.ptrAlignment(target);
88298891 const ptr_volatile = llvm.Bool.fromBool(info.@"volatile");
88308892 if (info.host_size != 0) {
8831 const int_ptr_ty = self.context.intType(info.host_size * 8).pointerType(0);
8832 const int_ptr = self.builder.buildBitCast(ptr, int_ptr_ty, "");
8833 const containing_int = self.builder.buildLoad(int_ptr, "");
8893 const int_elem_ty = self.context.intType(info.host_size * 8);
8894 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
8895 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
88348896 assert(ordering == .NotAtomic);
88358897 containing_int.setAlignment(ptr_alignment);
88368898 containing_int.setVolatile(ptr_volatile);
src/codegen/llvm/bindings.zig+14-8
......@@ -141,14 +141,6 @@ pub const Value = opaque {
141141 pub const setAliasee = LLVMAliasSetAliasee;
142142 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
152144 pub const constBitCast = LLVMConstBitCast;
153145 extern fn LLVMConstBitCast(ConstantVal: *const Value, ToType: *const Type) *const Value;
154146
......@@ -249,6 +241,9 @@ pub const Value = opaque {
249241
250242 pub const addFunctionAttr = ZigLLVMAddFunctionAttr;
251243 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;
252247};
253248
254249pub const Type = opaque {
......@@ -280,6 +275,9 @@ pub const Type = opaque {
280275 pub const getUndef = LLVMGetUndef;
281276 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
283281 pub const arrayType = LLVMArrayType;
284282 extern fn LLVMArrayType(ElementType: *const Type, ElementCount: c_uint) *const Type;
285283
......@@ -311,6 +309,14 @@ pub const Type = opaque {
311309
312310 pub const isSized = LLVMTypeIsSized;
313311 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;
314320};
315321
316322pub const Module = opaque {