authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-27 04:57:01-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-27 04:57:01-05:00
log3a7a39cb913387c997ed457535e53ca054d2465d
treecf2798c2ada2b1901f6e2129ea45c6566c40febe
parent1b86a628acef7bc180ea6cbe6e4930710e5dff97
parent81318e870418d017244d6d133aabca19f2c63b58
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14078 from jacobly0/llvm-opaque-ptrs

llvm: remove unnecessary code for opaque pointers

3 files changed, 183 insertions(+), 330 deletions(-)

src/codegen/llvm.zig+169-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);
......@@ -1938,6 +1928,7 @@ pub const Object = struct {
19381928 if (ty.castTag(.@"struct")) |payload| {
19391929 const struct_obj = payload.data;
19401930 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
1931 assert(struct_obj.haveLayout());
19411932 const info = struct_obj.backing_int_ty.intInfo(target);
19421933 const dwarf_encoding: c_uint = switch (info.signedness) {
19431934 .signed => DW.ATE.signed,
......@@ -2477,12 +2468,8 @@ pub const DeclGen = struct {
24772468 new_global.setAlignment(global.getAlignment());
24782469 if (decl.@"linksection") |section| new_global.setSection(section);
24792470 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.
24832471 // 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);
2472 global.replaceAllUsesWith(new_global);
24862473 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
24872474 new_global.takeName(global);
24882475 global.deleteGlobal();
......@@ -2781,11 +2768,7 @@ pub const DeclGen = struct {
27812768 }
27822769 const ptr_info = t.ptrInfo().data;
27832770 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);
2771 return dg.context.pointerType(llvm_addrspace);
27892772 },
27902773 .Opaque => switch (t.tag()) {
27912774 .@"opaque" => {
......@@ -2949,6 +2932,7 @@ pub const DeclGen = struct {
29492932 const struct_obj = t.castTag(.@"struct").?.data;
29502933
29512934 if (struct_obj.layout == .Packed) {
2935 assert(struct_obj.haveLayout());
29522936 const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty);
29532937 gop.value_ptr.* = int_llvm_ty;
29542938 return int_llvm_ty;
......@@ -3108,8 +3092,7 @@ pub const DeclGen = struct {
31083092 defer llvm_params.deinit();
31093093
31103094 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));
3095 try llvm_params.append(dg.context.pointerType(0));
31133096 }
31143097
31153098 if (fn_info.return_type.isError() and
......@@ -3131,9 +3114,7 @@ pub const DeclGen = struct {
31313114 try llvm_params.append(try dg.lowerType(param_ty));
31323115 },
31333116 .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));
3117 try llvm_params.append(dg.context.pointerType(0));
31373118 },
31383119 .abi_sized_int => {
31393120 const param_ty = fn_info.param_types[it.zig_index - 1];
......@@ -3323,16 +3304,12 @@ pub const DeclGen = struct {
33233304 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
33243305 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
33253306
3326 const llvm_var_type = try dg.lowerType(tv.ty);
3327 const llvm_actual_ptr_type = llvm_var_type.pointerType(llvm_actual_addrspace);
3328
33293307 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;
3308 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
3309 val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace))
3310 else
3311 val;
3312 return addrspace_casted_ptr;
33363313 },
33373314 .slice => {
33383315 const slice = tv.val.castTag(.slice).?.data;
......@@ -3355,7 +3332,7 @@ pub const DeclGen = struct {
33553332 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
33563333 },
33573334 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
3358 return dg.lowerParentPtr(tv.val, tv.ty.childType());
3335 return dg.lowerParentPtr(tv.val);
33593336 },
33603337 .null_value, .zero => {
33613338 const llvm_type = try dg.lowerType(tv.ty);
......@@ -3363,7 +3340,7 @@ pub const DeclGen = struct {
33633340 },
33643341 .opt_payload => {
33653342 const payload = tv.val.castTag(.opt_payload).?.data;
3366 return dg.lowerParentPtr(payload, tv.ty);
3343 return dg.lowerParentPtr(payload);
33673344 },
33683345 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
33693346 tv.ty.fmtDebug(), tag,
......@@ -3657,6 +3634,7 @@ pub const DeclGen = struct {
36573634 const struct_obj = tv.ty.castTag(.@"struct").?.data;
36583635
36593636 if (struct_obj.layout == .Packed) {
3637 assert(struct_obj.haveLayout());
36603638 const big_bits = struct_obj.backing_int_ty.bitSize(target);
36613639 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));
36623640 const fields = struct_obj.fields.values();
......@@ -3940,7 +3918,6 @@ pub const DeclGen = struct {
39403918 dg: *DeclGen,
39413919 ptr_val: Value,
39423920 decl_index: Module.Decl.Index,
3943 ptr_child_ty: Type,
39443921 ) Error!*llvm.Value {
39453922 const decl = dg.module.declPtr(decl_index);
39463923 dg.module.markDeclAlive(decl);
......@@ -3949,62 +3926,54 @@ pub const DeclGen = struct {
39493926 .data = decl.ty,
39503927 };
39513928 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 }
3929 return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
39593930 }
39603931
3961 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value {
3932 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value {
39623933 const target = dg.module.getTarget();
3963 var bitcast_needed: bool = undefined;
3964 const llvm_ptr = switch (ptr_val.tag()) {
3934 switch (ptr_val.tag()) {
39653935 .decl_ref_mut => {
39663936 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
3967 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3937 return dg.lowerParentPtrDecl(ptr_val, decl);
39683938 },
39693939 .decl_ref => {
39703940 const decl = ptr_val.castTag(.decl_ref).?.data;
3971 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3941 return dg.lowerParentPtrDecl(ptr_val, decl);
39723942 },
39733943 .variable => {
39743944 const decl = ptr_val.castTag(.variable).?.data.owner_decl;
3975 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);
3945 return dg.lowerParentPtrDecl(ptr_val, decl);
39763946 },
39773947 .int_i64 => {
39783948 const int = ptr_val.castTag(.int_i64).?.data;
39793949 const llvm_usize = try dg.lowerType(Type.usize);
39803950 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);
3981 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));
3951 return llvm_int.constIntToPtr(dg.context.pointerType(0));
39823952 },
39833953 .int_u64 => {
39843954 const int = ptr_val.castTag(.int_u64).?.data;
39853955 const llvm_usize = try dg.lowerType(Type.usize);
39863956 const llvm_int = llvm_usize.constInt(int, .False);
3987 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));
3957 return llvm_int.constIntToPtr(dg.context.pointerType(0));
39883958 },
3989 .field_ptr => blk: {
3959 .field_ptr => {
39903960 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);
3961 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr);
39923962 const parent_ty = field_ptr.container_ty;
39933963
39943964 const field_index = @intCast(u32, field_ptr.field_index);
39953965 const llvm_u32 = dg.context.intType(32);
39963966 switch (parent_ty.zigTypeTag()) {
39973967 .Union => {
3998 bitcast_needed = true;
39993968 if (parent_ty.containerLayout() == .Packed) {
4000 break :blk parent_llvm_ptr;
3969 return parent_llvm_ptr;
40013970 }
40023971
40033972 const layout = parent_ty.unionGetLayout(target);
40043973 if (layout.payload_size == 0) {
40053974 // In this case a pointer to the union and a pointer to any
40063975 // (void) payload is the same.
4007 break :blk parent_llvm_ptr;
3976 return parent_llvm_ptr;
40083977 }
40093978 const llvm_pl_index = if (layout.tag_size == 0)
40103979 0
......@@ -4015,10 +3984,9 @@ pub const DeclGen = struct {
40153984 llvm_u32.constInt(llvm_pl_index, .False),
40163985 };
40173986 const parent_llvm_ty = try dg.lowerType(parent_ty);
4018 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
3987 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40193988 },
40203989 .Struct => {
4021 const field_ty = parent_ty.structFieldType(field_index);
40223990 if (parent_ty.containerLayout() == .Packed) {
40233991 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
40243992 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
......@@ -4033,26 +4001,23 @@ pub const DeclGen = struct {
40334001 };
40344002 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
40354003 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);
4004 const final_llvm_ty = dg.context.pointerType(0);
4005 return field_addr.constIntToPtr(final_llvm_ty);
40394006 }
40404007
40414008 var ty_buf: Type.Payload.Pointer = undefined;
40424009
40434010 const parent_llvm_ty = try dg.lowerType(parent_ty);
40444011 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {
4045 bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
40464012 const indices: [2]*llvm.Value = .{
40474013 llvm_u32.constInt(0, .False),
40484014 llvm_u32.constInt(llvm_field_index, .False),
40494015 };
4050 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4016 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40514017 } else {
4052 bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module);
40534018 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);
40544019 const indices: [1]*llvm.Value = .{llvm_index};
4055 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4020 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40564021 }
40574022 },
40584023 .Pointer => {
......@@ -4062,37 +4027,34 @@ pub const DeclGen = struct {
40624027 llvm_u32.constInt(field_index, .False),
40634028 };
40644029 const parent_llvm_ty = try dg.lowerType(parent_ty);
4065 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4030 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40664031 },
40674032 else => unreachable,
40684033 }
40694034 },
4070 .elem_ptr => blk: {
4035 .elem_ptr => {
40714036 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);
4037 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr);
40744038
40754039 const llvm_usize = try dg.lowerType(Type.usize);
40764040 const indices: [1]*llvm.Value = .{
40774041 llvm_usize.constInt(elem_ptr.index, .False),
40784042 };
40794043 const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);
4080 break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4044 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
40814045 },
4082 .opt_payload_ptr => blk: {
4046 .opt_payload_ptr => {
40834047 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);
4048 const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr);
40854049 var buf: Type.Payload.ElemType = undefined;
40864050
40874051 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
4088 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4089
40904052 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
40914053 payload_ty.optionalReprIsPayload())
40924054 {
40934055 // In this case, we represent pointer to optional the same as pointer
40944056 // to the payload.
4095 break :blk parent_llvm_ptr;
4057 return parent_llvm_ptr;
40964058 }
40974059
40984060 const llvm_u32 = dg.context.intType(32);
......@@ -4101,19 +4063,17 @@ pub const DeclGen = struct {
41014063 llvm_u32.constInt(0, .False),
41024064 };
41034065 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);
4066 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41054067 },
4106 .eu_payload_ptr => blk: {
4068 .eu_payload_ptr => {
41074069 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);
4070 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr);
41094071
41104072 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4111 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4112
41134073 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
41144074 // In this case, we represent pointer to error union the same as pointer
41154075 // to the payload.
4116 break :blk parent_llvm_ptr;
4076 return parent_llvm_ptr;
41174077 }
41184078
41194079 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;
......@@ -4123,14 +4083,9 @@ pub const DeclGen = struct {
41234083 llvm_u32.constInt(payload_offset, .False),
41244084 };
41254085 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);
4086 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
41274087 },
41284088 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;
41344089 }
41354090 }
41364091
......@@ -4189,8 +4144,7 @@ pub const DeclGen = struct {
41894144 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
41904145 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
41914146 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);
4147 const llvm_decl_wanted_ptr_ty = self.context.pointerType(llvm_wanted_addrspace);
41944148 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
41954149 } else llvm_decl_val;
41964150
......@@ -4471,18 +4425,11 @@ pub const FuncGen = struct {
44714425 global.setGlobalConstant(.True);
44724426 global.setUnnamedAddr(.True);
44734427 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)
4428 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
4429 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))
44834430 else
4484 bitcasted_ptr;
4485 return casted_ptr;
4431 global;
4432 return addrspace_casted_ptr;
44864433 }
44874434
44884435 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
......@@ -4770,17 +4717,7 @@ pub const FuncGen = struct {
47704717 load_inst.setAlignment(alignment);
47714718 try llvm_args.append(load_inst);
47724719 } 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 }
4720 try llvm_args.append(llvm_arg);
47844721 }
47854722 },
47864723 .byref => {
......@@ -4824,26 +4761,22 @@ pub const FuncGen = struct {
48244761 const param_ty = self.air.typeOf(arg);
48254762 const llvm_arg = try self.resolveInst(arg);
48264763 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);
4764 const int_llvm_ty = self.context.intType(abi_size * 8);
48294765
48304766 if (isByRef(param_ty)) {
48314767 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, "");
4768 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");
48344769 load_inst.setAlignment(alignment);
48354770 try llvm_args.append(load_inst);
48364771 } else {
48374772 // LLVM does not allow bitcasting structs so we must allocate
4838 // a local, bitcast its pointer, store, and then load.
4773 // a local, store as one type, and then load as another type.
48394774 const alignment = @max(
48404775 param_ty.abiAlignment(target),
48414776 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
48424777 );
48434778 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);
4779 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
48474780 store_inst.setAlignment(alignment);
48484781 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
48494782 load_inst.setAlignment(alignment);
......@@ -4872,12 +4805,11 @@ pub const FuncGen = struct {
48724805 break :p p;
48734806 };
48744807
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), "");
4808 const llvm_ty = self.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);
48774809 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
48784810 for (llvm_types) |field_ty, i_usize| {
48794811 const i = @intCast(c_uint, i_usize);
4880 const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, "");
4812 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");
48814813 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");
48824814 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
48834815 llvm_args.appendAssumeCapacity(load_inst);
......@@ -4886,7 +4818,7 @@ pub const FuncGen = struct {
48864818 .as_u16 => {
48874819 const arg = args[it.zig_index - 1];
48884820 const llvm_arg = try self.resolveInst(arg);
4889 const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), "");
4821 const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), "");
48904822 try llvm_args.append(casted);
48914823 },
48924824 .float_array => |count| {
......@@ -4903,9 +4835,8 @@ pub const FuncGen = struct {
49034835 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);
49044836 const array_llvm_ty = float_ty.arrayType(count);
49054837
4906 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
49074838 const alignment = arg_ty.abiAlignment(target);
4908 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");
4839 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49094840 load_inst.setAlignment(alignment);
49104841 try llvm_args.append(load_inst);
49114842 },
......@@ -4921,10 +4852,9 @@ pub const FuncGen = struct {
49214852 llvm_arg = store_inst;
49224853 }
49234854
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), "");
4855 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);
49264856 const alignment = arg_ty.abiAlignment(target);
4927 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");
4857 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
49284858 load_inst.setAlignment(alignment);
49294859 try llvm_args.append(load_inst);
49304860 },
......@@ -5028,12 +4958,10 @@ pub const FuncGen = struct {
50284958 if (abi_ret_ty != llvm_ret_ty) {
50294959 // In this case the function return type is honoring the calling convention by having
50304960 // 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.
4961 // by using our canonical type, then loading it if necessary.
50324962 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);
50334963 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);
4964 const store_inst = self.builder.buildStore(call, rp);
50374965 store_inst.setAlignment(alignment);
50384966 if (isByRef(return_type)) {
50394967 return rp;
......@@ -5086,7 +5014,6 @@ pub const FuncGen = struct {
50865014 }
50875015
50885016 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5089 const ptr_abi_ty = abi_ret_ty.pointerType(0);
50905017 const operand = try self.resolveInst(un_op);
50915018 const target = self.dg.module.getTarget();
50925019 const alignment = ret_ty.abiAlignment(target);
......@@ -5094,8 +5021,7 @@ pub const FuncGen = struct {
50945021 if (isByRef(ret_ty)) {
50955022 // operand is a pointer however self.ret_ptr is null so that means
50965023 // 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, "");
5024 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");
50995025 load_inst.setAlignment(alignment);
51005026 _ = self.builder.buildRet(load_inst);
51015027 return null;
......@@ -5110,8 +5036,7 @@ pub const FuncGen = struct {
51105036 const rp = self.buildAlloca(llvm_ret_ty, alignment);
51115037 const store_inst = self.builder.buildStore(operand, rp);
51125038 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, "");
5039 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");
51155040 load_inst.setAlignment(alignment);
51165041 _ = self.builder.buildRet(load_inst);
51175042 return null;
......@@ -5141,12 +5066,7 @@ pub const FuncGen = struct {
51415066 const ptr = try self.resolveInst(un_op);
51425067 const target = self.dg.module.getTarget();
51435068 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, "");
5069 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
51505070 loaded.setAlignment(ret_ty.abiAlignment(target));
51515071 _ = self.builder.buildRet(loaded);
51525072 return null;
......@@ -5178,8 +5098,8 @@ pub const FuncGen = struct {
51785098 const llvm_fn_name = "llvm.va_copy";
51795099 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
51805100 const param_types = [_]*llvm.Type{
5181 self.dg.context.intType(8).pointerType(0),
5182 self.dg.context.intType(8).pointerType(0),
5101 self.context.pointerType(0),
5102 self.context.pointerType(0),
51835103 };
51845104 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
51855105 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
......@@ -5203,7 +5123,7 @@ pub const FuncGen = struct {
52035123
52045124 const llvm_fn_name = "llvm.va_end";
52055125 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)};
5126 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
52075127 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
52085128 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
52095129 };
......@@ -5224,7 +5144,7 @@ pub const FuncGen = struct {
52245144
52255145 const llvm_fn_name = "llvm.va_start";
52265146 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)};
5147 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
52285148 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
52295149 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
52305150 };
......@@ -5417,7 +5337,7 @@ pub const FuncGen = struct {
54175337 // of function pointers, however the phi makes it a runtime value and therefore
54185338 // the LLVM type has to be wrapped in a pointer.
54195339 if (is_body or isByRef(inst_ty)) {
5420 break :ty raw_llvm_ty.pointerType(0);
5340 break :ty self.context.pointerType(0);
54215341 }
54225342 break :ty raw_llvm_ty;
54235343 };
......@@ -5482,7 +5402,7 @@ pub const FuncGen = struct {
54825402 const payload_ty = self.air.typeOfIndex(inst);
54835403 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
54845404 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);
5405 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
54865406 }
54875407
54885408 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
......@@ -5491,9 +5411,8 @@ pub const FuncGen = struct {
54915411 const err_union_ptr = try self.resolveInst(extra.data.ptr);
54925412 const body = self.air.extra[extra.end..][0..extra.data.body_len];
54935413 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
5494 const payload_ty = self.air.typeOfIndex(inst);
54955414 const is_unused = self.liveness.isUnused(inst);
5496 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty);
5415 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);
54975416 }
54985417
54995418 fn lowerTry(
......@@ -5504,7 +5423,6 @@ pub const FuncGen = struct {
55045423 operand_is_ptr: bool,
55055424 can_elide_load: bool,
55065425 is_unused: bool,
5507 result_ty: Type,
55085426 ) !?*llvm.Value {
55095427 const payload_ty = err_union_ty.errorUnionPayload();
55105428 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
......@@ -5547,12 +5465,7 @@ pub const FuncGen = struct {
55475465 return null;
55485466 }
55495467 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, "");
5468 return if (operand_is_ptr) err_union else null;
55565469 }
55575470 const offset = errUnionPayloadOffset(payload_ty, target);
55585471 if (operand_is_ptr) {
......@@ -6038,9 +5951,8 @@ pub const FuncGen = struct {
60385951 const union_llvm_ty = try self.dg.lowerType(struct_ty);
60395952 const layout = struct_ty.unionGetLayout(target);
60405953 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, "");
5954 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
60425955 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), "");
60445956 if (isByRef(field_ty)) {
60455957 if (canElideLoad(self, body_tail))
60465958 return field_ptr;
......@@ -6068,7 +5980,7 @@ pub const FuncGen = struct {
60685980
60695981 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
60705982 if (field_offset == 0) {
6071 return self.builder.buildBitCast(field_ptr, res_ty, "");
5983 return field_ptr;
60725984 }
60735985 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
60745986
......@@ -6635,7 +6547,7 @@ pub const FuncGen = struct {
66356547 self.builder.buildLoad(optional_llvm_ty, operand, "")
66366548 else
66376549 operand;
6638 const llvm_i8 = self.dg.context.intType(8);
6550 const llvm_i8 = self.context.intType(8);
66396551 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
66406552 }
66416553
......@@ -6701,16 +6613,12 @@ pub const FuncGen = struct {
67016613 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67026614 const operand = try self.resolveInst(ty_op.operand);
67036615 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6704 const result_ty = self.air.getRefType(ty_op.ty);
67056616 var buf: Type.Payload.ElemType = undefined;
67066617 const payload_ty = optional_ty.optionalChild(&buf);
67076618 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
67086619 // We have a pointer to a zero-bit value and we need to return
67096620 // 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, "");
6621 return operand;
67146622 }
67156623 if (optional_ty.optionalReprIsPayload()) {
67166624 // The payload and the optional are the same value.
......@@ -6726,17 +6634,13 @@ pub const FuncGen = struct {
67266634 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
67276635 const operand = try self.resolveInst(ty_op.operand);
67286636 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6729 const result_ty = self.air.getRefType(ty_op.ty);
67306637 var buf: Type.Payload.ElemType = undefined;
67316638 const payload_ty = optional_ty.optionalChild(&buf);
67326639 const non_null_bit = self.context.intType(8).constInt(1, .False);
67336640 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
67346641 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
67356642 _ = 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, "");
6643 return operand;
67406644 }
67416645 if (optional_ty.optionalReprIsPayload()) {
67426646 // The payload and the optional are the same value.
......@@ -6794,11 +6698,7 @@ pub const FuncGen = struct {
67946698 const target = self.dg.module.getTarget();
67956699
67966700 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, "");
6701 return if (operand_is_ptr) operand else null;
68026702 }
68036703 const offset = errUnionPayloadOffset(payload_ty, target);
68046704 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
......@@ -6834,7 +6734,7 @@ pub const FuncGen = struct {
68346734 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
68356735 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
68366736 if (operand_is_ptr) {
6837 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");
6737 return operand;
68386738 } else {
68396739 return err_llvm_ty.constInt(0, .False);
68406740 }
......@@ -7104,14 +7004,8 @@ pub const FuncGen = struct {
71047004 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
71057005
71067006 // 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, "");
7007 // but `ptr` is pointing to the global directly.
7008 const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), ptr, 0, "");
71157009 return self.builder.buildInsertValue(partial, len, 1, "");
71167010 }
71177011
......@@ -7636,7 +7530,7 @@ pub const FuncGen = struct {
76367530 .neg => {
76377531 // In this case we can generate a softfloat negation by XORing the
76387532 // bits with a constant.
7639 const int_llvm_ty = self.dg.context.intType(float_bits);
7533 const int_llvm_ty = self.context.intType(float_bits);
76407534 const one = int_llvm_ty.constInt(1, .False);
76417535 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
76427536 const sign_mask = one.constShl(shift_amt);
......@@ -8045,8 +7939,8 @@ pub const FuncGen = struct {
80457939 const target = self.dg.module.getTarget();
80467940
80477941 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), "");
7942 // They are both pointers, so just return the same opaque pointer :)
7943 return operand;
80507944 }
80517945
80527946 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
......@@ -8061,9 +7955,7 @@ pub const FuncGen = struct {
80617955 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
80627956 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
80637957 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);
7958 const llvm_store = self.builder.buildStore(operand, array_ptr);
80677959 llvm_store.setAlignment(inst_ty.abiAlignment(target));
80687960 } else {
80697961 // If the ABI size of the element type is not evenly divisible by size in bits;
......@@ -8092,9 +7984,7 @@ pub const FuncGen = struct {
80927984
80937985 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
80947986 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, "");
7987 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");
80987988 // The array is aligned to the element's alignment, while the vector might have a completely
80997989 // different alignment. This means we need to enforce the alignment of this load.
81007990 vector.setAlignment(elem_ty.abiAlignment(target));
......@@ -8124,20 +8014,15 @@ pub const FuncGen = struct {
81248014 }
81258015
81268016 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, "");
8017 const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, "");
81308018 load_inst.setAlignment(operand_ty.abiAlignment(target));
81318019 return load_inst;
81328020 }
81338021
81348022 if (result_is_ref) {
8135 // Bitcast the result pointer, then store.
81368023 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
81378024 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);
8025 const store_inst = self.builder.buildStore(operand, result_ptr);
81418026 store_inst.setAlignment(alignment);
81428027 return result_ptr;
81438028 }
......@@ -8145,12 +8030,10 @@ pub const FuncGen = struct {
81458030 if (llvm_dest_ty.getTypeKind() == .Struct) {
81468031 // Both our operand and our result are values, not pointers,
81478032 // but LLVM won't let us bitcast struct values.
8148 // Therefore, we store operand to bitcasted alloca, then load for result.
8033 // Therefore, we store operand to alloca, then load for result.
81498034 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
81508035 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);
8036 const store_inst = self.builder.buildStore(operand, result_ptr);
81548037 store_inst.setAlignment(alignment);
81558038 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
81568039 load_inst.setAlignment(alignment);
......@@ -8248,7 +8131,7 @@ pub const FuncGen = struct {
82488131 /// Use this instead of builder.buildAlloca, because this function makes sure to
82498132 /// put the alloca instruction at the top of the function!
82508133 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());
8134 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());
82528135 }
82538136
82548137 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
......@@ -8282,13 +8165,11 @@ pub const FuncGen = struct {
82828165 const target = self.dg.module.getTarget();
82838166 const operand_size = operand_ty.abiSize(target);
82848167 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, "");
82878168 const fill_char = u8_llvm_ty.constInt(0xaa, .False);
82888169 const dest_ptr_align = ptr_ty.ptrAlignment(target);
82898170 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
82908171 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());
8172 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
82928173 if (self.dg.module.comp.bin_file.options.valgrind) {
82938174 self.valgrindMarkUndef(dest_ptr, len);
82948175 }
......@@ -8365,7 +8246,7 @@ pub const FuncGen = struct {
83658246 const llvm_i32 = self.context.intType(32);
83668247 const llvm_fn_name = "llvm.frameaddress.p0";
83678248 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8368 const llvm_p0i8 = self.context.intType(8).pointerType(0);
8249 const llvm_p0i8 = self.context.pointerType(0);
83698250 const param_types = [_]*llvm.Type{llvm_i32};
83708251 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);
83718252 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
......@@ -8388,14 +8269,13 @@ pub const FuncGen = struct {
83888269 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
83898270 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
83908271 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8391 var ptr = try self.resolveInst(extra.ptr);
8272 const ptr = try self.resolveInst(extra.ptr);
83928273 var expected_value = try self.resolveInst(extra.expected_value);
83938274 var new_value = try self.resolveInst(extra.new_value);
83948275 const operand_ty = self.air.typeOf(extra.ptr).elemType();
83958276 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
83968277 if (opt_abi_ty) |abi_ty| {
83978278 // operand needs widening and truncating
8398 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
83998279 if (operand_ty.isSignedInt()) {
84008280 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
84018281 new_value = self.builder.buildSExt(new_value, abi_ty, "");
......@@ -8447,7 +8327,6 @@ pub const FuncGen = struct {
84478327 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);
84488328 if (opt_abi_ty) |abi_ty| {
84498329 // operand needs widening and truncating or bitcasting.
8450 const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
84518330 const casted_operand = if (is_float)
84528331 self.builder.buildBitCast(operand, abi_ty, "")
84538332 else if (is_signed_int)
......@@ -8457,7 +8336,7 @@ pub const FuncGen = struct {
84578336
84588337 const uncasted_result = self.builder.buildAtomicRmw(
84598338 op,
8460 casted_ptr,
8339 ptr,
84618340 casted_operand,
84628341 ordering,
84638342 single_threaded,
......@@ -8476,11 +8355,10 @@ pub const FuncGen = struct {
84768355
84778356 // It's a pointer but we need to treat it as an int.
84788357 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8479 const casted_ptr = self.builder.buildBitCast(ptr, usize_llvm_ty.pointerType(0), "");
84808358 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
84818359 const uncasted_result = self.builder.buildAtomicRmw(
84828360 op,
8483 casted_ptr,
8361 ptr,
84848362 casted_operand,
84858363 ordering,
84868364 single_threaded,
......@@ -8508,8 +8386,7 @@ pub const FuncGen = struct {
85088386
85098387 if (opt_abi_llvm_ty) |abi_llvm_ty| {
85108388 // 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, "");
8389 const load_inst = self.builder.buildLoad(abi_llvm_ty, ptr, "");
85138390 load_inst.setAlignment(ptr_alignment);
85148391 load_inst.setVolatile(ptr_volatile);
85158392 load_inst.setOrdering(ordering);
......@@ -8531,13 +8408,12 @@ pub const FuncGen = struct {
85318408 const ptr_ty = self.air.typeOf(bin_op.lhs);
85328409 const operand_ty = ptr_ty.childType();
85338410 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
8534 var ptr = try self.resolveInst(bin_op.lhs);
8411 const ptr = try self.resolveInst(bin_op.lhs);
85358412 var element = try self.resolveInst(bin_op.rhs);
85368413 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
85378414
85388415 if (opt_abi_ty) |abi_ty| {
85398416 // operand needs widening
8540 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
85418417 if (operand_ty.isSignedInt()) {
85428418 element = self.builder.buildSExt(element, abi_ty, "");
85438419 } else {
......@@ -8557,15 +8433,13 @@ pub const FuncGen = struct {
85578433 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;
85588434 const len = try self.resolveInst(extra.rhs);
85598435 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, "");
85628436 const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value;
85638437 const target = self.dg.module.getTarget();
85648438 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8565 _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8439 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
85668440
85678441 if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) {
8568 self.valgrindMarkUndef(dest_ptr_u8, len);
8442 self.valgrindMarkUndef(dest_ptr, len);
85698443 }
85708444 return null;
85718445 }
......@@ -8578,15 +8452,12 @@ pub const FuncGen = struct {
85788452 const src_ptr = try self.resolveInst(extra.lhs);
85798453 const src_ptr_ty = self.air.typeOf(extra.lhs);
85808454 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, "");
85848455 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
85858456 const target = self.dg.module.getTarget();
85868457 _ = self.builder.buildMemCpy(
8587 dest_ptr_u8,
8458 dest_ptr,
85888459 dest_ptr_ty.ptrAlignment(target),
8589 src_ptr_u8,
8460 src_ptr,
85908461 src_ptr_ty.ptrAlignment(target),
85918462 len,
85928463 is_volatile,
......@@ -8780,8 +8651,8 @@ pub const FuncGen = struct {
87808651 const error_set_ty = self.air.getRefType(ty_op.ty);
87818652
87828653 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");
8654 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
8655 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
87858656 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
87868657 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87878658
......@@ -8807,7 +8678,7 @@ pub const FuncGen = struct {
88078678
88088679 self.builder.positionBuilderAtEnd(end_block);
88098680
8810 const llvm_type = self.dg.context.intType(1);
8681 const llvm_type = self.context.intType(1);
88118682 const incoming_values: [2]*llvm.Value = .{
88128683 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
88138684 };
......@@ -8869,13 +8740,13 @@ pub const FuncGen = struct {
88698740 }
88708741 }
88718742
8872 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");
8743 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
88738744 self.builder.positionBuilderAtEnd(entry_block);
88748745 self.builder.clearCurrentDebugLocation();
88758746
88768747 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");
8748 const named_block = self.context.appendBasicBlock(fn_val, "Named");
8749 const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed");
88798750 const tag_int_value = fn_val.getParam(0);
88808751 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count()));
88818752
......@@ -8893,10 +8764,10 @@ pub const FuncGen = struct {
88938764 switch_instr.addCase(this_tag_int_value, named_block);
88948765 }
88958766 self.builder.positionBuilderAtEnd(named_block);
8896 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(1, .False));
8767 _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False));
88978768
88988769 self.builder.positionBuilderAtEnd(unnamed_block);
8899 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(0, .False));
8770 _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False));
89008771 return fn_val;
89018772 }
89028773
......@@ -8955,12 +8826,12 @@ pub const FuncGen = struct {
89558826 }
89568827 }
89578828
8958 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");
8829 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
89598830 self.builder.positionBuilderAtEnd(entry_block);
89608831 self.builder.clearCurrentDebugLocation();
89618832
89628833 const fields = enum_ty.enumFields();
8963 const bad_value_block = self.dg.context.appendBasicBlock(fn_val, "BadValue");
8834 const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue");
89648835 const tag_int_value = fn_val.getParam(0);
89658836 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count()));
89668837
......@@ -8969,7 +8840,7 @@ pub const FuncGen = struct {
89698840 };
89708841
89718842 for (fields.keys()) |name, field_index| {
8972 const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
8843 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
89738844 const str_init_llvm_ty = str_init.typeOf();
89748845 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
89758846 str_global.setInitializer(str_init);
......@@ -8990,7 +8861,7 @@ pub const FuncGen = struct {
89908861 slice_global.setUnnamedAddr(.True);
89918862 slice_global.setAlignment(slice_alignment);
89928863
8993 const return_block = self.dg.context.appendBasicBlock(fn_val, "Name");
8864 const return_block = self.context.appendBasicBlock(fn_val, "Name");
89948865 const this_tag_int_value = int: {
89958866 var tag_val_payload: Value.Payload.U32 = .{
89968867 .base = .{ .tag = .enum_field_index },
......@@ -9042,7 +8913,7 @@ pub const FuncGen = struct {
90428913 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
90438914
90448915 const error_name_table_ptr = try self.getErrorNameTable();
9045 const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0);
8916 const ptr_slice_llvm_ty = self.context.pointerType(0);
90468917 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");
90478918 const indices = [_]*llvm.Value{operand};
90488919 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
......@@ -9284,8 +9155,9 @@ pub const FuncGen = struct {
92849155 .Struct => {
92859156 if (result_ty.containerLayout() == .Packed) {
92869157 const struct_obj = result_ty.castTag(.@"struct").?.data;
9158 assert(struct_obj.haveLayout());
92879159 const big_bits = struct_obj.backing_int_ty.bitSize(target);
9288 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));
9160 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
92899161 const fields = struct_obj.fields.values();
92909162 comptime assert(Type.packed_struct_layout_version == 2);
92919163 var running_int: *llvm.Value = int_llvm_ty.constNull();
......@@ -9296,7 +9168,7 @@ pub const FuncGen = struct {
92969168
92979169 const non_int_val = try self.resolveInst(elem);
92989170 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9299 const small_int_ty = self.dg.context.intType(ty_bit_size);
9171 const small_int_ty = self.context.intType(ty_bit_size);
93009172 const small_int_val = if (field.ty.isPtrAtRuntime())
93019173 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
93029174 else
......@@ -9410,11 +9282,11 @@ pub const FuncGen = struct {
94109282
94119283 if (union_obj.layout == .Packed) {
94129284 const big_bits = union_ty.bitSize(target);
9413 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));
9285 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
94149286 const field = union_obj.fields.values()[extra.field_index];
94159287 const non_int_val = try self.resolveInst(extra.init);
94169288 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9417 const small_int_ty = self.dg.context.intType(ty_bit_size);
9289 const small_int_ty = self.context.intType(ty_bit_size);
94189290 const small_int_val = if (field.ty.isPtrAtRuntime())
94199291 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
94209292 else
......@@ -9444,9 +9316,9 @@ pub const FuncGen = struct {
94449316 }
94459317 assert(isByRef(union_ty));
94469318 // 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.
9319 // necessarily match the format that we need, depending on which tag is active.
9320 // We must construct the correct unnamed struct type here, in order to then set
9321 // the fields appropriately.
94509322 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);
94519323 const llvm_payload = try self.resolveInst(extra.init);
94529324 assert(union_obj.haveFieldTypes());
......@@ -9489,8 +9361,6 @@ pub const FuncGen = struct {
94899361 break :t self.context.structType(&fields, fields_len, .False);
94909362 };
94919363
9492 const casted_ptr = self.builder.buildBitCast(result_ptr, llvm_union_ty.pointerType(0), "");
9493
94949364 // Now we follow the layout as expressed above with GEP instructions to set the
94959365 // tag and the payload.
94969366 const index_type = self.context.intType(32);
......@@ -9510,7 +9380,7 @@ pub const FuncGen = struct {
95109380 index_type.constNull(),
95119381 };
95129382 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, "");
9383 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
95149384 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
95159385 return result_ptr;
95169386 }
......@@ -9522,7 +9392,7 @@ pub const FuncGen = struct {
95229392 index_type.constNull(),
95239393 };
95249394 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, "");
9395 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
95269396 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
95279397 }
95289398 {
......@@ -9530,7 +9400,7 @@ pub const FuncGen = struct {
95309400 index_type.constNull(),
95319401 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
95329402 };
9533 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, "");
9403 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
95349404 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
95359405 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
95369406 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
......@@ -9579,8 +9449,7 @@ pub const FuncGen = struct {
95799449 .data => {},
95809450 }
95819451
9582 const llvm_u8 = self.context.intType(8);
9583 const llvm_ptr_u8 = llvm_u8.pointerType(0);
9452 const llvm_ptr_u8 = self.context.pointerType(0);
95849453 const llvm_u32 = self.context.intType(32);
95859454
95869455 const llvm_fn_name = "llvm.prefetch.p0";
......@@ -9595,10 +9464,9 @@ pub const FuncGen = struct {
95959464 };
95969465
95979466 const ptr = try self.resolveInst(prefetch.ptr);
9598 const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, "");
95999467
96009468 const params = [_]*llvm.Value{
9601 ptr_u8,
9469 ptr,
96029470 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),
96039471 llvm_u32.constInt(prefetch.locality, .False),
96049472 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
......@@ -9625,8 +9493,7 @@ pub const FuncGen = struct {
96259493
96269494 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
96279495 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
9496 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
96309497
96319498 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
96329499 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
......@@ -9699,7 +9566,7 @@ pub const FuncGen = struct {
96999566 non_null_bit: *llvm.Value,
97009567 ) !?*llvm.Value {
97019568 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), "");
9569 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
97039570
97049571 if (isByRef(optional_ty)) {
97059572 const target = self.dg.module.getTarget();
......@@ -9740,31 +9607,24 @@ pub const FuncGen = struct {
97409607 .Packed => {
97419608 const result_ty = self.air.typeOfIndex(inst);
97429609 const result_ty_info = result_ty.ptrInfo().data;
9743 const result_llvm_ty = try self.dg.lowerType(result_ty);
97449610
97459611 if (result_ty_info.host_size != 0) {
97469612 // From LLVM's perspective, a pointer to a packed struct and a pointer
97479613 // to a field of a packed struct are the same. The difference is in the
97489614 // Zig pointer type which provides information for how to mask and shift
97499615 // 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, "");
9616 return struct_ptr;
97539617 }
97549618
97559619 // We have a pointer to a packed struct field that happens to be byte-aligned.
97569620 // Offset our operand pointer by the correct number of bytes.
97579621 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 }
9622 if (byte_offset == 0) return struct_ptr;
97619623 const byte_llvm_ty = self.context.intType(8);
9762 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
97639624 const llvm_usize = try self.dg.lowerType(Type.usize);
97649625 const llvm_index = llvm_usize.constInt(byte_offset, .False);
97659626 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, "");
9627 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
97689628 },
97699629 else => {
97709630 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
......@@ -9777,39 +9637,25 @@ pub const FuncGen = struct {
97779637 // end of the struct. Treat our struct pointer as an array of two and get
97789638 // the index to the element at index `1` to get a pointer to the end of
97799639 // the struct.
9780 const llvm_u32 = self.dg.context.intType(32);
9640 const llvm_u32 = self.context.intType(32);
97819641 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);
97829642 const indices: [1]*llvm.Value = .{llvm_index};
97839643 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
97849644 }
97859645 },
97869646 },
9787 .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty),
9647 .Union => {
9648 const layout = struct_ty.unionGetLayout(target);
9649 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;
9650 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9651 const union_llvm_ty = try self.dg.lowerType(struct_ty);
9652 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
9653 return union_field_ptr;
9654 },
97889655 else => unreachable,
97899656 }
97909657 }
97919658
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
98139659 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
98149660 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
98159661 assert(id != 0);
......@@ -9828,13 +9674,12 @@ pub const FuncGen = struct {
98289674 const target = fg.dg.module.getTarget();
98299675 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
98309676 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9831 const llvm_ptr_u8 = fg.context.intType(8).pointerType(0);
98329677 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);
98339678 const size_bytes = pointee_type.abiSize(target);
98349679 _ = fg.builder.buildMemCpy(
9835 fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""),
9680 result_ptr,
98369681 result_align,
9837 fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""),
9682 ptr,
98389683 ptr_alignment,
98399684 llvm_usize.constInt(size_bytes, .False),
98409685 is_volatile,
......@@ -9855,7 +9700,7 @@ pub const FuncGen = struct {
98559700
98569701 assert(info.vector_index != .runtime);
98579702 if (info.vector_index != .none) {
9858 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9703 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
98599704 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);
98609705 const vec_ty = vec_elem_ty.vectorType(info.host_size);
98619706
......@@ -9878,8 +9723,7 @@ pub const FuncGen = struct {
98789723 }
98799724
98809725 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, "");
9726 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
98839727 containing_int.setAlignment(ptr_alignment);
98849728 containing_int.setVolatile(ptr_volatile);
98859729
......@@ -9894,8 +9738,7 @@ pub const FuncGen = struct {
98949738
98959739 const same_size_int = self.context.intType(elem_bits);
98969740 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);
9741 const store_inst = self.builder.buildStore(truncated_int, result_ptr);
98999742 store_inst.setAlignment(result_align);
99009743 return result_ptr;
99019744 }
......@@ -9933,7 +9776,7 @@ pub const FuncGen = struct {
99339776
99349777 assert(info.vector_index != .runtime);
99359778 if (info.vector_index != .none) {
9936 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9779 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
99379780 const vec_elem_ty = try self.dg.lowerType(elem_ty);
99389781 const vec_ty = vec_elem_ty.vectorType(info.host_size);
99399782
......@@ -9952,8 +9795,7 @@ pub const FuncGen = struct {
99529795
99539796 if (info.host_size != 0) {
99549797 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, "");
9798 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
99579799 assert(ordering == .NotAtomic);
99589800 containing_int.setAlignment(ptr_alignment);
99599801 containing_int.setVolatile(ptr_volatile);
......@@ -9978,7 +9820,7 @@ pub const FuncGen = struct {
99789820 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");
99799821 const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, "");
99809822
9981 const store_inst = self.builder.buildStore(ored_value, int_ptr);
9823 const store_inst = self.builder.buildStore(ored_value, ptr);
99829824 assert(ordering == .NotAtomic);
99839825 store_inst.setAlignment(ptr_alignment);
99849826 store_inst.setVolatile(ptr_volatile);
......@@ -9992,12 +9834,11 @@ pub const FuncGen = struct {
99929834 return;
99939835 }
99949836 assert(ordering == .NotAtomic);
9995 const llvm_ptr_u8 = self.context.intType(8).pointerType(0);
99969837 const size_bytes = elem_ty.abiSize(target);
99979838 _ = self.builder.buildMemCpy(
9998 self.builder.buildBitCast(ptr, llvm_ptr_u8, ""),
9839 ptr,
99999840 ptr_alignment,
10000 self.builder.buildBitCast(elem, llvm_ptr_u8, ""),
9841 elem,
100019842 elem_ty.abiAlignment(target),
100029843 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),
100039844 info.@"volatile",
......@@ -11187,6 +11028,7 @@ fn compilerRtIntBits(bits: u16) u16 {
1118711028}
1118811029
1118911030fn buildAllocaInner(
11031 context: *llvm.Context,
1119011032 builder: *llvm.Builder,
1119111033 llvm_func: *llvm.Value,
1119211034 di_scope_non_null: bool,
......@@ -11224,7 +11066,7 @@ fn buildAllocaInner(
1122411066 // The pointer returned from this function should have the generic address space,
1122511067 // if this isn't the case then cast it to the generic address space.
1122611068 if (address_space != llvm.address_space.default) {
11227 return builder.buildAddrSpaceCast(alloca, llvm_ty.pointerType(llvm.address_space.default), "");
11069 return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), "");
1122811070 }
1122911071
1123011072 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
test/behavior/struct.zig+14
......@@ -1430,6 +1430,12 @@ test "struct has only one reference" {
14301430 fn errorUnionStructReturn() error{Foo}!struct { x: u8 } {
14311431 return error.Foo;
14321432 }
1433
1434 fn pointerPackedStruct(_: *packed struct { x: u8 }) void {}
1435 fn nestedPointerPackedStruct(_: struct { x: *packed struct { x: u8 } }) void {}
1436 fn pointerNestedPackedStruct(_: *struct { x: packed struct { x: u8 } }) void {}
1437 fn pointerNestedPointerPackedStruct(_: *struct { x: *packed struct { x: u8 } }) void {}
1438
14331439 fn optionalComptimeIntParam(comptime x: ?comptime_int) comptime_int {
14341440 return x.?;
14351441 }
......@@ -1446,6 +1452,14 @@ test "struct has only one reference" {
14461452 const error_union_struct_return: *const anyopaque = &S.errorUnionStructReturn;
14471453 try expect(optional_struct_return != error_union_struct_return);
14481454
1455 const pointer_packed_struct: *const anyopaque = &S.pointerPackedStruct;
1456 const nested_pointer_packed_struct: *const anyopaque = &S.nestedPointerPackedStruct;
1457 try expect(pointer_packed_struct != nested_pointer_packed_struct);
1458
1459 const pointer_nested_packed_struct: *const anyopaque = &S.pointerNestedPackedStruct;
1460 const pointer_nested_pointer_packed_struct: *const anyopaque = &S.pointerNestedPointerPackedStruct;
1461 try expect(pointer_nested_packed_struct != pointer_nested_pointer_packed_struct);
1462
14491463 try expectEqual(@alignOf(struct {}), S.optionalComptimeIntParam(@alignOf(struct {})));
14501464 try expectEqual(@alignOf(struct { x: u8 }), S.errorUnionComptimeIntParam(@alignOf(struct { x: u8 })));
14511465 try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 })));