authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-26 23:08:10-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-12-27 00:12:56-05:00
log46b49a0a766a39ca37ba48f1a1c2ed28c260b08b
tree9511c81a36419d8307767f23cc9495caa378fcbc
parent1b86a628acef7bc180ea6cbe6e4930710e5dff97

llvm: cleanup code no longer needed with opaque pointers

When using llvm opaque pointers, typed pointers and pointer bitcasts are no longer needed. This also avoids needing packed struct layouts that are nested inside pointers, letting us avoid computing struct layouts in Sema that could cause unnecessary dependency loops.

2 files changed, 165 insertions(+), 330 deletions(-)

src/codegen/llvm.zig+165-327
......@@ -582,7 +582,7 @@ pub const Object = struct {
582582 const mod = self.module;
583583 const target = mod.getTarget();
584584
585 const llvm_ptr_ty = self.context.intType(8).pointerType(0); // TODO: Address space
585 const llvm_ptr_ty = self.context.pointerType(0); // TODO: Address space
586586 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
587587 const type_fields = [_]*llvm.Type{
588588 llvm_ptr_ty,
......@@ -608,7 +608,7 @@ pub const Object = struct {
608608 str_global.setAlignment(1);
609609
610610 const slice_fields = [_]*llvm.Value{
611 str_global.constBitCast(llvm_ptr_ty),
611 str_global,
612612 llvm_usize_ty.constInt(name.len, .False),
613613 };
614614 llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len);
......@@ -623,7 +623,7 @@ pub const Object = struct {
623623 error_name_table_global.setUnnamedAddr(.True);
624624 error_name_table_global.setAlignment(slice_alignment); // TODO: Dont hardcode
625625
626 const error_name_table_ptr = error_name_table_global.constBitCast(llvm_slice_ty.pointerType(0)); // TODO: Address space
626 const error_name_table_ptr = error_name_table_global;
627627 error_name_table_ptr_global.setInitializer(error_name_table_ptr);
628628 }
629629
......@@ -681,10 +681,9 @@ pub const Object = struct {
681681 const other_global = object.getLlvmGlobal(decl.name) orelse continue;
682682 if (other_global == llvm_global) continue;
683683
684 const new_global_ptr = other_global.constBitCast(llvm_global.typeOf());
685 llvm_global.replaceAllUsesWith(new_global_ptr);
684 llvm_global.replaceAllUsesWith(other_global);
686685 deleteLlvmGlobal(llvm_global);
687 entry.value_ptr.* = new_global_ptr;
686 entry.value_ptr.* = other_global;
688687 }
689688 object.extern_collisions.clearRetainingCapacity();
690689
......@@ -703,11 +702,7 @@ pub const Object = struct {
703702 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
704703 if (other_global == llvm_global) continue;
705704
706 // replaceAllUsesWith requires the type to be unchanged. So we bitcast
707 // the new global to the old type and use that as the thing to replace
708 // old uses.
709 const new_global_ptr = llvm_global.constBitCast(other_global.typeOf());
710 other_global.replaceAllUsesWith(new_global_ptr);
705 other_global.replaceAllUsesWith(llvm_global);
711706 llvm_global.takeName(other_global);
712707 deleteLlvmGlobal(other_global);
713708 // Problem: now we need to replace in the decl_map that
......@@ -962,7 +957,7 @@ pub const Object = struct {
962957 if (isByRef(param_ty)) {
963958 const alignment = param_ty.abiAlignment(target);
964959 const param_llvm_ty = param.typeOf();
965 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
960 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
966961 const store_inst = builder.buildStore(param, arg_ptr);
967962 store_inst.setAlignment(alignment);
968963 args.appendAssumeCapacity(arg_ptr);
......@@ -1020,14 +1015,12 @@ pub const Object = struct {
10201015 const param_llvm_ty = try dg.lowerType(param_ty);
10211016 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
10221017 const int_llvm_ty = dg.context.intType(abi_size * 8);
1023 const int_ptr_llvm_ty = int_llvm_ty.pointerType(0);
10241018 const alignment = @max(
10251019 param_ty.abiAlignment(target),
10261020 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
10271021 );
1028 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1029 const casted_ptr = builder.buildBitCast(arg_ptr, int_ptr_llvm_ty, "");
1030 const store_inst = builder.buildStore(param, casted_ptr);
1022 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1023 const store_inst = builder.buildStore(param, arg_ptr);
10311024 store_inst.setAlignment(alignment);
10321025
10331026 try args.ensureUnusedCapacity(1);
......@@ -1078,14 +1071,13 @@ pub const Object = struct {
10781071 const param_ty = fn_info.param_types[it.zig_index - 1];
10791072 const param_llvm_ty = try dg.lowerType(param_ty);
10801073 const param_alignment = param_ty.abiAlignment(target);
1081 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1074 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
10821075 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1083 const casted_ptr = builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), "");
10841076 for (field_types) |_, field_i_usize| {
10851077 const field_i = @intCast(c_uint, field_i_usize);
10861078 const param = llvm_func.getParam(llvm_arg_i);
10871079 llvm_arg_i += 1;
1088 const field_ptr = builder.buildStructGEP(llvm_ty, casted_ptr, field_i, "");
1080 const field_ptr = builder.buildStructGEP(llvm_ty, arg_ptr, field_i, "");
10891081 const store_inst = builder.buildStore(param, field_ptr);
10901082 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
10911083 }
......@@ -1113,9 +1105,8 @@ pub const Object = struct {
11131105 llvm_arg_i += 1;
11141106
11151107 const alignment = param_ty.abiAlignment(target);
1116 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1117 const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), "");
1118 _ = builder.buildStore(param, casted_ptr);
1108 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1109 _ = builder.buildStore(param, arg_ptr);
11191110
11201111 if (isByRef(param_ty)) {
11211112 try args.append(arg_ptr);
......@@ -1132,9 +1123,8 @@ pub const Object = struct {
11321123 llvm_arg_i += 1;
11331124
11341125 const alignment = param_ty.abiAlignment(target);
1135 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);
1136 const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), "");
1137 _ = builder.buildStore(param, casted_ptr);
1126 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1127 _ = builder.buildStore(param, arg_ptr);
11381128
11391129 if (isByRef(param_ty)) {
11401130 try args.append(arg_ptr);
......@@ -2477,12 +2467,8 @@ pub const DeclGen = struct {
24772467 new_global.setAlignment(global.getAlignment());
24782468 if (decl.@"linksection") |section| new_global.setSection(section);
24792469 new_global.setInitializer(llvm_init);
2480 // replaceAllUsesWith requires the type to be unchanged. So we convert
2481 // the new global to the old type and use that as the thing to replace
2482 // old uses.
24832470 // TODO: How should this work then the address space of a global changed?
2484 const new_global_ptr = new_global.constBitCast(global.typeOf());
2485 global.replaceAllUsesWith(new_global_ptr);
2471 global.replaceAllUsesWith(new_global);
24862472 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
24872473 new_global.takeName(global);
24882474 global.deleteGlobal();
......@@ -2781,11 +2767,7 @@ pub const DeclGen = struct {
27812767 }
27822768 const ptr_info = t.ptrInfo().data;
27832769 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);
2784 if (ptr_info.host_size != 0) {
2785 return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace);
2786 }
2787 const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type);
2788 return llvm_elem_ty.pointerType(llvm_addrspace);
2770 return dg.context.pointerType(llvm_addrspace);
27892771 },
27902772 .Opaque => switch (t.tag()) {
27912773 .@"opaque" => {
......@@ -3108,8 +3090,7 @@ pub const DeclGen = struct {
31083090 defer llvm_params.deinit();
31093091
31103092 if (firstParamSRet(fn_info, target)) {
3111 const llvm_sret_ty = try dg.lowerType(fn_info.return_type);
3112 try llvm_params.append(llvm_sret_ty.pointerType(0));
3093 try llvm_params.append(dg.context.pointerType(0));
31133094 }
31143095
31153096 if (fn_info.return_type.isError() and
......@@ -3131,9 +3112,7 @@ pub const DeclGen = struct {
31313112 try llvm_params.append(try dg.lowerType(param_ty));
31323113 },
31333114 .byref, .byref_mut => {
3134 const param_ty = fn_info.param_types[it.zig_index - 1];
3135 const raw_llvm_ty = try dg.lowerType(param_ty);
3136 try llvm_params.append(raw_llvm_ty.pointerType(0));
3115 try llvm_params.append(dg.context.pointerType(0));
31373116 },
31383117 .abi_sized_int => {
31393118 const param_ty = fn_info.param_types[it.zig_index - 1];
......@@ -3323,16 +3302,12 @@ pub const DeclGen = struct {
33233302 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
33243303 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
33253304
3326 const llvm_var_type = try dg.lowerType(tv.ty);
3327 const llvm_actual_ptr_type = llvm_var_type.pointerType(llvm_actual_addrspace);
3328
33293305 const val = try dg.resolveGlobalDecl(decl_index);
3330 const val_ptr = val.constBitCast(llvm_actual_ptr_type);
3331 if (llvm_actual_addrspace != llvm_wanted_addrspace) {
3332 const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace);
3333 return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type);
3334 }
3335 return val_ptr;
3306 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
3307 val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace))
3308 else
3309 val;
3310 return addrspace_casted_ptr;
33363311 },
33373312 .slice => {
33383313 const slice = tv.val.castTag(.slice).?.data;
......@@ -3355,7 +3330,7 @@ pub const DeclGen = struct {
33553330 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
33563331 },
33573332 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
3358 return dg.lowerParentPtr(tv.val, tv.ty.childType());
3333 return dg.lowerParentPtr(tv.val);
33593334 },
33603335 .null_value, .zero => {
33613336 const llvm_type = try dg.lowerType(tv.ty);
......@@ -3363,7 +3338,7 @@ pub const DeclGen = struct {
33633338 },
33643339 .opt_payload => {
33653340 const payload = tv.val.castTag(.opt_payload).?.data;
3366 return dg.lowerParentPtr(payload, tv.ty);
3341 return dg.lowerParentPtr(payload);
33673342 },
33683343 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
33693344 tv.ty.fmtDebug(), tag,
......@@ -3940,7 +3915,6 @@ pub const DeclGen = struct {
39403915 dg: *DeclGen,
39413916 ptr_val: Value,
39423917 decl_index: Module.Decl.Index,
3943 ptr_child_ty: Type,
39443918 ) Error!*llvm.Value {
39453919 const decl = dg.module.declPtr(decl_index);
39463920 dg.module.markDeclAlive(decl);
......@@ -3949,62 +3923,54 @@ pub const DeclGen = struct {
39493923 .data = decl.ty,
39503924 };
39513925 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
3952 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
3953
3954 if (ptr_child_ty.eql(decl.ty, dg.module)) {
3955 return llvm_ptr;
3956 } else {
3957 return llvm_ptr.constBitCast((try dg.lowerType(ptr_child_ty)).pointerType(0));
3958 }
3926 return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
39593927 }
39603928
3961 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value {
3929 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value {
39623930 const target = dg.module.getTarget();
3963 var bitcast_needed: bool = undefined;
3964 const llvm_ptr = switch (ptr_val.tag()) {
3931 switch (ptr_val.tag()) {
39653932 .decl_ref_mut => {
39663933 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
3967 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3934 return dg.lowerParentPtrDecl(ptr_val, decl);
39683935 },
39693936 .decl_ref => {
39703937 const decl = ptr_val.castTag(.decl_ref).?.data;
3971 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3938 return dg.lowerParentPtrDecl(ptr_val, decl);
39723939 },
39733940 .variable => {
39743941 const decl = ptr_val.castTag(.variable).?.data.owner_decl;
3975 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3942 return dg.lowerParentPtrDecl(ptr_val, decl);
39763943 },
39773944 .int_i64 => {
39783945 const int = ptr_val.castTag(.int_i64).?.data;
39793946 const llvm_usize = try dg.lowerType(Type.usize);
39803947 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);
3981 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));
3948 return llvm_int.constIntToPtr(dg.context.pointerType(0));
39823949 },
39833950 .int_u64 => {
39843951 const int = ptr_val.castTag(.int_u64).?.data;
39853952 const llvm_usize = try dg.lowerType(Type.usize);
39863953 const llvm_int = llvm_usize.constInt(int, .False);
3987 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));
3954 return llvm_int.constIntToPtr(dg.context.pointerType(0));
39883955 },
3989 .field_ptr => blk: {
3956 .field_ptr => {
39903957 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
3991 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, field_ptr.container_ty);
3958 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr);
39923959 const parent_ty = field_ptr.container_ty;
39933960
39943961 const field_index = @intCast(u32, field_ptr.field_index);
39953962 const llvm_u32 = dg.context.intType(32);
39963963 switch (parent_ty.zigTypeTag()) {
39973964 .Union => {
3998 bitcast_needed = true;
39993965 if (parent_ty.containerLayout() == .Packed) {
4000 break :blk parent_llvm_ptr;
3966 return parent_llvm_ptr;
40013967 }
40023968
40033969 const layout = parent_ty.unionGetLayout(target);
40043970 if (layout.payload_size == 0) {
40053971 // In this case a pointer to the union and a pointer to any
40063972 // (void) payload is the same.
4007 break :blk parent_llvm_ptr;
3973 return parent_llvm_ptr;
40083974 }
40093975 const llvm_pl_index = if (layout.tag_size == 0)
40103976 0
......@@ -4015,10 +3981,9 @@ pub const DeclGen = struct {
40153981 llvm_u32.constInt(llvm_pl_index, .False),
40163982 };
40173983 const parent_llvm_ty = try dg.lowerType(parent_ty);
4018 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3984 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40193985 },
40203986 .Struct => {
4021 const field_ty = parent_ty.structFieldType(field_index);
40223987 if (parent_ty.containerLayout() == .Packed) {
40233988 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
40243989 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
......@@ -4033,26 +3998,23 @@ pub const DeclGen = struct {
40333998 };
40343999 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
40354000 const field_addr = base_addr.constAdd(byte_offset);
4036 bitcast_needed = false;
4037 const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0);
4038 break :blk field_addr.constIntToPtr(final_llvm_ty);
4001 const final_llvm_ty = dg.context.pointerType(0);
4002 return field_addr.constIntToPtr(final_llvm_ty);
40394003 }
40404004
40414005 var ty_buf: Type.Payload.Pointer = undefined;
40424006
40434007 const parent_llvm_ty = try dg.lowerType(parent_ty);
40444008 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {
4045 bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
40464009 const indices: [2]*llvm.Value = .{
40474010 llvm_u32.constInt(0, .False),
40484011 llvm_u32.constInt(llvm_field_index, .False),
40494012 };
4050 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4013 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40514014 } else {
4052 bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module);
40534015 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);
40544016 const indices: [1]*llvm.Value = .{llvm_index};
4055 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4017 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40564018 }
40574019 },
40584020 .Pointer => {
......@@ -4062,37 +4024,34 @@ pub const DeclGen = struct {
40624024 llvm_u32.constInt(field_index, .False),
40634025 };
40644026 const parent_llvm_ty = try dg.lowerType(parent_ty);
4065 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4027 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40664028 },
40674029 else => unreachable,
40684030 }
40694031 },
4070 .elem_ptr => blk: {
4032 .elem_ptr => {
40714033 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
4072 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, elem_ptr.elem_ty);
4073 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module);
4034 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr);
40744035
40754036 const llvm_usize = try dg.lowerType(Type.usize);
40764037 const indices: [1]*llvm.Value = .{
40774038 llvm_usize.constInt(elem_ptr.index, .False),
40784039 };
40794040 const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);
4080 break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4041 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40814042 },
4082 .opt_payload_ptr => blk: {
4043 .opt_payload_ptr => {
40834044 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
4084 const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, opt_payload_ptr.container_ty);
4045 const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr);
40854046 var buf: Type.Payload.ElemType = undefined;
40864047
40874048 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
4088 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4089
40904049 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
40914050 payload_ty.optionalReprIsPayload())
40924051 {
40934052 // In this case, we represent pointer to optional the same as pointer
40944053 // to the payload.
4095 break :blk parent_llvm_ptr;
4054 return parent_llvm_ptr;
40964055 }
40974056
40984057 const llvm_u32 = dg.context.intType(32);
......@@ -4101,19 +4060,17 @@ pub const DeclGen = struct {
41014060 llvm_u32.constInt(0, .False),
41024061 };
41034062 const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty);
4104 break :blk opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4063 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41054064 },
4106 .eu_payload_ptr => blk: {
4065 .eu_payload_ptr => {
41074066 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
4108 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);
4067 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr);
41094068
41104069 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4111 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4112
41134070 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
41144071 // In this case, we represent pointer to error union the same as pointer
41154072 // to the payload.
4116 break :blk parent_llvm_ptr;
4073 return parent_llvm_ptr;
41174074 }
41184075
41194076 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;
......@@ -4123,14 +4080,9 @@ pub const DeclGen = struct {
41234080 llvm_u32.constInt(payload_offset, .False),
41244081 };
41254082 const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty);
4126 break :blk eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4083 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41274084 },
41284085 else => unreachable,
4129 };
4130 if (bitcast_needed) {
4131 return llvm_ptr.constBitCast((try dg.lowerPtrElemTy(ptr_child_ty)).pointerType(0));
4132 } else {
4133 return llvm_ptr;
41344086 }
41354087 }
41364088
......@@ -4189,8 +4141,7 @@ pub const DeclGen = struct {
41894141 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
41904142 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
41914143 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
4192 const llvm_decl_ty = try self.lowerType(decl.ty);
4193 const llvm_decl_wanted_ptr_ty = llvm_decl_ty.pointerType(llvm_wanted_addrspace);
4144 const llvm_decl_wanted_ptr_ty = self.context.pointerType(llvm_wanted_addrspace);
41944145 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
41954146 } else llvm_decl_val;
41964147
......@@ -4471,18 +4422,11 @@ pub const FuncGen = struct {
44714422 global.setGlobalConstant(.True);
44724423 global.setUnnamedAddr(.True);
44734424 global.setAlignment(tv.ty.abiAlignment(target));
4474 // Because of LLVM limitations for lowering certain types such as unions,
4475 // the type of global constants might not match the type it is supposed to
4476 // be, and so we must bitcast the pointer at the usage sites.
4477 const wanted_llvm_ty = try self.dg.lowerType(tv.ty);
4478 const wanted_bitcasted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_actual_addrspace);
4479 const bitcasted_ptr = global.constBitCast(wanted_bitcasted_llvm_ptr_ty);
4480 const wanted_llvm_ptr_ty = wanted_llvm_ty.pointerType(llvm_wanted_addrspace);
4481 const casted_ptr = if (llvm_wanted_addrspace != llvm_actual_addrspace)
4482 bitcasted_ptr.constAddrSpaceCast(wanted_llvm_ptr_ty)
4425 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
4426 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))
44834427 else
4484 bitcasted_ptr;
4485 return casted_ptr;
4428 global;
4429 return addrspace_casted_ptr;
44864430 }
44874431
44884432 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
......@@ -4770,17 +4714,7 @@ pub const FuncGen = struct {
47704714 load_inst.setAlignment(alignment);
47714715 try llvm_args.append(load_inst);
47724716 } else {
4773 if (param_ty.zigTypeTag() == .Pointer) {
4774 // We need a bitcast in case of two possibilities:
4775 // 1. The parameter type is a pointer to zero-sized type,
4776 // which is always lowered to an LLVM type of `*i8`.
4777 // 2. The argument is a global which does act as a pointer, however
4778 // a bitcast is needed in order for the LLVM types to match.
4779 const casted_ptr = self.builder.buildBitCast(llvm_arg, llvm_param_ty, "");
4780 try llvm_args.append(casted_ptr);
4781 } else {
4782 try llvm_args.append(llvm_arg);
4783 }
4717 try llvm_args.append(llvm_arg);
47844718 }
47854719 },
47864720 .byref => {
......@@ -4824,26 +4758,22 @@ pub const FuncGen = struct {
48244758 const param_ty = self.air.typeOf(arg);
48254759 const llvm_arg = try self.resolveInst(arg);
48264760 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
4827 const int_llvm_ty = self.dg.context.intType(abi_size * 8);
4828 const int_ptr_llvm_ty = int_llvm_ty.pointerType(0);
4761 const int_llvm_ty = self.context.intType(abi_size * 8);
48294762
48304763 if (isByRef(param_ty)) {
48314764 const alignment = param_ty.abiAlignment(target);
4832 const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, "");
4833 const load_inst = self.builder.buildLoad(int_llvm_ty, casted_ptr, "");
4765 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");
48344766 load_inst.setAlignment(alignment);
48354767 try llvm_args.append(load_inst);
48364768 } else {
48374769 // LLVM does not allow bitcasting structs so we must allocate
4838 // a local, bitcast its pointer, store, and then load.
4770 // a local, store as one type, and then load as another type.
48394771 const alignment = @max(
48404772 param_ty.abiAlignment(target),
48414773 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
48424774 );
48434775 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
4844 const param_llvm_ty = try self.dg.lowerType(param_ty);
4845 const casted_ptr = self.builder.buildBitCast(int_ptr, param_llvm_ty.pointerType(0), "");
4846 const store_inst = self.builder.buildStore(llvm_arg, casted_ptr);
4776 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
48474777 store_inst.setAlignment(alignment);
48484778 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
48494779 load_inst.setAlignment(alignment);
......@@ -4872,12 +4802,11 @@ pub const FuncGen = struct {
48724802 break :p p;
48734803 };
48744804
4875 const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);
4876 const casted_ptr = self.builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), "");
4805 const llvm_ty = self.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);
48774806 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
48784807 for (llvm_types) |field_ty, i_usize| {
48794808 const i = @intCast(c_uint, i_usize);
4880 const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, "");
4809 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");
48814810 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");
48824811 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
48834812 llvm_args.appendAssumeCapacity(load_inst);
......@@ -4886,7 +4815,7 @@ pub const FuncGen = struct {
48864815 .as_u16 => {
48874816 const arg = args[it.zig_index - 1];
48884817 const llvm_arg = try self.resolveInst(arg);
4889 const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), "");
4818 const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), "");
48904819 try llvm_args.append(casted);
48914820 },
48924821 .float_array => |count| {
......@@ -4903,9 +4832,8 @@ pub const FuncGen = struct {
49034832 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);
49044833 const array_llvm_ty = float_ty.arrayType(count);
49054834
4906 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
49074835 const alignment = arg_ty.abiAlignment(target);
4908 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");
4836 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49094837 load_inst.setAlignment(alignment);
49104838 try llvm_args.append(load_inst);
49114839 },
......@@ -4921,10 +4849,9 @@ pub const FuncGen = struct {
49214849 llvm_arg = store_inst;
49224850 }
49234851
4924 const array_llvm_ty = self.dg.context.intType(elem_size).arrayType(arr_len);
4925 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
4852 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);
49264853 const alignment = arg_ty.abiAlignment(target);
4927 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");
4854 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49284855 load_inst.setAlignment(alignment);
49294856 try llvm_args.append(load_inst);
49304857 },
......@@ -5028,12 +4955,10 @@ pub const FuncGen = struct {
50284955 if (abi_ret_ty != llvm_ret_ty) {
50294956 // In this case the function return type is honoring the calling convention by having
50304957 // a different LLVM type than the usual one. We solve this here at the callsite
5031 // by bitcasting a pointer to our canonical type, then loading it if necessary.
4958 // by using our canonical type, then loading it if necessary.
50324959 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);
50334960 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5034 const ptr_abi_ty = abi_ret_ty.pointerType(0);
5035 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");
5036 const store_inst = self.builder.buildStore(call, casted_ptr);
4961 const store_inst = self.builder.buildStore(call, rp);
50374962 store_inst.setAlignment(alignment);
50384963 if (isByRef(return_type)) {
50394964 return rp;
......@@ -5086,7 +5011,6 @@ pub const FuncGen = struct {
50865011 }
50875012
50885013 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5089 const ptr_abi_ty = abi_ret_ty.pointerType(0);
50905014 const operand = try self.resolveInst(un_op);
50915015 const target = self.dg.module.getTarget();
50925016 const alignment = ret_ty.abiAlignment(target);
......@@ -5094,8 +5018,7 @@ pub const FuncGen = struct {
50945018 if (isByRef(ret_ty)) {
50955019 // operand is a pointer however self.ret_ptr is null so that means
50965020 // we need to return a value.
5097 const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");
5098 const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
5021 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");
50995022 load_inst.setAlignment(alignment);
51005023 _ = self.builder.buildRet(load_inst);
51015024 return null;
......@@ -5110,8 +5033,7 @@ pub const FuncGen = struct {
51105033 const rp = self.buildAlloca(llvm_ret_ty, alignment);
51115034 const store_inst = self.builder.buildStore(operand, rp);
51125035 store_inst.setAlignment(alignment);
5113 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");
5114 const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
5036 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");
51155037 load_inst.setAlignment(alignment);
51165038 _ = self.builder.buildRet(load_inst);
51175039 return null;
......@@ -5141,12 +5063,7 @@ pub const FuncGen = struct {
51415063 const ptr = try self.resolveInst(un_op);
51425064 const target = self.dg.module.getTarget();
51435065 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5144 const llvm_ret_ty = try self.dg.lowerType(ret_ty);
5145 const casted_ptr = if (abi_ret_ty == llvm_ret_ty) ptr else p: {
5146 const ptr_abi_ty = abi_ret_ty.pointerType(0);
5147 break :p self.builder.buildBitCast(ptr, ptr_abi_ty, "");
5148 };
5149 const loaded = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
5066 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
51505067 loaded.setAlignment(ret_ty.abiAlignment(target));
51515068 _ = self.builder.buildRet(loaded);
51525069 return null;
......@@ -5178,8 +5095,8 @@ pub const FuncGen = struct {
51785095 const llvm_fn_name = "llvm.va_copy";
51795096 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
51805097 const param_types = [_]*llvm.Type{
5181 self.dg.context.intType(8).pointerType(0),
5182 self.dg.context.intType(8).pointerType(0),
5098 self.context.pointerType(0),
5099 self.context.pointerType(0),
51835100 };
51845101 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
51855102 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
......@@ -5203,7 +5120,7 @@ pub const FuncGen = struct {
52035120
52045121 const llvm_fn_name = "llvm.va_end";
52055122 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5206 const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)};
5123 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
52075124 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
52085125 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
52095126 };
......@@ -5224,7 +5141,7 @@ pub const FuncGen = struct {
52245141
52255142 const llvm_fn_name = "llvm.va_start";
52265143 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5227 const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)};
5144 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
52285145 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
52295146 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
52305147 };
......@@ -5417,7 +5334,7 @@ pub const FuncGen = struct {
54175334 // of function pointers, however the phi makes it a runtime value and therefore
54185335 // the LLVM type has to be wrapped in a pointer.
54195336 if (is_body or isByRef(inst_ty)) {
5420 break :ty raw_llvm_ty.pointerType(0);
5337 break :ty self.context.pointerType(0);
54215338 }
54225339 break :ty raw_llvm_ty;
54235340 };
......@@ -5482,7 +5399,7 @@ pub const FuncGen = struct {
54825399 const payload_ty = self.air.typeOfIndex(inst);
54835400 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
54845401 const is_unused = self.liveness.isUnused(inst);
5485 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty);
5402 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
54865403 }
54875404
54885405 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
......@@ -5491,9 +5408,8 @@ pub const FuncGen = struct {
54915408 const err_union_ptr = try self.resolveInst(extra.data.ptr);
54925409 const body = self.air.extra[extra.end..][0..extra.data.body_len];
54935410 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
5494 const payload_ty = self.air.typeOfIndex(inst);
54955411 const is_unused = self.liveness.isUnused(inst);
5496 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty);
5412 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);
54975413 }
54985414
54995415 fn lowerTry(
......@@ -5504,7 +5420,6 @@ pub const FuncGen = struct {
55045420 operand_is_ptr: bool,
55055421 can_elide_load: bool,
55065422 is_unused: bool,
5507 result_ty: Type,
55085423 ) !?*llvm.Value {
55095424 const payload_ty = err_union_ty.errorUnionPayload();
55105425 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
......@@ -5547,12 +5462,7 @@ pub const FuncGen = struct {
55475462 return null;
55485463 }
55495464 if (!payload_has_bits) {
5550 if (!operand_is_ptr) return null;
5551
5552 // TODO once we update to an LLVM version with opaque pointers
5553 // this bitcast won't be necessary.
5554 const res_ptr_ty = try fg.dg.lowerType(result_ty);
5555 return fg.builder.buildBitCast(err_union, res_ptr_ty, "");
5465 return if (operand_is_ptr) err_union else null;
55565466 }
55575467 const offset = errUnionPayloadOffset(payload_ty, target);
55585468 if (operand_is_ptr) {
......@@ -6038,9 +5948,8 @@ pub const FuncGen = struct {
60385948 const union_llvm_ty = try self.dg.lowerType(struct_ty);
60395949 const layout = struct_ty.unionGetLayout(target);
60405950 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
6041 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
5951 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
60425952 const llvm_field_ty = try self.dg.lowerType(field_ty);
6043 const field_ptr = self.builder.buildBitCast(union_field_ptr, llvm_field_ty.pointerType(0), "");
60445953 if (isByRef(field_ty)) {
60455954 if (canElideLoad(self, body_tail))
60465955 return field_ptr;
......@@ -6068,7 +5977,7 @@ pub const FuncGen = struct {
60685977
60695978 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
60705979 if (field_offset == 0) {
6071 return self.builder.buildBitCast(field_ptr, res_ty, "");
5980 return field_ptr;
60725981 }
60735982 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
60745983
......@@ -6635,7 +6544,7 @@ pub const FuncGen = struct {
66356544 self.builder.buildLoad(optional_llvm_ty, operand, "")
66366545 else
66376546 operand;
6638 const llvm_i8 = self.dg.context.intType(8);
6547 const llvm_i8 = self.context.intType(8);
66396548 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
66406549 }
66416550
......@@ -6701,16 +6610,12 @@ pub const FuncGen = struct {
67016610 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67026611 const operand = try self.resolveInst(ty_op.operand);
67036612 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6704 const result_ty = self.air.getRefType(ty_op.ty);
67056613 var buf: Type.Payload.ElemType = undefined;
67066614 const payload_ty = optional_ty.optionalChild(&buf);
67076615 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
67086616 // We have a pointer to a zero-bit value and we need to return
67096617 // a pointer to a zero-bit value.
6710
6711 // TODO once we update to LLVM 16 this bitcast won't be necessary.
6712 const res_ptr_ty = try self.dg.lowerType(result_ty);
6713 return self.builder.buildBitCast(operand, res_ptr_ty, "");
6618 return operand;
67146619 }
67156620 if (optional_ty.optionalReprIsPayload()) {
67166621 // The payload and the optional are the same value.
......@@ -6726,17 +6631,13 @@ pub const FuncGen = struct {
67266631 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67276632 const operand = try self.resolveInst(ty_op.operand);
67286633 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6729 const result_ty = self.air.getRefType(ty_op.ty);
67306634 var buf: Type.Payload.ElemType = undefined;
67316635 const payload_ty = optional_ty.optionalChild(&buf);
67326636 const non_null_bit = self.context.intType(8).constInt(1, .False);
67336637 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
67346638 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
67356639 _ = self.builder.buildStore(non_null_bit, operand);
6736
6737 // TODO once we update to LLVM 16 this bitcast won't be necessary.
6738 const res_ptr_ty = try self.dg.lowerType(result_ty);
6739 return self.builder.buildBitCast(operand, res_ptr_ty, "");
6640 return operand;
67406641 }
67416642 if (optional_ty.optionalReprIsPayload()) {
67426643 // The payload and the optional are the same value.
......@@ -6794,11 +6695,7 @@ pub const FuncGen = struct {
67946695 const target = self.dg.module.getTarget();
67956696
67966697 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6797 if (!operand_is_ptr) return null;
6798
6799 // TODO once we update to LLVM 14 this bitcast won't be necessary.
6800 const res_ptr_ty = try self.dg.lowerType(result_ty);
6801 return self.builder.buildBitCast(operand, res_ptr_ty, "");
6698 return if (operand_is_ptr) operand else null;
68026699 }
68036700 const offset = errUnionPayloadOffset(payload_ty, target);
68046701 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
......@@ -6834,7 +6731,7 @@ pub const FuncGen = struct {
68346731 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
68356732 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
68366733 if (operand_is_ptr) {
6837 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");
6734 return operand;
68386735 } else {
68396736 return err_llvm_ty.constInt(0, .False);
68406737 }
......@@ -7104,14 +7001,8 @@ pub const FuncGen = struct {
71047001 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
71057002
71067003 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`
7107 // but `ptr` is pointing to the global directly. If it's an array, we would want to
7108 // do GEP(0,0), or we can just bitcast it to be correct, like we do here.
7109 // This prevents an assertion failure.
7110 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
7111 const ptr_ty = inst_ty.slicePtrFieldType(&buf);
7112 const ptr_llvm_ty = try self.dg.lowerType(ptr_ty);
7113 const casted_ptr = self.builder.buildBitCast(ptr, ptr_llvm_ty, "");
7114 const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), casted_ptr, 0, "");
7004 // but `ptr` is pointing to the global directly.
7005 const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), ptr, 0, "");
71157006 return self.builder.buildInsertValue(partial, len, 1, "");
71167007 }
71177008
......@@ -7636,7 +7527,7 @@ pub const FuncGen = struct {
76367527 .neg => {
76377528 // In this case we can generate a softfloat negation by XORing the
76387529 // bits with a constant.
7639 const int_llvm_ty = self.dg.context.intType(float_bits);
7530 const int_llvm_ty = self.context.intType(float_bits);
76407531 const one = int_llvm_ty.constInt(1, .False);
76417532 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
76427533 const sign_mask = one.constShl(shift_amt);
......@@ -8045,8 +7936,8 @@ pub const FuncGen = struct {
80457936 const target = self.dg.module.getTarget();
80467937
80477938 if (operand_is_ref and result_is_ref) {
8048 // They are both pointers; just do a bitcast on the pointers :)
8049 return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
7939 // They are both pointers, so just return the same opaque pointer :)
7940 return operand;
80507941 }
80517942
80527943 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
......@@ -8061,9 +7952,7 @@ pub const FuncGen = struct {
80617952 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
80627953 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
80637954 if (bitcast_ok) {
8064 const llvm_vector_ty = try self.dg.lowerType(operand_ty);
8065 const casted_ptr = self.builder.buildBitCast(array_ptr, llvm_vector_ty.pointerType(0), "");
8066 const llvm_store = self.builder.buildStore(operand, casted_ptr);
7955 const llvm_store = self.builder.buildStore(operand, array_ptr);
80677956 llvm_store.setAlignment(inst_ty.abiAlignment(target));
80687957 } else {
80697958 // If the ABI size of the element type is not evenly divisible by size in bits;
......@@ -8092,9 +7981,7 @@ pub const FuncGen = struct {
80927981
80937982 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
80947983 if (bitcast_ok) {
8095 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);
8096 const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, "");
8097 const vector = self.builder.buildLoad(llvm_vector_ty, casted_ptr, "");
7984 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");
80987985 // The array is aligned to the element's alignment, while the vector might have a completely
80997986 // different alignment. This means we need to enforce the alignment of this load.
81007987 vector.setAlignment(elem_ty.abiAlignment(target));
......@@ -8124,20 +8011,15 @@ pub const FuncGen = struct {
81248011 }
81258012
81268013 if (operand_is_ref) {
8127 // Bitcast the operand pointer, then load.
8128 const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
8129 const load_inst = self.builder.buildLoad(llvm_dest_ty, casted_ptr, "");
8014 const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, "");
81308015 load_inst.setAlignment(operand_ty.abiAlignment(target));
81318016 return load_inst;
81328017 }
81338018
81348019 if (result_is_ref) {
8135 // Bitcast the result pointer, then store.
81368020 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
81378021 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8138 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8139 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
8140 const store_inst = self.builder.buildStore(operand, casted_ptr);
8022 const store_inst = self.builder.buildStore(operand, result_ptr);
81418023 store_inst.setAlignment(alignment);
81428024 return result_ptr;
81438025 }
......@@ -8145,12 +8027,10 @@ pub const FuncGen = struct {
81458027 if (llvm_dest_ty.getTypeKind() == .Struct) {
81468028 // Both our operand and our result are values, not pointers,
81478029 // but LLVM won't let us bitcast struct values.
8148 // Therefore, we store operand to bitcasted alloca, then load for result.
8030 // Therefore, we store operand to alloca, then load for result.
81498031 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
81508032 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8151 const operand_llvm_ty = try self.dg.lowerType(operand_ty);
8152 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
8153 const store_inst = self.builder.buildStore(operand, casted_ptr);
8033 const store_inst = self.builder.buildStore(operand, result_ptr);
81548034 store_inst.setAlignment(alignment);
81558035 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
81568036 load_inst.setAlignment(alignment);
......@@ -8248,7 +8128,7 @@ pub const FuncGen = struct {
82488128 /// Use this instead of builder.buildAlloca, because this function makes sure to
82498129 /// put the alloca instruction at the top of the function!
82508130 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {
8251 return buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());
8131 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());
82528132 }
82538133
82548134 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
......@@ -8282,13 +8162,11 @@ pub const FuncGen = struct {
82828162 const target = self.dg.module.getTarget();
82838163 const operand_size = operand_ty.abiSize(target);
82848164 const u8_llvm_ty = self.context.intType(8);
8285 const ptr_u8_llvm_ty = u8_llvm_ty.pointerType(0);
8286 const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, ptr_u8_llvm_ty, "");
82878165 const fill_char = u8_llvm_ty.constInt(0xaa, .False);
82888166 const dest_ptr_align = ptr_ty.ptrAlignment(target);
82898167 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
82908168 const len = usize_llvm_ty.constInt(operand_size, .False);
8291 _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8169 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
82928170 if (self.dg.module.comp.bin_file.options.valgrind) {
82938171 self.valgrindMarkUndef(dest_ptr, len);
82948172 }
......@@ -8365,7 +8243,7 @@ pub const FuncGen = struct {
83658243 const llvm_i32 = self.context.intType(32);
83668244 const llvm_fn_name = "llvm.frameaddress.p0";
83678245 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8368 const llvm_p0i8 = self.context.intType(8).pointerType(0);
8246 const llvm_p0i8 = self.context.pointerType(0);
83698247 const param_types = [_]*llvm.Type{llvm_i32};
83708248 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);
83718249 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
......@@ -8388,14 +8266,13 @@ pub const FuncGen = struct {
83888266 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
83898267 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
83908268 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8391 var ptr = try self.resolveInst(extra.ptr);
8269 const ptr = try self.resolveInst(extra.ptr);
83928270 var expected_value = try self.resolveInst(extra.expected_value);
83938271 var new_value = try self.resolveInst(extra.new_value);
83948272 const operand_ty = self.air.typeOf(extra.ptr).elemType();
83958273 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
83968274 if (opt_abi_ty) |abi_ty| {
83978275 // operand needs widening and truncating
8398 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
83998276 if (operand_ty.isSignedInt()) {
84008277 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
84018278 new_value = self.builder.buildSExt(new_value, abi_ty, "");
......@@ -8447,7 +8324,6 @@ pub const FuncGen = struct {
84478324 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);
84488325 if (opt_abi_ty) |abi_ty| {
84498326 // operand needs widening and truncating or bitcasting.
8450 const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
84518327 const casted_operand = if (is_float)
84528328 self.builder.buildBitCast(operand, abi_ty, "")
84538329 else if (is_signed_int)
......@@ -8457,7 +8333,7 @@ pub const FuncGen = struct {
84578333
84588334 const uncasted_result = self.builder.buildAtomicRmw(
84598335 op,
8460 casted_ptr,
8336 ptr,
84618337 casted_operand,
84628338 ordering,
84638339 single_threaded,
......@@ -8476,11 +8352,10 @@ pub const FuncGen = struct {
84768352
84778353 // It's a pointer but we need to treat it as an int.
84788354 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8479 const casted_ptr = self.builder.buildBitCast(ptr, usize_llvm_ty.pointerType(0), "");
84808355 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
84818356 const uncasted_result = self.builder.buildAtomicRmw(
84828357 op,
8483 casted_ptr,
8358 ptr,
84848359 casted_operand,
84858360 ordering,
84868361 single_threaded,
......@@ -8508,8 +8383,7 @@ pub const FuncGen = struct {
85088383
85098384 if (opt_abi_llvm_ty) |abi_llvm_ty| {
85108385 // operand needs widening and truncating
8511 const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), "");
8512 const load_inst = self.builder.buildLoad(abi_llvm_ty, casted_ptr, "");
8386 const load_inst = self.builder.buildLoad(abi_llvm_ty, ptr, "");
85138387 load_inst.setAlignment(ptr_alignment);
85148388 load_inst.setVolatile(ptr_volatile);
85158389 load_inst.setOrdering(ordering);
......@@ -8531,13 +8405,12 @@ pub const FuncGen = struct {
85318405 const ptr_ty = self.air.typeOf(bin_op.lhs);
85328406 const operand_ty = ptr_ty.childType();
85338407 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
8534 var ptr = try self.resolveInst(bin_op.lhs);
8408 const ptr = try self.resolveInst(bin_op.lhs);
85358409 var element = try self.resolveInst(bin_op.rhs);
85368410 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
85378411
85388412 if (opt_abi_ty) |abi_ty| {
85398413 // operand needs widening
8540 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
85418414 if (operand_ty.isSignedInt()) {
85428415 element = self.builder.buildSExt(element, abi_ty, "");
85438416 } else {
......@@ -8557,15 +8430,13 @@ pub const FuncGen = struct {
85578430 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;
85588431 const len = try self.resolveInst(extra.rhs);
85598432 const u8_llvm_ty = self.context.intType(8);
8560 const ptr_u8_llvm_ty = u8_llvm_ty.pointerType(0);
8561 const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, ptr_u8_llvm_ty, "");
85628433 const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value;
85638434 const target = self.dg.module.getTarget();
85648435 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8565 _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8436 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
85668437
85678438 if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) {
8568 self.valgrindMarkUndef(dest_ptr_u8, len);
8439 self.valgrindMarkUndef(dest_ptr, len);
85698440 }
85708441 return null;
85718442 }
......@@ -8578,15 +8449,12 @@ pub const FuncGen = struct {
85788449 const src_ptr = try self.resolveInst(extra.lhs);
85798450 const src_ptr_ty = self.air.typeOf(extra.lhs);
85808451 const len = try self.resolveInst(extra.rhs);
8581 const llvm_ptr_u8 = self.context.intType(8).pointerType(0);
8582 const dest_ptr_u8 = self.builder.buildBitCast(dest_ptr, llvm_ptr_u8, "");
8583 const src_ptr_u8 = self.builder.buildBitCast(src_ptr, llvm_ptr_u8, "");
85848452 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
85858453 const target = self.dg.module.getTarget();
85868454 _ = self.builder.buildMemCpy(
8587 dest_ptr_u8,
8455 dest_ptr,
85888456 dest_ptr_ty.ptrAlignment(target),
8589 src_ptr_u8,
8457 src_ptr,
85908458 src_ptr_ty.ptrAlignment(target),
85918459 len,
85928460 is_volatile,
......@@ -8780,8 +8648,8 @@ pub const FuncGen = struct {
87808648 const error_set_ty = self.air.getRefType(ty_op.ty);
87818649
87828650 const names = error_set_ty.errorSetNames();
8783 const valid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Valid");
8784 const invalid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Invalid");
8651 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
8652 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
87858653 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
87868654 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87878655
......@@ -8807,7 +8675,7 @@ pub const FuncGen = struct {
88078675
88088676 self.builder.positionBuilderAtEnd(end_block);
88098677
8810 const llvm_type = self.dg.context.intType(1);
8678 const llvm_type = self.context.intType(1);
88118679 const incoming_values: [2]*llvm.Value = .{
88128680 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
88138681 };
......@@ -8869,13 +8737,13 @@ pub const FuncGen = struct {
88698737 }
88708738 }
88718739
8872 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");
8740 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
88738741 self.builder.positionBuilderAtEnd(entry_block);
88748742 self.builder.clearCurrentDebugLocation();
88758743
88768744 const fields = enum_ty.enumFields();
8877 const named_block = self.dg.context.appendBasicBlock(fn_val, "Named");
8878 const unnamed_block = self.dg.context.appendBasicBlock(fn_val, "Unnamed");
8745 const named_block = self.context.appendBasicBlock(fn_val, "Named");
8746 const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed");
88798747 const tag_int_value = fn_val.getParam(0);
88808748 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count()));
88818749
......@@ -8893,10 +8761,10 @@ pub const FuncGen = struct {
88938761 switch_instr.addCase(this_tag_int_value, named_block);
88948762 }
88958763 self.builder.positionBuilderAtEnd(named_block);
8896 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(1, .False));
8764 _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False));
88978765
88988766 self.builder.positionBuilderAtEnd(unnamed_block);
8899 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(0, .False));
8767 _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False));
89008768 return fn_val;
89018769 }
89028770
......@@ -8955,12 +8823,12 @@ pub const FuncGen = struct {
89558823 }
89568824 }
89578825
8958 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");
8826 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
89598827 self.builder.positionBuilderAtEnd(entry_block);
89608828 self.builder.clearCurrentDebugLocation();
89618829
89628830 const fields = enum_ty.enumFields();
8963 const bad_value_block = self.dg.context.appendBasicBlock(fn_val, "BadValue");
8831 const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue");
89648832 const tag_int_value = fn_val.getParam(0);
89658833 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count()));
89668834
......@@ -8969,7 +8837,7 @@ pub const FuncGen = struct {
89698837 };
89708838
89718839 for (fields.keys()) |name, field_index| {
8972 const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
8840 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
89738841 const str_init_llvm_ty = str_init.typeOf();
89748842 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
89758843 str_global.setInitializer(str_init);
......@@ -8990,7 +8858,7 @@ pub const FuncGen = struct {
89908858 slice_global.setUnnamedAddr(.True);
89918859 slice_global.setAlignment(slice_alignment);
89928860
8993 const return_block = self.dg.context.appendBasicBlock(fn_val, "Name");
8861 const return_block = self.context.appendBasicBlock(fn_val, "Name");
89948862 const this_tag_int_value = int: {
89958863 var tag_val_payload: Value.Payload.U32 = .{
89968864 .base = .{ .tag = .enum_field_index },
......@@ -9042,7 +8910,7 @@ pub const FuncGen = struct {
90428910 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
90438911
90448912 const error_name_table_ptr = try self.getErrorNameTable();
9045 const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0);
8913 const ptr_slice_llvm_ty = self.context.pointerType(0);
90468914 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");
90478915 const indices = [_]*llvm.Value{operand};
90488916 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
......@@ -9285,7 +9153,7 @@ pub const FuncGen = struct {
92859153 if (result_ty.containerLayout() == .Packed) {
92869154 const struct_obj = result_ty.castTag(.@"struct").?.data;
92879155 const big_bits = struct_obj.backing_int_ty.bitSize(target);
9288 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));
9156 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
92899157 const fields = struct_obj.fields.values();
92909158 comptime assert(Type.packed_struct_layout_version == 2);
92919159 var running_int: *llvm.Value = int_llvm_ty.constNull();
......@@ -9296,7 +9164,7 @@ pub const FuncGen = struct {
92969164
92979165 const non_int_val = try self.resolveInst(elem);
92989166 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9299 const small_int_ty = self.dg.context.intType(ty_bit_size);
9167 const small_int_ty = self.context.intType(ty_bit_size);
93009168 const small_int_val = if (field.ty.isPtrAtRuntime())
93019169 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
93029170 else
......@@ -9410,11 +9278,11 @@ pub const FuncGen = struct {
94109278
94119279 if (union_obj.layout == .Packed) {
94129280 const big_bits = union_ty.bitSize(target);
9413 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));
9281 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
94149282 const field = union_obj.fields.values()[extra.field_index];
94159283 const non_int_val = try self.resolveInst(extra.init);
94169284 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9417 const small_int_ty = self.dg.context.intType(ty_bit_size);
9285 const small_int_ty = self.context.intType(ty_bit_size);
94189286 const small_int_val = if (field.ty.isPtrAtRuntime())
94199287 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
94209288 else
......@@ -9444,9 +9312,9 @@ pub const FuncGen = struct {
94449312 }
94459313 assert(isByRef(union_ty));
94469314 // The llvm type of the alloca will be the named LLVM union type, and will not
9447 // necessarily match the format that we need, depending on which tag is active. We
9448 // must construct the correct unnamed struct type here and bitcast, in order to
9449 // then set the fields appropriately.
9315 // necessarily match the format that we need, depending on which tag is active.
9316 // We must construct the correct unnamed struct type here, in order to then set
9317 // the fields appropriately.
94509318 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);
94519319 const llvm_payload = try self.resolveInst(extra.init);
94529320 assert(union_obj.haveFieldTypes());
......@@ -9489,8 +9357,6 @@ pub const FuncGen = struct {
94899357 break :t self.context.structType(&fields, fields_len, .False);
94909358 };
94919359
9492 const casted_ptr = self.builder.buildBitCast(result_ptr, llvm_union_ty.pointerType(0), "");
9493
94949360 // Now we follow the layout as expressed above with GEP instructions to set the
94959361 // tag and the payload.
94969362 const index_type = self.context.intType(32);
......@@ -9510,7 +9376,7 @@ pub const FuncGen = struct {
95109376 index_type.constNull(),
95119377 };
95129378 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9513 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");
9379 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
95149380 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
95159381 return result_ptr;
95169382 }
......@@ -9522,7 +9388,7 @@ pub const FuncGen = struct {
95229388 index_type.constNull(),
95239389 };
95249390 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9525 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");
9391 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
95269392 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
95279393 }
95289394 {
......@@ -9530,7 +9396,7 @@ pub const FuncGen = struct {
95309396 index_type.constNull(),
95319397 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
95329398 };
9533 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, "");
9399 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
95349400 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
95359401 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
95369402 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
......@@ -9579,8 +9445,7 @@ pub const FuncGen = struct {
95799445 .data => {},
95809446 }
95819447
9582 const llvm_u8 = self.context.intType(8);
9583 const llvm_ptr_u8 = llvm_u8.pointerType(0);
9448 const llvm_ptr_u8 = self.context.pointerType(0);
95849449 const llvm_u32 = self.context.intType(32);
95859450
95869451 const llvm_fn_name = "llvm.prefetch.p0";
......@@ -9595,10 +9460,9 @@ pub const FuncGen = struct {
95959460 };
95969461
95979462 const ptr = try self.resolveInst(prefetch.ptr);
9598 const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, "");
95999463
96009464 const params = [_]*llvm.Value{
9601 ptr_u8,
9465 ptr,
96029466 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),
96039467 llvm_u32.constInt(prefetch.locality, .False),
96049468 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
......@@ -9625,8 +9489,7 @@ pub const FuncGen = struct {
96259489
96269490 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
96279491 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());
9628 const llvm_slice_ty = try self.dg.lowerType(slice_ty);
9629 const llvm_slice_ptr_ty = llvm_slice_ty.pointerType(0); // TODO: Address space
9492 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
96309493
96319494 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
96329495 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
......@@ -9699,7 +9562,7 @@ pub const FuncGen = struct {
96999562 non_null_bit: *llvm.Value,
97009563 ) !?*llvm.Value {
97019564 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
9702 const non_null_field = self.builder.buildZExt(non_null_bit, self.dg.context.intType(8), "");
9565 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
97039566
97049567 if (isByRef(optional_ty)) {
97059568 const target = self.dg.module.getTarget();
......@@ -9740,31 +9603,24 @@ pub const FuncGen = struct {
97409603 .Packed => {
97419604 const result_ty = self.air.typeOfIndex(inst);
97429605 const result_ty_info = result_ty.ptrInfo().data;
9743 const result_llvm_ty = try self.dg.lowerType(result_ty);
97449606
97459607 if (result_ty_info.host_size != 0) {
97469608 // From LLVM's perspective, a pointer to a packed struct and a pointer
97479609 // to a field of a packed struct are the same. The difference is in the
97489610 // Zig pointer type which provides information for how to mask and shift
97499611 // out the relevant bits when accessing the pointee.
9750 // Here we perform a bitcast because we want to use the host_size
9751 // as the llvm pointer element type.
9752 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
9612 return struct_ptr;
97539613 }
97549614
97559615 // We have a pointer to a packed struct field that happens to be byte-aligned.
97569616 // Offset our operand pointer by the correct number of bytes.
97579617 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);
9758 if (byte_offset == 0) {
9759 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
9760 }
9618 if (byte_offset == 0) return struct_ptr;
97619619 const byte_llvm_ty = self.context.intType(8);
9762 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
97639620 const llvm_usize = try self.dg.lowerType(Type.usize);
97649621 const llvm_index = llvm_usize.constInt(byte_offset, .False);
97659622 const indices: [1]*llvm.Value = .{llvm_index};
9766 const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, "");
9767 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
9623 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
97689624 },
97699625 else => {
97709626 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
......@@ -9777,39 +9633,25 @@ pub const FuncGen = struct {
97779633 // end of the struct. Treat our struct pointer as an array of two and get
97789634 // the index to the element at index `1` to get a pointer to the end of
97799635 // the struct.
9780 const llvm_u32 = self.dg.context.intType(32);
9636 const llvm_u32 = self.context.intType(32);
97819637 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);
97829638 const indices: [1]*llvm.Value = .{llvm_index};
97839639 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
97849640 }
97859641 },
97869642 },
9787 .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty),
9643 .Union => {
9644 const layout = struct_ty.unionGetLayout(target);
9645 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;
9646 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9647 const union_llvm_ty = try self.dg.lowerType(struct_ty);
9648 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
9649 return union_field_ptr;
9650 },
97889651 else => unreachable,
97899652 }
97909653 }
97919654
9792 fn unionFieldPtr(
9793 self: *FuncGen,
9794 inst: Air.Inst.Index,
9795 union_ptr: *llvm.Value,
9796 union_ty: Type,
9797 ) !?*llvm.Value {
9798 const target = self.dg.module.getTarget();
9799 const layout = union_ty.unionGetLayout(target);
9800 const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
9801 if (layout.payload_size == 0) {
9802 return self.builder.buildBitCast(union_ptr, result_llvm_ty, "");
9803 }
9804 if (union_ty.containerLayout() == .Packed) {
9805 return self.builder.buildBitCast(union_ptr, result_llvm_ty, "");
9806 }
9807 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9808 const union_llvm_ty = try self.dg.lowerType(union_ty);
9809 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, union_ptr, payload_index, "");
9810 return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
9811 }
9812
98139655 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
98149656 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
98159657 assert(id != 0);
......@@ -9828,13 +9670,12 @@ pub const FuncGen = struct {
98289670 const target = fg.dg.module.getTarget();
98299671 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
98309672 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9831 const llvm_ptr_u8 = fg.context.intType(8).pointerType(0);
98329673 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);
98339674 const size_bytes = pointee_type.abiSize(target);
98349675 _ = fg.builder.buildMemCpy(
9835 fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""),
9676 result_ptr,
98369677 result_align,
9837 fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""),
9678 ptr,
98389679 ptr_alignment,
98399680 llvm_usize.constInt(size_bytes, .False),
98409681 is_volatile,
......@@ -9855,7 +9696,7 @@ pub const FuncGen = struct {
98559696
98569697 assert(info.vector_index != .runtime);
98579698 if (info.vector_index != .none) {
9858 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9699 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
98599700 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);
98609701 const vec_ty = vec_elem_ty.vectorType(info.host_size);
98619702
......@@ -9878,8 +9719,7 @@ pub const FuncGen = struct {
98789719 }
98799720
98809721 const int_elem_ty = self.context.intType(info.host_size * 8);
9881 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
9882 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
9722 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
98839723 containing_int.setAlignment(ptr_alignment);
98849724 containing_int.setVolatile(ptr_volatile);
98859725
......@@ -9894,8 +9734,7 @@ pub const FuncGen = struct {
98949734
98959735 const same_size_int = self.context.intType(elem_bits);
98969736 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
9897 const bitcasted_ptr = self.builder.buildBitCast(result_ptr, same_size_int.pointerType(0), "");
9898 const store_inst = self.builder.buildStore(truncated_int, bitcasted_ptr);
9737 const store_inst = self.builder.buildStore(truncated_int, result_ptr);
98999738 store_inst.setAlignment(result_align);
99009739 return result_ptr;
99019740 }
......@@ -9933,7 +9772,7 @@ pub const FuncGen = struct {
99339772
99349773 assert(info.vector_index != .runtime);
99359774 if (info.vector_index != .none) {
9936 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9775 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
99379776 const vec_elem_ty = try self.dg.lowerType(elem_ty);
99389777 const vec_ty = vec_elem_ty.vectorType(info.host_size);
99399778
......@@ -9952,8 +9791,7 @@ pub const FuncGen = struct {
99529791
99539792 if (info.host_size != 0) {
99549793 const int_elem_ty = self.context.intType(info.host_size * 8);
9955 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");
9956 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
9794 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
99579795 assert(ordering == .NotAtomic);
99589796 containing_int.setAlignment(ptr_alignment);
99599797 containing_int.setVolatile(ptr_volatile);
......@@ -9978,7 +9816,7 @@ pub const FuncGen = struct {
99789816 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");
99799817 const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, "");
99809818
9981 const store_inst = self.builder.buildStore(ored_value, int_ptr);
9819 const store_inst = self.builder.buildStore(ored_value, ptr);
99829820 assert(ordering == .NotAtomic);
99839821 store_inst.setAlignment(ptr_alignment);
99849822 store_inst.setVolatile(ptr_volatile);
......@@ -9992,12 +9830,11 @@ pub const FuncGen = struct {
99929830 return;
99939831 }
99949832 assert(ordering == .NotAtomic);
9995 const llvm_ptr_u8 = self.context.intType(8).pointerType(0);
99969833 const size_bytes = elem_ty.abiSize(target);
99979834 _ = self.builder.buildMemCpy(
9998 self.builder.buildBitCast(ptr, llvm_ptr_u8, ""),
9835 ptr,
99999836 ptr_alignment,
10000 self.builder.buildBitCast(elem, llvm_ptr_u8, ""),
9837 elem,
100019838 elem_ty.abiAlignment(target),
100029839 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),
100039840 info.@"volatile",
......@@ -11187,6 +11024,7 @@ fn compilerRtIntBits(bits: u16) u16 {
1118711024}
1118811025
1118911026fn buildAllocaInner(
11027 context: *llvm.Context,
1119011028 builder: *llvm.Builder,
1119111029 llvm_func: *llvm.Value,
1119211030 di_scope_non_null: bool,
......@@ -11224,7 +11062,7 @@ fn buildAllocaInner(
1122411062 // The pointer returned from this function should have the generic address space,
1122511063 // if this isn't the case then cast it to the generic address space.
1122611064 if (address_space != llvm.address_space.default) {
11227 return builder.buildAddrSpaceCast(alloca, llvm_ty.pointerType(llvm.address_space.default), "");
11065 return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), "");
1122811066 }
1122911067
1123011068 return alloca;
src/codegen/llvm/bindings.zig-3
......@@ -287,9 +287,6 @@ pub const Type = opaque {
287287 pub const getUndef = LLVMGetUndef;
288288 extern fn LLVMGetUndef(Ty: *Type) *Value;
289289
290 pub const pointerType = LLVMPointerType;
291 extern fn LLVMPointerType(ElementType: *Type, AddressSpace: c_uint) *Type;
292
293290 pub const arrayType = LLVMArrayType;
294291 extern fn LLVMArrayType(ElementType: *Type, ElementCount: c_uint) *Type;
295292