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 {...@@ -582,7 +582,7 @@ pub const Object = struct {
582 const mod = self.module;582 const mod = self.module;
583 const target = mod.getTarget();583 const target = mod.getTarget();
584584
585 const llvm_ptr_ty = self.context.intType(8).pointerType(0); // TODO: Address space585 const llvm_ptr_ty = self.context.pointerType(0); // TODO: Address space
586 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());586 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
587 const type_fields = [_]*llvm.Type{587 const type_fields = [_]*llvm.Type{
588 llvm_ptr_ty,588 llvm_ptr_ty,
...@@ -608,7 +608,7 @@ pub const Object = struct {...@@ -608,7 +608,7 @@ pub const Object = struct {
608 str_global.setAlignment(1);608 str_global.setAlignment(1);
609609
610 const slice_fields = [_]*llvm.Value{610 const slice_fields = [_]*llvm.Value{
611 str_global.constBitCast(llvm_ptr_ty),611 str_global,
612 llvm_usize_ty.constInt(name.len, .False),612 llvm_usize_ty.constInt(name.len, .False),
613 };613 };
614 llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len);614 llvm_error.* = llvm_slice_ty.constNamedStruct(&slice_fields, slice_fields.len);
...@@ -623,7 +623,7 @@ pub const Object = struct {...@@ -623,7 +623,7 @@ pub const Object = struct {
623 error_name_table_global.setUnnamedAddr(.True);623 error_name_table_global.setUnnamedAddr(.True);
624 error_name_table_global.setAlignment(slice_alignment); // TODO: Dont hardcode624 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 space626 const error_name_table_ptr = error_name_table_global;
627 error_name_table_ptr_global.setInitializer(error_name_table_ptr);627 error_name_table_ptr_global.setInitializer(error_name_table_ptr);
628 }628 }
629629
...@@ -681,10 +681,9 @@ pub const Object = struct {...@@ -681,10 +681,9 @@ pub const Object = struct {
681 const other_global = object.getLlvmGlobal(decl.name) orelse continue;681 const other_global = object.getLlvmGlobal(decl.name) orelse continue;
682 if (other_global == llvm_global) continue;682 if (other_global == llvm_global) continue;
683683
684 const new_global_ptr = other_global.constBitCast(llvm_global.typeOf());684 llvm_global.replaceAllUsesWith(other_global);
685 llvm_global.replaceAllUsesWith(new_global_ptr);
686 deleteLlvmGlobal(llvm_global);685 deleteLlvmGlobal(llvm_global);
687 entry.value_ptr.* = new_global_ptr;686 entry.value_ptr.* = other_global;
688 }687 }
689 object.extern_collisions.clearRetainingCapacity();688 object.extern_collisions.clearRetainingCapacity();
690689
...@@ -703,11 +702,7 @@ pub const Object = struct {...@@ -703,11 +702,7 @@ pub const Object = struct {
703 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;702 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
704 if (other_global == llvm_global) continue;703 if (other_global == llvm_global) continue;
705704
706 // replaceAllUsesWith requires the type to be unchanged. So we bitcast705 other_global.replaceAllUsesWith(llvm_global);
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);
711 llvm_global.takeName(other_global);706 llvm_global.takeName(other_global);
712 deleteLlvmGlobal(other_global);707 deleteLlvmGlobal(other_global);
713 // Problem: now we need to replace in the decl_map that708 // Problem: now we need to replace in the decl_map that
...@@ -962,7 +957,7 @@ pub const Object = struct {...@@ -962,7 +957,7 @@ pub const Object = struct {
962 if (isByRef(param_ty)) {957 if (isByRef(param_ty)) {
963 const alignment = param_ty.abiAlignment(target);958 const alignment = param_ty.abiAlignment(target);
964 const param_llvm_ty = param.typeOf();959 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);
966 const store_inst = builder.buildStore(param, arg_ptr);961 const store_inst = builder.buildStore(param, arg_ptr);
967 store_inst.setAlignment(alignment);962 store_inst.setAlignment(alignment);
968 args.appendAssumeCapacity(arg_ptr);963 args.appendAssumeCapacity(arg_ptr);
...@@ -1020,14 +1015,12 @@ pub const Object = struct {...@@ -1020,14 +1015,12 @@ pub const Object = struct {
1020 const param_llvm_ty = try dg.lowerType(param_ty);1015 const param_llvm_ty = try dg.lowerType(param_ty);
1021 const abi_size = @intCast(c_uint, param_ty.abiSize(target));1016 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
1022 const int_llvm_ty = dg.context.intType(abi_size * 8);1017 const int_llvm_ty = dg.context.intType(abi_size * 8);
1023 const int_ptr_llvm_ty = int_llvm_ty.pointerType(0);
1024 const alignment = @max(1018 const alignment = @max(
1025 param_ty.abiAlignment(target),1019 param_ty.abiAlignment(target),
1026 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),1020 dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
1027 );1021 );
1028 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);1022 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1029 const casted_ptr = builder.buildBitCast(arg_ptr, int_ptr_llvm_ty, "");1023 const store_inst = builder.buildStore(param, arg_ptr);
1030 const store_inst = builder.buildStore(param, casted_ptr);
1031 store_inst.setAlignment(alignment);1024 store_inst.setAlignment(alignment);
10321025
1033 try args.ensureUnusedCapacity(1);1026 try args.ensureUnusedCapacity(1);
...@@ -1078,14 +1071,13 @@ pub const Object = struct {...@@ -1078,14 +1071,13 @@ pub const Object = struct {
1078 const param_ty = fn_info.param_types[it.zig_index - 1];1071 const param_ty = fn_info.param_types[it.zig_index - 1];
1079 const param_llvm_ty = try dg.lowerType(param_ty);1072 const param_llvm_ty = try dg.lowerType(param_ty);
1080 const param_alignment = param_ty.abiAlignment(target);1073 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);
1082 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);1075 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), "");
1084 for (field_types) |_, field_i_usize| {1076 for (field_types) |_, field_i_usize| {
1085 const field_i = @intCast(c_uint, field_i_usize);1077 const field_i = @intCast(c_uint, field_i_usize);
1086 const param = llvm_func.getParam(llvm_arg_i);1078 const param = llvm_func.getParam(llvm_arg_i);
1087 llvm_arg_i += 1;1079 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, "");
1089 const store_inst = builder.buildStore(param, field_ptr);1081 const store_inst = builder.buildStore(param, field_ptr);
1090 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);1082 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
1091 }1083 }
...@@ -1113,9 +1105,8 @@ pub const Object = struct {...@@ -1113,9 +1105,8 @@ pub const Object = struct {
1113 llvm_arg_i += 1;1105 llvm_arg_i += 1;
11141106
1115 const alignment = param_ty.abiAlignment(target);1107 const alignment = param_ty.abiAlignment(target);
1116 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);1108 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1117 const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), "");1109 _ = builder.buildStore(param, arg_ptr);
1118 _ = builder.buildStore(param, casted_ptr);
11191110
1120 if (isByRef(param_ty)) {1111 if (isByRef(param_ty)) {
1121 try args.append(arg_ptr);1112 try args.append(arg_ptr);
...@@ -1132,9 +1123,8 @@ pub const Object = struct {...@@ -1132,9 +1123,8 @@ pub const Object = struct {
1132 llvm_arg_i += 1;1123 llvm_arg_i += 1;
11331124
1134 const alignment = param_ty.abiAlignment(target);1125 const alignment = param_ty.abiAlignment(target);
1135 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, alignment, target);1126 const arg_ptr = buildAllocaInner(dg.context, builder, llvm_func, false, param_llvm_ty, alignment, target);
1136 const casted_ptr = builder.buildBitCast(arg_ptr, param.typeOf().pointerType(0), "");1127 _ = builder.buildStore(param, arg_ptr);
1137 _ = builder.buildStore(param, casted_ptr);
11381128
1139 if (isByRef(param_ty)) {1129 if (isByRef(param_ty)) {
1140 try args.append(arg_ptr);1130 try args.append(arg_ptr);
...@@ -1938,6 +1928,7 @@ pub const Object = struct {...@@ -1938,6 +1928,7 @@ pub const Object = struct {
1938 if (ty.castTag(.@"struct")) |payload| {1928 if (ty.castTag(.@"struct")) |payload| {
1939 const struct_obj = payload.data;1929 const struct_obj = payload.data;
1940 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {1930 if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
1931 assert(struct_obj.haveLayout());
1941 const info = struct_obj.backing_int_ty.intInfo(target);1932 const info = struct_obj.backing_int_ty.intInfo(target);
1942 const dwarf_encoding: c_uint = switch (info.signedness) {1933 const dwarf_encoding: c_uint = switch (info.signedness) {
1943 .signed => DW.ATE.signed,1934 .signed => DW.ATE.signed,
...@@ -2477,12 +2468,8 @@ pub const DeclGen = struct {...@@ -2477,12 +2468,8 @@ pub const DeclGen = struct {
2477 new_global.setAlignment(global.getAlignment());2468 new_global.setAlignment(global.getAlignment());
2478 if (decl.@"linksection") |section| new_global.setSection(section);2469 if (decl.@"linksection") |section| new_global.setSection(section);
2479 new_global.setInitializer(llvm_init);2470 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.
2483 // TODO: How should this work then the address space of a global changed?2471 // TODO: How should this work then the address space of a global changed?
2484 const new_global_ptr = new_global.constBitCast(global.typeOf());2472 global.replaceAllUsesWith(new_global);
2485 global.replaceAllUsesWith(new_global_ptr);
2486 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);2473 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
2487 new_global.takeName(global);2474 new_global.takeName(global);
2488 global.deleteGlobal();2475 global.deleteGlobal();
...@@ -2781,11 +2768,7 @@ pub const DeclGen = struct {...@@ -2781,11 +2768,7 @@ pub const DeclGen = struct {
2781 }2768 }
2782 const ptr_info = t.ptrInfo().data;2769 const ptr_info = t.ptrInfo().data;
2783 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);2770 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);
2784 if (ptr_info.host_size != 0) {2771 return dg.context.pointerType(llvm_addrspace);
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);
2789 },2772 },
2790 .Opaque => switch (t.tag()) {2773 .Opaque => switch (t.tag()) {
2791 .@"opaque" => {2774 .@"opaque" => {
...@@ -2949,6 +2932,7 @@ pub const DeclGen = struct {...@@ -2949,6 +2932,7 @@ pub const DeclGen = struct {
2949 const struct_obj = t.castTag(.@"struct").?.data;2932 const struct_obj = t.castTag(.@"struct").?.data;
29502933
2951 if (struct_obj.layout == .Packed) {2934 if (struct_obj.layout == .Packed) {
2935 assert(struct_obj.haveLayout());
2952 const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty);2936 const int_llvm_ty = try dg.lowerType(struct_obj.backing_int_ty);
2953 gop.value_ptr.* = int_llvm_ty;2937 gop.value_ptr.* = int_llvm_ty;
2954 return int_llvm_ty;2938 return int_llvm_ty;
...@@ -3108,8 +3092,7 @@ pub const DeclGen = struct {...@@ -3108,8 +3092,7 @@ pub const DeclGen = struct {
3108 defer llvm_params.deinit();3092 defer llvm_params.deinit();
31093093
3110 if (firstParamSRet(fn_info, target)) {3094 if (firstParamSRet(fn_info, target)) {
3111 const llvm_sret_ty = try dg.lowerType(fn_info.return_type);3095 try llvm_params.append(dg.context.pointerType(0));
3112 try llvm_params.append(llvm_sret_ty.pointerType(0));
3113 }3096 }
31143097
3115 if (fn_info.return_type.isError() and3098 if (fn_info.return_type.isError() and
...@@ -3131,9 +3114,7 @@ pub const DeclGen = struct {...@@ -3131,9 +3114,7 @@ pub const DeclGen = struct {
3131 try llvm_params.append(try dg.lowerType(param_ty));3114 try llvm_params.append(try dg.lowerType(param_ty));
3132 },3115 },
3133 .byref, .byref_mut => {3116 .byref, .byref_mut => {
3134 const param_ty = fn_info.param_types[it.zig_index - 1];3117 try llvm_params.append(dg.context.pointerType(0));
3135 const raw_llvm_ty = try dg.lowerType(param_ty);
3136 try llvm_params.append(raw_llvm_ty.pointerType(0));
3137 },3118 },
3138 .abi_sized_int => {3119 .abi_sized_int => {
3139 const param_ty = fn_info.param_types[it.zig_index - 1];3120 const param_ty = fn_info.param_types[it.zig_index - 1];
...@@ -3323,16 +3304,12 @@ pub const DeclGen = struct {...@@ -3323,16 +3304,12 @@ pub const DeclGen = struct {
3323 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);3304 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
3324 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);3305 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
3329 const val = try dg.resolveGlobalDecl(decl_index);3307 const val = try dg.resolveGlobalDecl(decl_index);
3330 const val_ptr = val.constBitCast(llvm_actual_ptr_type);3308 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
3331 if (llvm_actual_addrspace != llvm_wanted_addrspace) {3309 val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace))
3332 const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace);3310 else
3333 return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type);3311 val;
3334 }3312 return addrspace_casted_ptr;
3335 return val_ptr;
3336 },3313 },
3337 .slice => {3314 .slice => {
3338 const slice = tv.val.castTag(.slice).?.data;3315 const slice = tv.val.castTag(.slice).?.data;
...@@ -3355,7 +3332,7 @@ pub const DeclGen = struct {...@@ -3355,7 +3332,7 @@ pub const DeclGen = struct {
3355 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));3332 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
3356 },3333 },
3357 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {3334 .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);
3359 },3336 },
3360 .null_value, .zero => {3337 .null_value, .zero => {
3361 const llvm_type = try dg.lowerType(tv.ty);3338 const llvm_type = try dg.lowerType(tv.ty);
...@@ -3363,7 +3340,7 @@ pub const DeclGen = struct {...@@ -3363,7 +3340,7 @@ pub const DeclGen = struct {
3363 },3340 },
3364 .opt_payload => {3341 .opt_payload => {
3365 const payload = tv.val.castTag(.opt_payload).?.data;3342 const payload = tv.val.castTag(.opt_payload).?.data;
3366 return dg.lowerParentPtr(payload, tv.ty);3343 return dg.lowerParentPtr(payload);
3367 },3344 },
3368 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{3345 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
3369 tv.ty.fmtDebug(), tag,3346 tv.ty.fmtDebug(), tag,
...@@ -3657,6 +3634,7 @@ pub const DeclGen = struct {...@@ -3657,6 +3634,7 @@ pub const DeclGen = struct {
3657 const struct_obj = tv.ty.castTag(.@"struct").?.data;3634 const struct_obj = tv.ty.castTag(.@"struct").?.data;
36583635
3659 if (struct_obj.layout == .Packed) {3636 if (struct_obj.layout == .Packed) {
3637 assert(struct_obj.haveLayout());
3660 const big_bits = struct_obj.backing_int_ty.bitSize(target);3638 const big_bits = struct_obj.backing_int_ty.bitSize(target);
3661 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));3639 const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits));
3662 const fields = struct_obj.fields.values();3640 const fields = struct_obj.fields.values();
...@@ -3940,7 +3918,6 @@ pub const DeclGen = struct {...@@ -3940,7 +3918,6 @@ pub const DeclGen = struct {
3940 dg: *DeclGen,3918 dg: *DeclGen,
3941 ptr_val: Value,3919 ptr_val: Value,
3942 decl_index: Module.Decl.Index,3920 decl_index: Module.Decl.Index,
3943 ptr_child_ty: Type,
3944 ) Error!*llvm.Value {3921 ) Error!*llvm.Value {
3945 const decl = dg.module.declPtr(decl_index);3922 const decl = dg.module.declPtr(decl_index);
3946 dg.module.markDeclAlive(decl);3923 dg.module.markDeclAlive(decl);
...@@ -3949,62 +3926,54 @@ pub const DeclGen = struct {...@@ -3949,62 +3926,54 @@ pub const DeclGen = struct {
3949 .data = decl.ty,3926 .data = decl.ty,
3950 };3927 };
3951 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);3928 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
3952 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);3929 return 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 }
3959 }3930 }
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 {
3962 const target = dg.module.getTarget();3933 const target = dg.module.getTarget();
3963 var bitcast_needed: bool = undefined;3934 switch (ptr_val.tag()) {
3964 const llvm_ptr = switch (ptr_val.tag()) {
3965 .decl_ref_mut => {3935 .decl_ref_mut => {
3966 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;3936 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);
3968 },3938 },
3969 .decl_ref => {3939 .decl_ref => {
3970 const decl = ptr_val.castTag(.decl_ref).?.data;3940 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);
3972 },3942 },
3973 .variable => {3943 .variable => {
3974 const decl = ptr_val.castTag(.variable).?.data.owner_decl;3944 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);
3976 },3946 },
3977 .int_i64 => {3947 .int_i64 => {
3978 const int = ptr_val.castTag(.int_i64).?.data;3948 const int = ptr_val.castTag(.int_i64).?.data;
3979 const llvm_usize = try dg.lowerType(Type.usize);3949 const llvm_usize = try dg.lowerType(Type.usize);
3980 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);3950 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));
3982 },3952 },
3983 .int_u64 => {3953 .int_u64 => {
3984 const int = ptr_val.castTag(.int_u64).?.data;3954 const int = ptr_val.castTag(.int_u64).?.data;
3985 const llvm_usize = try dg.lowerType(Type.usize);3955 const llvm_usize = try dg.lowerType(Type.usize);
3986 const llvm_int = llvm_usize.constInt(int, .False);3956 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));
3988 },3958 },
3989 .field_ptr => blk: {3959 .field_ptr => {
3990 const field_ptr = ptr_val.castTag(.field_ptr).?.data;3960 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);
3992 const parent_ty = field_ptr.container_ty;3962 const parent_ty = field_ptr.container_ty;
39933963
3994 const field_index = @intCast(u32, field_ptr.field_index);3964 const field_index = @intCast(u32, field_ptr.field_index);
3995 const llvm_u32 = dg.context.intType(32);3965 const llvm_u32 = dg.context.intType(32);
3996 switch (parent_ty.zigTypeTag()) {3966 switch (parent_ty.zigTypeTag()) {
3997 .Union => {3967 .Union => {
3998 bitcast_needed = true;
3999 if (parent_ty.containerLayout() == .Packed) {3968 if (parent_ty.containerLayout() == .Packed) {
4000 break :blk parent_llvm_ptr;3969 return parent_llvm_ptr;
4001 }3970 }
40023971
4003 const layout = parent_ty.unionGetLayout(target);3972 const layout = parent_ty.unionGetLayout(target);
4004 if (layout.payload_size == 0) {3973 if (layout.payload_size == 0) {
4005 // In this case a pointer to the union and a pointer to any3974 // In this case a pointer to the union and a pointer to any
4006 // (void) payload is the same.3975 // (void) payload is the same.
4007 break :blk parent_llvm_ptr;3976 return parent_llvm_ptr;
4008 }3977 }
4009 const llvm_pl_index = if (layout.tag_size == 0)3978 const llvm_pl_index = if (layout.tag_size == 0)
4010 03979 0
...@@ -4015,10 +3984,9 @@ pub const DeclGen = struct {...@@ -4015,10 +3984,9 @@ pub const DeclGen = struct {
4015 llvm_u32.constInt(llvm_pl_index, .False),3984 llvm_u32.constInt(llvm_pl_index, .False),
4016 };3985 };
4017 const parent_llvm_ty = try dg.lowerType(parent_ty);3986 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);
4019 },3988 },
4020 .Struct => {3989 .Struct => {
4021 const field_ty = parent_ty.structFieldType(field_index);
4022 if (parent_ty.containerLayout() == .Packed) {3990 if (parent_ty.containerLayout() == .Packed) {
4023 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());3991 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
4024 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);3992 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
...@@ -4033,26 +4001,23 @@ pub const DeclGen = struct {...@@ -4033,26 +4001,23 @@ pub const DeclGen = struct {
4033 };4001 };
4034 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);4002 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
4035 const field_addr = base_addr.constAdd(byte_offset);4003 const field_addr = base_addr.constAdd(byte_offset);
4036 bitcast_needed = false;4004 const final_llvm_ty = dg.context.pointerType(0);
4037 const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0);4005 return field_addr.constIntToPtr(final_llvm_ty);
4038 break :blk field_addr.constIntToPtr(final_llvm_ty);
4039 }4006 }
40404007
4041 var ty_buf: Type.Payload.Pointer = undefined;4008 var ty_buf: Type.Payload.Pointer = undefined;
40424009
4043 const parent_llvm_ty = try dg.lowerType(parent_ty);4010 const parent_llvm_ty = try dg.lowerType(parent_ty);
4044 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {4011 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {
4045 bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
4046 const indices: [2]*llvm.Value = .{4012 const indices: [2]*llvm.Value = .{
4047 llvm_u32.constInt(0, .False),4013 llvm_u32.constInt(0, .False),
4048 llvm_u32.constInt(llvm_field_index, .False),4014 llvm_u32.constInt(llvm_field_index, .False),
4049 };4015 };
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);
4051 } else {4017 } else {
4052 bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module);
4053 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);4018 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);
4054 const indices: [1]*llvm.Value = .{llvm_index};4019 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);
4056 }4021 }
4057 },4022 },
4058 .Pointer => {4023 .Pointer => {
...@@ -4062,37 +4027,34 @@ pub const DeclGen = struct {...@@ -4062,37 +4027,34 @@ pub const DeclGen = struct {
4062 llvm_u32.constInt(field_index, .False),4027 llvm_u32.constInt(field_index, .False),
4063 };4028 };
4064 const parent_llvm_ty = try dg.lowerType(parent_ty);4029 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);
4066 },4031 },
4067 else => unreachable,4032 else => unreachable,
4068 }4033 }
4069 },4034 },
4070 .elem_ptr => blk: {4035 .elem_ptr => {
4071 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;4036 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);4037 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr);
4073 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module);
40744038
4075 const llvm_usize = try dg.lowerType(Type.usize);4039 const llvm_usize = try dg.lowerType(Type.usize);
4076 const indices: [1]*llvm.Value = .{4040 const indices: [1]*llvm.Value = .{
4077 llvm_usize.constInt(elem_ptr.index, .False),4041 llvm_usize.constInt(elem_ptr.index, .False),
4078 };4042 };
4079 const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);4043 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);
4081 },4045 },
4082 .opt_payload_ptr => blk: {4046 .opt_payload_ptr => {
4083 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;4047 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);
4085 var buf: Type.Payload.ElemType = undefined;4049 var buf: Type.Payload.ElemType = undefined;
40864050
4087 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);4051 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);
4088 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4089
4090 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or4052 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
4091 payload_ty.optionalReprIsPayload())4053 payload_ty.optionalReprIsPayload())
4092 {4054 {
4093 // In this case, we represent pointer to optional the same as pointer4055 // In this case, we represent pointer to optional the same as pointer
4094 // to the payload.4056 // to the payload.
4095 break :blk parent_llvm_ptr;4057 return parent_llvm_ptr;
4096 }4058 }
40974059
4098 const llvm_u32 = dg.context.intType(32);4060 const llvm_u32 = dg.context.intType(32);
...@@ -4101,19 +4063,17 @@ pub const DeclGen = struct {...@@ -4101,19 +4063,17 @@ pub const DeclGen = struct {
4101 llvm_u32.constInt(0, .False),4063 llvm_u32.constInt(0, .False),
4102 };4064 };
4103 const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty);4065 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);
4105 },4067 },
4106 .eu_payload_ptr => blk: {4068 .eu_payload_ptr => {
4107 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;4069 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
4110 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();4072 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();
4111 bitcast_needed = !payload_ty.eql(ptr_child_ty, dg.module);
4112
4113 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {4073 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4114 // In this case, we represent pointer to error union the same as pointer4074 // In this case, we represent pointer to error union the same as pointer
4115 // to the payload.4075 // to the payload.
4116 break :blk parent_llvm_ptr;4076 return parent_llvm_ptr;
4117 }4077 }
41184078
4119 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;4079 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;
...@@ -4123,14 +4083,9 @@ pub const DeclGen = struct {...@@ -4123,14 +4083,9 @@ pub const DeclGen = struct {
4123 llvm_u32.constInt(payload_offset, .False),4083 llvm_u32.constInt(payload_offset, .False),
4124 };4084 };
4125 const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty);4085 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);
4127 },4087 },
4128 else => unreachable,4088 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;
4134 }4089 }
4135 }4090 }
41364091
...@@ -4189,8 +4144,7 @@ pub const DeclGen = struct {...@@ -4189,8 +4144,7 @@ pub const DeclGen = struct {
4189 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);4144 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
4190 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);4145 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
4191 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {4146 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
4192 const llvm_decl_ty = try self.lowerType(decl.ty);4147 const llvm_decl_wanted_ptr_ty = self.context.pointerType(llvm_wanted_addrspace);
4193 const llvm_decl_wanted_ptr_ty = llvm_decl_ty.pointerType(llvm_wanted_addrspace);
4194 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);4148 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
4195 } else llvm_decl_val;4149 } else llvm_decl_val;
41964150
...@@ -4471,18 +4425,11 @@ pub const FuncGen = struct {...@@ -4471,18 +4425,11 @@ pub const FuncGen = struct {
4471 global.setGlobalConstant(.True);4425 global.setGlobalConstant(.True);
4472 global.setUnnamedAddr(.True);4426 global.setUnnamedAddr(.True);
4473 global.setAlignment(tv.ty.abiAlignment(target));4427 global.setAlignment(tv.ty.abiAlignment(target));
4474 // Because of LLVM limitations for lowering certain types such as unions,4428 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
4475 // the type of global constants might not match the type it is supposed to4429 global.constAddrSpaceCast(self.context.pointerType(llvm_wanted_addrspace))
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)
4483 else4430 else
4484 bitcasted_ptr;4431 global;
4485 return casted_ptr;4432 return addrspace_casted_ptr;
4486 }4433 }
44874434
4488 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4435 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
...@@ -4770,17 +4717,7 @@ pub const FuncGen = struct {...@@ -4770,17 +4717,7 @@ pub const FuncGen = struct {
4770 load_inst.setAlignment(alignment);4717 load_inst.setAlignment(alignment);
4771 try llvm_args.append(load_inst);4718 try llvm_args.append(load_inst);
4772 } else {4719 } else {
4773 if (param_ty.zigTypeTag() == .Pointer) {4720 try llvm_args.append(llvm_arg);
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 }
4784 }4721 }
4785 },4722 },
4786 .byref => {4723 .byref => {
...@@ -4824,26 +4761,22 @@ pub const FuncGen = struct {...@@ -4824,26 +4761,22 @@ pub const FuncGen = struct {
4824 const param_ty = self.air.typeOf(arg);4761 const param_ty = self.air.typeOf(arg);
4825 const llvm_arg = try self.resolveInst(arg);4762 const llvm_arg = try self.resolveInst(arg);
4826 const abi_size = @intCast(c_uint, param_ty.abiSize(target));4763 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
4827 const int_llvm_ty = self.dg.context.intType(abi_size * 8);4764 const int_llvm_ty = self.context.intType(abi_size * 8);
4828 const int_ptr_llvm_ty = int_llvm_ty.pointerType(0);
48294765
4830 if (isByRef(param_ty)) {4766 if (isByRef(param_ty)) {
4831 const alignment = param_ty.abiAlignment(target);4767 const alignment = param_ty.abiAlignment(target);
4832 const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, "");4768 const load_inst = self.builder.buildLoad(int_llvm_ty, llvm_arg, "");
4833 const load_inst = self.builder.buildLoad(int_llvm_ty, casted_ptr, "");
4834 load_inst.setAlignment(alignment);4769 load_inst.setAlignment(alignment);
4835 try llvm_args.append(load_inst);4770 try llvm_args.append(load_inst);
4836 } else {4771 } else {
4837 // LLVM does not allow bitcasting structs so we must allocate4772 // 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.
4839 const alignment = @max(4774 const alignment = @max(
4840 param_ty.abiAlignment(target),4775 param_ty.abiAlignment(target),
4841 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),4776 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
4842 );4777 );
4843 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);4778 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
4844 const param_llvm_ty = try self.dg.lowerType(param_ty);4779 const store_inst = self.builder.buildStore(llvm_arg, int_ptr);
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);
4847 store_inst.setAlignment(alignment);4780 store_inst.setAlignment(alignment);
4848 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");4781 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
4849 load_inst.setAlignment(alignment);4782 load_inst.setAlignment(alignment);
...@@ -4872,12 +4805,11 @@ pub const FuncGen = struct {...@@ -4872,12 +4805,11 @@ pub const FuncGen = struct {
4872 break :p p;4805 break :p p;
4873 };4806 };
48744807
4875 const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);4808 const llvm_ty = self.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), "");
4877 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);4809 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
4878 for (llvm_types) |field_ty, i_usize| {4810 for (llvm_types) |field_ty, i_usize| {
4879 const i = @intCast(c_uint, i_usize);4811 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, "");
4881 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");4813 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");
4882 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);4814 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
4883 llvm_args.appendAssumeCapacity(load_inst);4815 llvm_args.appendAssumeCapacity(load_inst);
...@@ -4886,7 +4818,7 @@ pub const FuncGen = struct {...@@ -4886,7 +4818,7 @@ pub const FuncGen = struct {
4886 .as_u16 => {4818 .as_u16 => {
4887 const arg = args[it.zig_index - 1];4819 const arg = args[it.zig_index - 1];
4888 const llvm_arg = try self.resolveInst(arg);4820 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), "");
4890 try llvm_args.append(casted);4822 try llvm_args.append(casted);
4891 },4823 },
4892 .float_array => |count| {4824 .float_array => |count| {
...@@ -4903,9 +4835,8 @@ pub const FuncGen = struct {...@@ -4903,9 +4835,8 @@ pub const FuncGen = struct {
4903 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);4835 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);
4904 const array_llvm_ty = float_ty.arrayType(count);4836 const array_llvm_ty = float_ty.arrayType(count);
49054837
4906 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
4907 const alignment = arg_ty.abiAlignment(target);4838 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, "");
4909 load_inst.setAlignment(alignment);4840 load_inst.setAlignment(alignment);
4910 try llvm_args.append(load_inst);4841 try llvm_args.append(load_inst);
4911 },4842 },
...@@ -4921,10 +4852,9 @@ pub const FuncGen = struct {...@@ -4921,10 +4852,9 @@ pub const FuncGen = struct {
4921 llvm_arg = store_inst;4852 llvm_arg = store_inst;
4922 }4853 }
49234854
4924 const array_llvm_ty = self.dg.context.intType(elem_size).arrayType(arr_len);4855 const array_llvm_ty = self.context.intType(elem_size).arrayType(arr_len);
4925 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
4926 const alignment = arg_ty.abiAlignment(target);4856 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, "");
4928 load_inst.setAlignment(alignment);4858 load_inst.setAlignment(alignment);
4929 try llvm_args.append(load_inst);4859 try llvm_args.append(load_inst);
4930 },4860 },
...@@ -5028,12 +4958,10 @@ pub const FuncGen = struct {...@@ -5028,12 +4958,10 @@ pub const FuncGen = struct {
5028 if (abi_ret_ty != llvm_ret_ty) {4958 if (abi_ret_ty != llvm_ret_ty) {
5029 // In this case the function return type is honoring the calling convention by having4959 // In this case the function return type is honoring the calling convention by having
5030 // a different LLVM type than the usual one. We solve this here at the callsite4960 // 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.
5032 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);4962 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);
5033 const rp = self.buildAlloca(llvm_ret_ty, alignment);4963 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5034 const ptr_abi_ty = abi_ret_ty.pointerType(0);4964 const store_inst = self.builder.buildStore(call, rp);
5035 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");
5036 const store_inst = self.builder.buildStore(call, casted_ptr);
5037 store_inst.setAlignment(alignment);4965 store_inst.setAlignment(alignment);
5038 if (isByRef(return_type)) {4966 if (isByRef(return_type)) {
5039 return rp;4967 return rp;
...@@ -5086,7 +5014,6 @@ pub const FuncGen = struct {...@@ -5086,7 +5014,6 @@ pub const FuncGen = struct {
5086 }5014 }
50875015
5088 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5016 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5089 const ptr_abi_ty = abi_ret_ty.pointerType(0);
5090 const operand = try self.resolveInst(un_op);5017 const operand = try self.resolveInst(un_op);
5091 const target = self.dg.module.getTarget();5018 const target = self.dg.module.getTarget();
5092 const alignment = ret_ty.abiAlignment(target);5019 const alignment = ret_ty.abiAlignment(target);
...@@ -5094,8 +5021,7 @@ pub const FuncGen = struct {...@@ -5094,8 +5021,7 @@ pub const FuncGen = struct {
5094 if (isByRef(ret_ty)) {5021 if (isByRef(ret_ty)) {
5095 // operand is a pointer however self.ret_ptr is null so that means5022 // operand is a pointer however self.ret_ptr is null so that means
5096 // we need to return a value.5023 // we need to return a value.
5097 const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");5024 const load_inst = self.builder.buildLoad(abi_ret_ty, operand, "");
5098 const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
5099 load_inst.setAlignment(alignment);5025 load_inst.setAlignment(alignment);
5100 _ = self.builder.buildRet(load_inst);5026 _ = self.builder.buildRet(load_inst);
5101 return null;5027 return null;
...@@ -5110,8 +5036,7 @@ pub const FuncGen = struct {...@@ -5110,8 +5036,7 @@ pub const FuncGen = struct {
5110 const rp = self.buildAlloca(llvm_ret_ty, alignment);5036 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5111 const store_inst = self.builder.buildStore(operand, rp);5037 const store_inst = self.builder.buildStore(operand, rp);
5112 store_inst.setAlignment(alignment);5038 store_inst.setAlignment(alignment);
5113 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");5039 const load_inst = self.builder.buildLoad(abi_ret_ty, rp, "");
5114 const load_inst = self.builder.buildLoad(abi_ret_ty, casted_ptr, "");
5115 load_inst.setAlignment(alignment);5040 load_inst.setAlignment(alignment);
5116 _ = self.builder.buildRet(load_inst);5041 _ = self.builder.buildRet(load_inst);
5117 return null;5042 return null;
...@@ -5141,12 +5066,7 @@ pub const FuncGen = struct {...@@ -5141,12 +5066,7 @@ pub const FuncGen = struct {
5141 const ptr = try self.resolveInst(un_op);5066 const ptr = try self.resolveInst(un_op);
5142 const target = self.dg.module.getTarget();5067 const target = self.dg.module.getTarget();
5143 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5068 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5144 const llvm_ret_ty = try self.dg.lowerType(ret_ty);5069 const loaded = self.builder.buildLoad(abi_ret_ty, ptr, "");
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, "");
5150 loaded.setAlignment(ret_ty.abiAlignment(target));5070 loaded.setAlignment(ret_ty.abiAlignment(target));
5151 _ = self.builder.buildRet(loaded);5071 _ = self.builder.buildRet(loaded);
5152 return null;5072 return null;
...@@ -5178,8 +5098,8 @@ pub const FuncGen = struct {...@@ -5178,8 +5098,8 @@ pub const FuncGen = struct {
5178 const llvm_fn_name = "llvm.va_copy";5098 const llvm_fn_name = "llvm.va_copy";
5179 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5099 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5180 const param_types = [_]*llvm.Type{5100 const param_types = [_]*llvm.Type{
5181 self.dg.context.intType(8).pointerType(0),5101 self.context.pointerType(0),
5182 self.dg.context.intType(8).pointerType(0),5102 self.context.pointerType(0),
5183 };5103 };
5184 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5104 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5185 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);5105 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
...@@ -5203,7 +5123,7 @@ pub const FuncGen = struct {...@@ -5203,7 +5123,7 @@ pub const FuncGen = struct {
52035123
5204 const llvm_fn_name = "llvm.va_end";5124 const llvm_fn_name = "llvm.va_end";
5205 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5125 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)};
5207 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5127 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5208 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);5128 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
5209 };5129 };
...@@ -5224,7 +5144,7 @@ pub const FuncGen = struct {...@@ -5224,7 +5144,7 @@ pub const FuncGen = struct {
52245144
5225 const llvm_fn_name = "llvm.va_start";5145 const llvm_fn_name = "llvm.va_start";
5226 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5146 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)};
5228 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5148 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);
5229 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);5149 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
5230 };5150 };
...@@ -5417,7 +5337,7 @@ pub const FuncGen = struct {...@@ -5417,7 +5337,7 @@ pub const FuncGen = struct {
5417 // of function pointers, however the phi makes it a runtime value and therefore5337 // of function pointers, however the phi makes it a runtime value and therefore
5418 // the LLVM type has to be wrapped in a pointer.5338 // the LLVM type has to be wrapped in a pointer.
5419 if (is_body or isByRef(inst_ty)) {5339 if (is_body or isByRef(inst_ty)) {
5420 break :ty raw_llvm_ty.pointerType(0);5340 break :ty self.context.pointerType(0);
5421 }5341 }
5422 break :ty raw_llvm_ty;5342 break :ty raw_llvm_ty;
5423 };5343 };
...@@ -5482,7 +5402,7 @@ pub const FuncGen = struct {...@@ -5482,7 +5402,7 @@ pub const FuncGen = struct {
5482 const payload_ty = self.air.typeOfIndex(inst);5402 const payload_ty = self.air.typeOfIndex(inst);
5483 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;5403 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
5484 const is_unused = self.liveness.isUnused(inst);5404 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);
5486 }5406 }
54875407
5488 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5408 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -5491,9 +5411,8 @@ pub const FuncGen = struct {...@@ -5491,9 +5411,8 @@ pub const FuncGen = struct {
5491 const err_union_ptr = try self.resolveInst(extra.data.ptr);5411 const err_union_ptr = try self.resolveInst(extra.data.ptr);
5492 const body = self.air.extra[extra.end..][0..extra.data.body_len];5412 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5493 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();5413 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
5494 const payload_ty = self.air.typeOfIndex(inst);
5495 const is_unused = self.liveness.isUnused(inst);5414 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);
5497 }5416 }
54985417
5499 fn lowerTry(5418 fn lowerTry(
...@@ -5504,7 +5423,6 @@ pub const FuncGen = struct {...@@ -5504,7 +5423,6 @@ pub const FuncGen = struct {
5504 operand_is_ptr: bool,5423 operand_is_ptr: bool,
5505 can_elide_load: bool,5424 can_elide_load: bool,
5506 is_unused: bool,5425 is_unused: bool,
5507 result_ty: Type,
5508 ) !?*llvm.Value {5426 ) !?*llvm.Value {
5509 const payload_ty = err_union_ty.errorUnionPayload();5427 const payload_ty = err_union_ty.errorUnionPayload();
5510 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();5428 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
...@@ -5547,12 +5465,7 @@ pub const FuncGen = struct {...@@ -5547,12 +5465,7 @@ pub const FuncGen = struct {
5547 return null;5465 return null;
5548 }5466 }
5549 if (!payload_has_bits) {5467 if (!payload_has_bits) {
5550 if (!operand_is_ptr) return null;5468 return if (operand_is_ptr) err_union else 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, "");
5556 }5469 }
5557 const offset = errUnionPayloadOffset(payload_ty, target);5470 const offset = errUnionPayloadOffset(payload_ty, target);
5558 if (operand_is_ptr) {5471 if (operand_is_ptr) {
...@@ -6038,9 +5951,8 @@ pub const FuncGen = struct {...@@ -6038,9 +5951,8 @@ pub const FuncGen = struct {
6038 const union_llvm_ty = try self.dg.lowerType(struct_ty);5951 const union_llvm_ty = try self.dg.lowerType(struct_ty);
6039 const layout = struct_ty.unionGetLayout(target);5952 const layout = struct_ty.unionGetLayout(target);
6040 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);5953 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, "");
6042 const llvm_field_ty = try self.dg.lowerType(field_ty);5955 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), "");
6044 if (isByRef(field_ty)) {5956 if (isByRef(field_ty)) {
6045 if (canElideLoad(self, body_tail))5957 if (canElideLoad(self, body_tail))
6046 return field_ptr;5958 return field_ptr;
...@@ -6068,7 +5980,7 @@ pub const FuncGen = struct {...@@ -6068,7 +5980,7 @@ pub const FuncGen = struct {
60685980
6069 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));5981 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
6070 if (field_offset == 0) {5982 if (field_offset == 0) {
6071 return self.builder.buildBitCast(field_ptr, res_ty, "");5983 return field_ptr;
6072 }5984 }
6073 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());5985 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
60745986
...@@ -6635,7 +6547,7 @@ pub const FuncGen = struct {...@@ -6635,7 +6547,7 @@ pub const FuncGen = struct {
6635 self.builder.buildLoad(optional_llvm_ty, operand, "")6547 self.builder.buildLoad(optional_llvm_ty, operand, "")
6636 else6548 else
6637 operand;6549 operand;
6638 const llvm_i8 = self.dg.context.intType(8);6550 const llvm_i8 = self.context.intType(8);
6639 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");6551 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
6640 }6552 }
66416553
...@@ -6701,16 +6613,12 @@ pub const FuncGen = struct {...@@ -6701,16 +6613,12 @@ pub const FuncGen = struct {
6701 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6613 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6702 const operand = try self.resolveInst(ty_op.operand);6614 const operand = try self.resolveInst(ty_op.operand);
6703 const optional_ty = self.air.typeOf(ty_op.operand).childType();6615 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6704 const result_ty = self.air.getRefType(ty_op.ty);
6705 var buf: Type.Payload.ElemType = undefined;6616 var buf: Type.Payload.ElemType = undefined;
6706 const payload_ty = optional_ty.optionalChild(&buf);6617 const payload_ty = optional_ty.optionalChild(&buf);
6707 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6618 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6708 // We have a pointer to a zero-bit value and we need to return6619 // We have a pointer to a zero-bit value and we need to return
6709 // a pointer to a zero-bit value.6620 // a pointer to a zero-bit value.
67106621 return operand;
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, "");
6714 }6622 }
6715 if (optional_ty.optionalReprIsPayload()) {6623 if (optional_ty.optionalReprIsPayload()) {
6716 // The payload and the optional are the same value.6624 // The payload and the optional are the same value.
...@@ -6726,17 +6634,13 @@ pub const FuncGen = struct {...@@ -6726,17 +6634,13 @@ pub const FuncGen = struct {
6726 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6634 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6727 const operand = try self.resolveInst(ty_op.operand);6635 const operand = try self.resolveInst(ty_op.operand);
6728 const optional_ty = self.air.typeOf(ty_op.operand).childType();6636 const optional_ty = self.air.typeOf(ty_op.operand).childType();
6729 const result_ty = self.air.getRefType(ty_op.ty);
6730 var buf: Type.Payload.ElemType = undefined;6637 var buf: Type.Payload.ElemType = undefined;
6731 const payload_ty = optional_ty.optionalChild(&buf);6638 const payload_ty = optional_ty.optionalChild(&buf);
6732 const non_null_bit = self.context.intType(8).constInt(1, .False);6639 const non_null_bit = self.context.intType(8).constInt(1, .False);
6733 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6640 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6734 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.6641 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
6735 _ = self.builder.buildStore(non_null_bit, operand);6642 _ = self.builder.buildStore(non_null_bit, operand);
67366643 return operand;
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, "");
6740 }6644 }
6741 if (optional_ty.optionalReprIsPayload()) {6645 if (optional_ty.optionalReprIsPayload()) {
6742 // The payload and the optional are the same value.6646 // The payload and the optional are the same value.
...@@ -6794,11 +6698,7 @@ pub const FuncGen = struct {...@@ -6794,11 +6698,7 @@ pub const FuncGen = struct {
6794 const target = self.dg.module.getTarget();6698 const target = self.dg.module.getTarget();
67956699
6796 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6700 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6797 if (!operand_is_ptr) return null;6701 return if (operand_is_ptr) operand else 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, "");
6802 }6702 }
6803 const offset = errUnionPayloadOffset(payload_ty, target);6703 const offset = errUnionPayloadOffset(payload_ty, target);
6804 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6704 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
...@@ -6834,7 +6734,7 @@ pub const FuncGen = struct {...@@ -6834,7 +6734,7 @@ pub const FuncGen = struct {
6834 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {6734 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
6835 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);6735 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
6836 if (operand_is_ptr) {6736 if (operand_is_ptr) {
6837 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");6737 return operand;
6838 } else {6738 } else {
6839 return err_llvm_ty.constInt(0, .False);6739 return err_llvm_ty.constInt(0, .False);
6840 }6740 }
...@@ -7104,14 +7004,8 @@ pub const FuncGen = struct {...@@ -7104,14 +7004,8 @@ pub const FuncGen = struct {
7104 const llvm_slice_ty = try self.dg.lowerType(inst_ty);7004 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
71057005
7106 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`7006 // 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 to7007 // but `ptr` is pointing to the global directly.
7108 // do GEP(0,0), or we can just bitcast it to be correct, like we do here.7008 const partial = self.builder.buildInsertValue(llvm_slice_ty.getUndef(), ptr, 0, "");
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, "");
7115 return self.builder.buildInsertValue(partial, len, 1, "");7009 return self.builder.buildInsertValue(partial, len, 1, "");
7116 }7010 }
71177011
...@@ -7636,7 +7530,7 @@ pub const FuncGen = struct {...@@ -7636,7 +7530,7 @@ pub const FuncGen = struct {
7636 .neg => {7530 .neg => {
7637 // In this case we can generate a softfloat negation by XORing the7531 // In this case we can generate a softfloat negation by XORing the
7638 // bits with a constant.7532 // 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);
7640 const one = int_llvm_ty.constInt(1, .False);7534 const one = int_llvm_ty.constInt(1, .False);
7641 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);7535 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
7642 const sign_mask = one.constShl(shift_amt);7536 const sign_mask = one.constShl(shift_amt);
...@@ -8045,8 +7939,8 @@ pub const FuncGen = struct {...@@ -8045,8 +7939,8 @@ pub const FuncGen = struct {
8045 const target = self.dg.module.getTarget();7939 const target = self.dg.module.getTarget();
80467940
8047 if (operand_is_ref and result_is_ref) {7941 if (operand_is_ref and result_is_ref) {
8048 // They are both pointers; just do a bitcast on the pointers :)7942 // They are both pointers, so just return the same opaque pointer :)
8049 return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");7943 return operand;
8050 }7944 }
80517945
8052 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {7946 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
...@@ -8061,9 +7955,7 @@ pub const FuncGen = struct {...@@ -8061,9 +7955,7 @@ pub const FuncGen = struct {
8061 const array_ptr = self.buildAlloca(llvm_dest_ty, null);7955 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
8062 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;7956 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8063 if (bitcast_ok) {7957 if (bitcast_ok) {
8064 const llvm_vector_ty = try self.dg.lowerType(operand_ty);7958 const llvm_store = self.builder.buildStore(operand, array_ptr);
8065 const casted_ptr = self.builder.buildBitCast(array_ptr, llvm_vector_ty.pointerType(0), "");
8066 const llvm_store = self.builder.buildStore(operand, casted_ptr);
8067 llvm_store.setAlignment(inst_ty.abiAlignment(target));7959 llvm_store.setAlignment(inst_ty.abiAlignment(target));
8068 } else {7960 } else {
8069 // If the ABI size of the element type is not evenly divisible by size in bits;7961 // If the ABI size of the element type is not evenly divisible by size in bits;
...@@ -8092,9 +7984,7 @@ pub const FuncGen = struct {...@@ -8092,9 +7984,7 @@ pub const FuncGen = struct {
80927984
8093 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;7985 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8094 if (bitcast_ok) {7986 if (bitcast_ok) {
8095 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);7987 const vector = self.builder.buildLoad(llvm_vector_ty, operand, "");
8096 const casted_ptr = self.builder.buildBitCast(operand, llvm_vector_ptr_ty, "");
8097 const vector = self.builder.buildLoad(llvm_vector_ty, casted_ptr, "");
8098 // The array is aligned to the element's alignment, while the vector might have a completely7988 // The array is aligned to the element's alignment, while the vector might have a completely
8099 // different alignment. This means we need to enforce the alignment of this load.7989 // different alignment. This means we need to enforce the alignment of this load.
8100 vector.setAlignment(elem_ty.abiAlignment(target));7990 vector.setAlignment(elem_ty.abiAlignment(target));
...@@ -8124,20 +8014,15 @@ pub const FuncGen = struct {...@@ -8124,20 +8014,15 @@ pub const FuncGen = struct {
8124 }8014 }
81258015
8126 if (operand_is_ref) {8016 if (operand_is_ref) {
8127 // Bitcast the operand pointer, then load.8017 const load_inst = self.builder.buildLoad(llvm_dest_ty, operand, "");
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, "");
8130 load_inst.setAlignment(operand_ty.abiAlignment(target));8018 load_inst.setAlignment(operand_ty.abiAlignment(target));
8131 return load_inst;8019 return load_inst;
8132 }8020 }
81338021
8134 if (result_is_ref) {8022 if (result_is_ref) {
8135 // Bitcast the result pointer, then store.
8136 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));8023 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8137 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8024 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8138 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8025 const store_inst = self.builder.buildStore(operand, result_ptr);
8139 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
8140 const store_inst = self.builder.buildStore(operand, casted_ptr);
8141 store_inst.setAlignment(alignment);8026 store_inst.setAlignment(alignment);
8142 return result_ptr;8027 return result_ptr;
8143 }8028 }
...@@ -8145,12 +8030,10 @@ pub const FuncGen = struct {...@@ -8145,12 +8030,10 @@ pub const FuncGen = struct {
8145 if (llvm_dest_ty.getTypeKind() == .Struct) {8030 if (llvm_dest_ty.getTypeKind() == .Struct) {
8146 // Both our operand and our result are values, not pointers,8031 // Both our operand and our result are values, not pointers,
8147 // but LLVM won't let us bitcast struct values.8032 // 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.
8149 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));8034 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8150 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8035 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8151 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8036 const store_inst = self.builder.buildStore(operand, result_ptr);
8152 const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), "");
8153 const store_inst = self.builder.buildStore(operand, casted_ptr);
8154 store_inst.setAlignment(alignment);8037 store_inst.setAlignment(alignment);
8155 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");8038 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
8156 load_inst.setAlignment(alignment);8039 load_inst.setAlignment(alignment);
...@@ -8248,7 +8131,7 @@ pub const FuncGen = struct {...@@ -8248,7 +8131,7 @@ pub const FuncGen = struct {
8248 /// Use this instead of builder.buildAlloca, because this function makes sure to8131 /// Use this instead of builder.buildAlloca, because this function makes sure to
8249 /// put the alloca instruction at the top of the function!8132 /// put the alloca instruction at the top of the function!
8250 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {8133 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());
8252 }8135 }
82538136
8254 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8137 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -8282,13 +8165,11 @@ pub const FuncGen = struct {...@@ -8282,13 +8165,11 @@ pub const FuncGen = struct {
8282 const target = self.dg.module.getTarget();8165 const target = self.dg.module.getTarget();
8283 const operand_size = operand_ty.abiSize(target);8166 const operand_size = operand_ty.abiSize(target);
8284 const u8_llvm_ty = self.context.intType(8);8167 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, "");
8287 const fill_char = u8_llvm_ty.constInt(0xaa, .False);8168 const fill_char = u8_llvm_ty.constInt(0xaa, .False);
8288 const dest_ptr_align = ptr_ty.ptrAlignment(target);8169 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8289 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8170 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8290 const len = usize_llvm_ty.constInt(operand_size, .False);8171 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());
8292 if (self.dg.module.comp.bin_file.options.valgrind) {8173 if (self.dg.module.comp.bin_file.options.valgrind) {
8293 self.valgrindMarkUndef(dest_ptr, len);8174 self.valgrindMarkUndef(dest_ptr, len);
8294 }8175 }
...@@ -8365,7 +8246,7 @@ pub const FuncGen = struct {...@@ -8365,7 +8246,7 @@ pub const FuncGen = struct {
8365 const llvm_i32 = self.context.intType(32);8246 const llvm_i32 = self.context.intType(32);
8366 const llvm_fn_name = "llvm.frameaddress.p0";8247 const llvm_fn_name = "llvm.frameaddress.p0";
8367 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {8248 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);
8369 const param_types = [_]*llvm.Type{llvm_i32};8250 const param_types = [_]*llvm.Type{llvm_i32};
8370 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);8251 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);
8371 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);8252 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
...@@ -8388,14 +8269,13 @@ pub const FuncGen = struct {...@@ -8388,14 +8269,13 @@ pub const FuncGen = struct {
8388 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {8269 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {
8389 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;8270 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8390 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;8271 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);
8392 var expected_value = try self.resolveInst(extra.expected_value);8273 var expected_value = try self.resolveInst(extra.expected_value);
8393 var new_value = try self.resolveInst(extra.new_value);8274 var new_value = try self.resolveInst(extra.new_value);
8394 const operand_ty = self.air.typeOf(extra.ptr).elemType();8275 const operand_ty = self.air.typeOf(extra.ptr).elemType();
8395 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8276 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8396 if (opt_abi_ty) |abi_ty| {8277 if (opt_abi_ty) |abi_ty| {
8397 // operand needs widening and truncating8278 // operand needs widening and truncating
8398 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
8399 if (operand_ty.isSignedInt()) {8279 if (operand_ty.isSignedInt()) {
8400 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");8280 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
8401 new_value = self.builder.buildSExt(new_value, abi_ty, "");8281 new_value = self.builder.buildSExt(new_value, abi_ty, "");
...@@ -8447,7 +8327,6 @@ pub const FuncGen = struct {...@@ -8447,7 +8327,6 @@ pub const FuncGen = struct {
8447 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);8327 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);
8448 if (opt_abi_ty) |abi_ty| {8328 if (opt_abi_ty) |abi_ty| {
8449 // operand needs widening and truncating or bitcasting.8329 // operand needs widening and truncating or bitcasting.
8450 const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
8451 const casted_operand = if (is_float)8330 const casted_operand = if (is_float)
8452 self.builder.buildBitCast(operand, abi_ty, "")8331 self.builder.buildBitCast(operand, abi_ty, "")
8453 else if (is_signed_int)8332 else if (is_signed_int)
...@@ -8457,7 +8336,7 @@ pub const FuncGen = struct {...@@ -8457,7 +8336,7 @@ pub const FuncGen = struct {
84578336
8458 const uncasted_result = self.builder.buildAtomicRmw(8337 const uncasted_result = self.builder.buildAtomicRmw(
8459 op,8338 op,
8460 casted_ptr,8339 ptr,
8461 casted_operand,8340 casted_operand,
8462 ordering,8341 ordering,
8463 single_threaded,8342 single_threaded,
...@@ -8476,11 +8355,10 @@ pub const FuncGen = struct {...@@ -8476,11 +8355,10 @@ pub const FuncGen = struct {
84768355
8477 // It's a pointer but we need to treat it as an int.8356 // It's a pointer but we need to treat it as an int.
8478 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8357 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8479 const casted_ptr = self.builder.buildBitCast(ptr, usize_llvm_ty.pointerType(0), "");
8480 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");8358 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
8481 const uncasted_result = self.builder.buildAtomicRmw(8359 const uncasted_result = self.builder.buildAtomicRmw(
8482 op,8360 op,
8483 casted_ptr,8361 ptr,
8484 casted_operand,8362 casted_operand,
8485 ordering,8363 ordering,
8486 single_threaded,8364 single_threaded,
...@@ -8508,8 +8386,7 @@ pub const FuncGen = struct {...@@ -8508,8 +8386,7 @@ pub const FuncGen = struct {
85088386
8509 if (opt_abi_llvm_ty) |abi_llvm_ty| {8387 if (opt_abi_llvm_ty) |abi_llvm_ty| {
8510 // operand needs widening and truncating8388 // operand needs widening and truncating
8511 const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), "");8389 const load_inst = self.builder.buildLoad(abi_llvm_ty, ptr, "");
8512 const load_inst = self.builder.buildLoad(abi_llvm_ty, casted_ptr, "");
8513 load_inst.setAlignment(ptr_alignment);8390 load_inst.setAlignment(ptr_alignment);
8514 load_inst.setVolatile(ptr_volatile);8391 load_inst.setVolatile(ptr_volatile);
8515 load_inst.setOrdering(ordering);8392 load_inst.setOrdering(ordering);
...@@ -8531,13 +8408,12 @@ pub const FuncGen = struct {...@@ -8531,13 +8408,12 @@ pub const FuncGen = struct {
8531 const ptr_ty = self.air.typeOf(bin_op.lhs);8408 const ptr_ty = self.air.typeOf(bin_op.lhs);
8532 const operand_ty = ptr_ty.childType();8409 const operand_ty = ptr_ty.childType();
8533 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;8410 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
8534 var ptr = try self.resolveInst(bin_op.lhs);8411 const ptr = try self.resolveInst(bin_op.lhs);
8535 var element = try self.resolveInst(bin_op.rhs);8412 var element = try self.resolveInst(bin_op.rhs);
8536 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8413 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
85378414
8538 if (opt_abi_ty) |abi_ty| {8415 if (opt_abi_ty) |abi_ty| {
8539 // operand needs widening8416 // operand needs widening
8540 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
8541 if (operand_ty.isSignedInt()) {8417 if (operand_ty.isSignedInt()) {
8542 element = self.builder.buildSExt(element, abi_ty, "");8418 element = self.builder.buildSExt(element, abi_ty, "");
8543 } else {8419 } else {
...@@ -8557,15 +8433,13 @@ pub const FuncGen = struct {...@@ -8557,15 +8433,13 @@ pub const FuncGen = struct {
8557 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;8433 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;
8558 const len = try self.resolveInst(extra.rhs);8434 const len = try self.resolveInst(extra.rhs);
8559 const u8_llvm_ty = self.context.intType(8);8435 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, "");
8562 const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value;8436 const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value;
8563 const target = self.dg.module.getTarget();8437 const target = self.dg.module.getTarget();
8564 const dest_ptr_align = ptr_ty.ptrAlignment(target);8438 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
8567 if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) {8441 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);
8569 }8443 }
8570 return null;8444 return null;
8571 }8445 }
...@@ -8578,15 +8452,12 @@ pub const FuncGen = struct {...@@ -8578,15 +8452,12 @@ pub const FuncGen = struct {
8578 const src_ptr = try self.resolveInst(extra.lhs);8452 const src_ptr = try self.resolveInst(extra.lhs);
8579 const src_ptr_ty = self.air.typeOf(extra.lhs);8453 const src_ptr_ty = self.air.typeOf(extra.lhs);
8580 const len = try self.resolveInst(extra.rhs);8454 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, "");
8584 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();8455 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
8585 const target = self.dg.module.getTarget();8456 const target = self.dg.module.getTarget();
8586 _ = self.builder.buildMemCpy(8457 _ = self.builder.buildMemCpy(
8587 dest_ptr_u8,8458 dest_ptr,
8588 dest_ptr_ty.ptrAlignment(target),8459 dest_ptr_ty.ptrAlignment(target),
8589 src_ptr_u8,8460 src_ptr,
8590 src_ptr_ty.ptrAlignment(target),8461 src_ptr_ty.ptrAlignment(target),
8591 len,8462 len,
8592 is_volatile,8463 is_volatile,
...@@ -8780,8 +8651,8 @@ pub const FuncGen = struct {...@@ -8780,8 +8651,8 @@ pub const FuncGen = struct {
8780 const error_set_ty = self.air.getRefType(ty_op.ty);8651 const error_set_ty = self.air.getRefType(ty_op.ty);
87818652
8782 const names = error_set_ty.errorSetNames();8653 const names = error_set_ty.errorSetNames();
8783 const valid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Valid");8654 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
8784 const invalid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Invalid");8655 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
8785 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");8656 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
8786 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));8657 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87878658
...@@ -8807,7 +8678,7 @@ pub const FuncGen = struct {...@@ -8807,7 +8678,7 @@ pub const FuncGen = struct {
88078678
8808 self.builder.positionBuilderAtEnd(end_block);8679 self.builder.positionBuilderAtEnd(end_block);
88098680
8810 const llvm_type = self.dg.context.intType(1);8681 const llvm_type = self.context.intType(1);
8811 const incoming_values: [2]*llvm.Value = .{8682 const incoming_values: [2]*llvm.Value = .{
8812 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),8683 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
8813 };8684 };
...@@ -8869,13 +8740,13 @@ pub const FuncGen = struct {...@@ -8869,13 +8740,13 @@ pub const FuncGen = struct {
8869 }8740 }
8870 }8741 }
88718742
8872 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");8743 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
8873 self.builder.positionBuilderAtEnd(entry_block);8744 self.builder.positionBuilderAtEnd(entry_block);
8874 self.builder.clearCurrentDebugLocation();8745 self.builder.clearCurrentDebugLocation();
88758746
8876 const fields = enum_ty.enumFields();8747 const fields = enum_ty.enumFields();
8877 const named_block = self.dg.context.appendBasicBlock(fn_val, "Named");8748 const named_block = self.context.appendBasicBlock(fn_val, "Named");
8878 const unnamed_block = self.dg.context.appendBasicBlock(fn_val, "Unnamed");8749 const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed");
8879 const tag_int_value = fn_val.getParam(0);8750 const tag_int_value = fn_val.getParam(0);
8880 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count()));8751 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 {...@@ -8893,10 +8764,10 @@ pub const FuncGen = struct {
8893 switch_instr.addCase(this_tag_int_value, named_block);8764 switch_instr.addCase(this_tag_int_value, named_block);
8894 }8765 }
8895 self.builder.positionBuilderAtEnd(named_block);8766 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
8898 self.builder.positionBuilderAtEnd(unnamed_block);8769 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));
8900 return fn_val;8771 return fn_val;
8901 }8772 }
89028773
...@@ -8955,12 +8826,12 @@ pub const FuncGen = struct {...@@ -8955,12 +8826,12 @@ pub const FuncGen = struct {
8955 }8826 }
8956 }8827 }
89578828
8958 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");8829 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
8959 self.builder.positionBuilderAtEnd(entry_block);8830 self.builder.positionBuilderAtEnd(entry_block);
8960 self.builder.clearCurrentDebugLocation();8831 self.builder.clearCurrentDebugLocation();
89618832
8962 const fields = enum_ty.enumFields();8833 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");
8964 const tag_int_value = fn_val.getParam(0);8835 const tag_int_value = fn_val.getParam(0);
8965 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count()));8836 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 {...@@ -8969,7 +8840,7 @@ pub const FuncGen = struct {
8969 };8840 };
89708841
8971 for (fields.keys()) |name, field_index| {8842 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);
8973 const str_init_llvm_ty = str_init.typeOf();8844 const str_init_llvm_ty = str_init.typeOf();
8974 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");8845 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
8975 str_global.setInitializer(str_init);8846 str_global.setInitializer(str_init);
...@@ -8990,7 +8861,7 @@ pub const FuncGen = struct {...@@ -8990,7 +8861,7 @@ pub const FuncGen = struct {
8990 slice_global.setUnnamedAddr(.True);8861 slice_global.setUnnamedAddr(.True);
8991 slice_global.setAlignment(slice_alignment);8862 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");
8994 const this_tag_int_value = int: {8865 const this_tag_int_value = int: {
8995 var tag_val_payload: Value.Payload.U32 = .{8866 var tag_val_payload: Value.Payload.U32 = .{
8996 .base = .{ .tag = .enum_field_index },8867 .base = .{ .tag = .enum_field_index },
...@@ -9042,7 +8913,7 @@ pub const FuncGen = struct {...@@ -9042,7 +8913,7 @@ pub const FuncGen = struct {
9042 const slice_llvm_ty = try self.dg.lowerType(slice_ty);8913 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
90438914
9044 const error_name_table_ptr = try self.getErrorNameTable();8915 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);
9046 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");8917 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");
9047 const indices = [_]*llvm.Value{operand};8918 const indices = [_]*llvm.Value{operand};
9048 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");8919 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
...@@ -9284,8 +9155,9 @@ pub const FuncGen = struct {...@@ -9284,8 +9155,9 @@ pub const FuncGen = struct {
9284 .Struct => {9155 .Struct => {
9285 if (result_ty.containerLayout() == .Packed) {9156 if (result_ty.containerLayout() == .Packed) {
9286 const struct_obj = result_ty.castTag(.@"struct").?.data;9157 const struct_obj = result_ty.castTag(.@"struct").?.data;
9158 assert(struct_obj.haveLayout());
9287 const big_bits = struct_obj.backing_int_ty.bitSize(target);9159 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));
9289 const fields = struct_obj.fields.values();9161 const fields = struct_obj.fields.values();
9290 comptime assert(Type.packed_struct_layout_version == 2);9162 comptime assert(Type.packed_struct_layout_version == 2);
9291 var running_int: *llvm.Value = int_llvm_ty.constNull();9163 var running_int: *llvm.Value = int_llvm_ty.constNull();
...@@ -9296,7 +9168,7 @@ pub const FuncGen = struct {...@@ -9296,7 +9168,7 @@ pub const FuncGen = struct {
92969168
9297 const non_int_val = try self.resolveInst(elem);9169 const non_int_val = try self.resolveInst(elem);
9298 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));9170 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);
9300 const small_int_val = if (field.ty.isPtrAtRuntime())9172 const small_int_val = if (field.ty.isPtrAtRuntime())
9301 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9173 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9302 else9174 else
...@@ -9410,11 +9282,11 @@ pub const FuncGen = struct {...@@ -9410,11 +9282,11 @@ pub const FuncGen = struct {
94109282
9411 if (union_obj.layout == .Packed) {9283 if (union_obj.layout == .Packed) {
9412 const big_bits = union_ty.bitSize(target);9284 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));
9414 const field = union_obj.fields.values()[extra.field_index];9286 const field = union_obj.fields.values()[extra.field_index];
9415 const non_int_val = try self.resolveInst(extra.init);9287 const non_int_val = try self.resolveInst(extra.init);
9416 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));9288 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);
9418 const small_int_val = if (field.ty.isPtrAtRuntime())9290 const small_int_val = if (field.ty.isPtrAtRuntime())
9419 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9291 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9420 else9292 else
...@@ -9444,9 +9316,9 @@ pub const FuncGen = struct {...@@ -9444,9 +9316,9 @@ pub const FuncGen = struct {
9444 }9316 }
9445 assert(isByRef(union_ty));9317 assert(isByRef(union_ty));
9446 // The llvm type of the alloca will be the named LLVM union type, and will not9318 // 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. We9319 // necessarily match the format that we need, depending on which tag is active.
9448 // must construct the correct unnamed struct type here and bitcast, in order to9320 // We must construct the correct unnamed struct type here, in order to then set
9449 // then set the fields appropriately.9321 // the fields appropriately.
9450 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);9322 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);
9451 const llvm_payload = try self.resolveInst(extra.init);9323 const llvm_payload = try self.resolveInst(extra.init);
9452 assert(union_obj.haveFieldTypes());9324 assert(union_obj.haveFieldTypes());
...@@ -9489,8 +9361,6 @@ pub const FuncGen = struct {...@@ -9489,8 +9361,6 @@ pub const FuncGen = struct {
9489 break :t self.context.structType(&fields, fields_len, .False);9361 break :t self.context.structType(&fields, fields_len, .False);
9490 };9362 };
94919363
9492 const casted_ptr = self.builder.buildBitCast(result_ptr, llvm_union_ty.pointerType(0), "");
9493
9494 // Now we follow the layout as expressed above with GEP instructions to set the9364 // Now we follow the layout as expressed above with GEP instructions to set the
9495 // tag and the payload.9365 // tag and the payload.
9496 const index_type = self.context.intType(32);9366 const index_type = self.context.intType(32);
...@@ -9510,7 +9380,7 @@ pub const FuncGen = struct {...@@ -9510,7 +9380,7 @@ pub const FuncGen = struct {
9510 index_type.constNull(),9380 index_type.constNull(),
9511 };9381 };
9512 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9382 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, "");
9514 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);9384 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
9515 return result_ptr;9385 return result_ptr;
9516 }9386 }
...@@ -9522,7 +9392,7 @@ pub const FuncGen = struct {...@@ -9522,7 +9392,7 @@ pub const FuncGen = struct {
9522 index_type.constNull(),9392 index_type.constNull(),
9523 };9393 };
9524 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9394 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, "");
9526 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);9396 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
9527 }9397 }
9528 {9398 {
...@@ -9530,7 +9400,7 @@ pub const FuncGen = struct {...@@ -9530,7 +9400,7 @@ pub const FuncGen = struct {
9530 index_type.constNull(),9400 index_type.constNull(),
9531 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),9401 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
9532 };9402 };
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, "");
9534 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);9404 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
9535 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);9405 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
9536 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);9406 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
...@@ -9579,8 +9449,7 @@ pub const FuncGen = struct {...@@ -9579,8 +9449,7 @@ pub const FuncGen = struct {
9579 .data => {},9449 .data => {},
9580 }9450 }
95819451
9582 const llvm_u8 = self.context.intType(8);9452 const llvm_ptr_u8 = self.context.pointerType(0);
9583 const llvm_ptr_u8 = llvm_u8.pointerType(0);
9584 const llvm_u32 = self.context.intType(32);9453 const llvm_u32 = self.context.intType(32);
95859454
9586 const llvm_fn_name = "llvm.prefetch.p0";9455 const llvm_fn_name = "llvm.prefetch.p0";
...@@ -9595,10 +9464,9 @@ pub const FuncGen = struct {...@@ -9595,10 +9464,9 @@ pub const FuncGen = struct {
9595 };9464 };
95969465
9597 const ptr = try self.resolveInst(prefetch.ptr);9466 const ptr = try self.resolveInst(prefetch.ptr);
9598 const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, "");
95999467
9600 const params = [_]*llvm.Value{9468 const params = [_]*llvm.Value{
9601 ptr_u8,9469 ptr,
9602 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),9470 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),
9603 llvm_u32.constInt(prefetch.locality, .False),9471 llvm_u32.constInt(prefetch.locality, .False),
9604 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),9472 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
...@@ -9625,8 +9493,7 @@ pub const FuncGen = struct {...@@ -9625,8 +9493,7 @@ pub const FuncGen = struct {
96259493
9626 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);9494 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
9627 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());9495 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());
9628 const llvm_slice_ty = try self.dg.lowerType(slice_ty);9496 const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space
9629 const llvm_slice_ptr_ty = llvm_slice_ty.pointerType(0); // TODO: Address space
96309497
9631 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");9498 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");
9632 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());9499 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
...@@ -9699,7 +9566,7 @@ pub const FuncGen = struct {...@@ -9699,7 +9566,7 @@ pub const FuncGen = struct {
9699 non_null_bit: *llvm.Value,9566 non_null_bit: *llvm.Value,
9700 ) !?*llvm.Value {9567 ) !?*llvm.Value {
9701 const optional_llvm_ty = try self.dg.lowerType(optional_ty);9568 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
9704 if (isByRef(optional_ty)) {9571 if (isByRef(optional_ty)) {
9705 const target = self.dg.module.getTarget();9572 const target = self.dg.module.getTarget();
...@@ -9740,31 +9607,24 @@ pub const FuncGen = struct {...@@ -9740,31 +9607,24 @@ pub const FuncGen = struct {
9740 .Packed => {9607 .Packed => {
9741 const result_ty = self.air.typeOfIndex(inst);9608 const result_ty = self.air.typeOfIndex(inst);
9742 const result_ty_info = result_ty.ptrInfo().data;9609 const result_ty_info = result_ty.ptrInfo().data;
9743 const result_llvm_ty = try self.dg.lowerType(result_ty);
97449610
9745 if (result_ty_info.host_size != 0) {9611 if (result_ty_info.host_size != 0) {
9746 // From LLVM's perspective, a pointer to a packed struct and a pointer9612 // From LLVM's perspective, a pointer to a packed struct and a pointer
9747 // to a field of a packed struct are the same. The difference is in the9613 // to a field of a packed struct are the same. The difference is in the
9748 // Zig pointer type which provides information for how to mask and shift9614 // Zig pointer type which provides information for how to mask and shift
9749 // out the relevant bits when accessing the pointee.9615 // out the relevant bits when accessing the pointee.
9750 // Here we perform a bitcast because we want to use the host_size9616 return struct_ptr;
9751 // as the llvm pointer element type.
9752 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
9753 }9617 }
97549618
9755 // We have a pointer to a packed struct field that happens to be byte-aligned.9619 // We have a pointer to a packed struct field that happens to be byte-aligned.
9756 // Offset our operand pointer by the correct number of bytes.9620 // Offset our operand pointer by the correct number of bytes.
9757 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);9621 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);
9758 if (byte_offset == 0) {9622 if (byte_offset == 0) return struct_ptr;
9759 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
9760 }
9761 const byte_llvm_ty = self.context.intType(8);9623 const byte_llvm_ty = self.context.intType(8);
9762 const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), "");
9763 const llvm_usize = try self.dg.lowerType(Type.usize);9624 const llvm_usize = try self.dg.lowerType(Type.usize);
9764 const llvm_index = llvm_usize.constInt(byte_offset, .False);9625 const llvm_index = llvm_usize.constInt(byte_offset, .False);
9765 const indices: [1]*llvm.Value = .{llvm_index};9626 const indices: [1]*llvm.Value = .{llvm_index};
9766 const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, "");9627 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
9767 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
9768 },9628 },
9769 else => {9629 else => {
9770 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);9630 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
...@@ -9777,39 +9637,25 @@ pub const FuncGen = struct {...@@ -9777,39 +9637,25 @@ pub const FuncGen = struct {
9777 // end of the struct. Treat our struct pointer as an array of two and get9637 // end of the struct. Treat our struct pointer as an array of two and get
9778 // the index to the element at index `1` to get a pointer to the end of9638 // the index to the element at index `1` to get a pointer to the end of
9779 // the struct.9639 // the struct.
9780 const llvm_u32 = self.dg.context.intType(32);9640 const llvm_u32 = self.context.intType(32);
9781 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);9641 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);
9782 const indices: [1]*llvm.Value = .{llvm_index};9642 const indices: [1]*llvm.Value = .{llvm_index};
9783 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");9643 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
9784 }9644 }
9785 },9645 },
9786 },9646 },
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 },
9788 else => unreachable,9655 else => unreachable,
9789 }9656 }
9790 }9657 }
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
9813 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {9659 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
9814 const id = llvm.lookupIntrinsicID(name.ptr, name.len);9660 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
9815 assert(id != 0);9661 assert(id != 0);
...@@ -9828,13 +9674,12 @@ pub const FuncGen = struct {...@@ -9828,13 +9674,12 @@ pub const FuncGen = struct {
9828 const target = fg.dg.module.getTarget();9674 const target = fg.dg.module.getTarget();
9829 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));9675 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
9830 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);9676 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
9831 const llvm_ptr_u8 = fg.context.intType(8).pointerType(0);
9832 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);9677 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);
9833 const size_bytes = pointee_type.abiSize(target);9678 const size_bytes = pointee_type.abiSize(target);
9834 _ = fg.builder.buildMemCpy(9679 _ = fg.builder.buildMemCpy(
9835 fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""),9680 result_ptr,
9836 result_align,9681 result_align,
9837 fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""),9682 ptr,
9838 ptr_alignment,9683 ptr_alignment,
9839 llvm_usize.constInt(size_bytes, .False),9684 llvm_usize.constInt(size_bytes, .False),
9840 is_volatile,9685 is_volatile,
...@@ -9855,7 +9700,7 @@ pub const FuncGen = struct {...@@ -9855,7 +9700,7 @@ pub const FuncGen = struct {
98559700
9856 assert(info.vector_index != .runtime);9701 assert(info.vector_index != .runtime);
9857 if (info.vector_index != .none) {9702 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);
9859 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);9704 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);
9860 const vec_ty = vec_elem_ty.vectorType(info.host_size);9705 const vec_ty = vec_elem_ty.vectorType(info.host_size);
98619706
...@@ -9878,8 +9723,7 @@ pub const FuncGen = struct {...@@ -9878,8 +9723,7 @@ pub const FuncGen = struct {
9878 }9723 }
98799724
9880 const int_elem_ty = self.context.intType(info.host_size * 8);9725 const int_elem_ty = self.context.intType(info.host_size * 8);
9881 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");9726 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9882 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
9883 containing_int.setAlignment(ptr_alignment);9727 containing_int.setAlignment(ptr_alignment);
9884 containing_int.setVolatile(ptr_volatile);9728 containing_int.setVolatile(ptr_volatile);
98859729
...@@ -9894,8 +9738,7 @@ pub const FuncGen = struct {...@@ -9894,8 +9738,7 @@ pub const FuncGen = struct {
98949738
9895 const same_size_int = self.context.intType(elem_bits);9739 const same_size_int = self.context.intType(elem_bits);
9896 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9740 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), "");9741 const store_inst = self.builder.buildStore(truncated_int, result_ptr);
9898 const store_inst = self.builder.buildStore(truncated_int, bitcasted_ptr);
9899 store_inst.setAlignment(result_align);9742 store_inst.setAlignment(result_align);
9900 return result_ptr;9743 return result_ptr;
9901 }9744 }
...@@ -9933,7 +9776,7 @@ pub const FuncGen = struct {...@@ -9933,7 +9776,7 @@ pub const FuncGen = struct {
99339776
9934 assert(info.vector_index != .runtime);9777 assert(info.vector_index != .runtime);
9935 if (info.vector_index != .none) {9778 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);
9937 const vec_elem_ty = try self.dg.lowerType(elem_ty);9780 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9938 const vec_ty = vec_elem_ty.vectorType(info.host_size);9781 const vec_ty = vec_elem_ty.vectorType(info.host_size);
99399782
...@@ -9952,8 +9795,7 @@ pub const FuncGen = struct {...@@ -9952,8 +9795,7 @@ pub const FuncGen = struct {
99529795
9953 if (info.host_size != 0) {9796 if (info.host_size != 0) {
9954 const int_elem_ty = self.context.intType(info.host_size * 8);9797 const int_elem_ty = self.context.intType(info.host_size * 8);
9955 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");9798 const containing_int = self.builder.buildLoad(int_elem_ty, ptr, "");
9956 const containing_int = self.builder.buildLoad(int_elem_ty, int_ptr, "");
9957 assert(ordering == .NotAtomic);9799 assert(ordering == .NotAtomic);
9958 containing_int.setAlignment(ptr_alignment);9800 containing_int.setAlignment(ptr_alignment);
9959 containing_int.setVolatile(ptr_volatile);9801 containing_int.setVolatile(ptr_volatile);
...@@ -9978,7 +9820,7 @@ pub const FuncGen = struct {...@@ -9978,7 +9820,7 @@ pub const FuncGen = struct {
9978 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");9820 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");
9979 const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, "");9821 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);
9982 assert(ordering == .NotAtomic);9824 assert(ordering == .NotAtomic);
9983 store_inst.setAlignment(ptr_alignment);9825 store_inst.setAlignment(ptr_alignment);
9984 store_inst.setVolatile(ptr_volatile);9826 store_inst.setVolatile(ptr_volatile);
...@@ -9992,12 +9834,11 @@ pub const FuncGen = struct {...@@ -9992,12 +9834,11 @@ pub const FuncGen = struct {
9992 return;9834 return;
9993 }9835 }
9994 assert(ordering == .NotAtomic);9836 assert(ordering == .NotAtomic);
9995 const llvm_ptr_u8 = self.context.intType(8).pointerType(0);
9996 const size_bytes = elem_ty.abiSize(target);9837 const size_bytes = elem_ty.abiSize(target);
9997 _ = self.builder.buildMemCpy(9838 _ = self.builder.buildMemCpy(
9998 self.builder.buildBitCast(ptr, llvm_ptr_u8, ""),9839 ptr,
9999 ptr_alignment,9840 ptr_alignment,
10000 self.builder.buildBitCast(elem, llvm_ptr_u8, ""),9841 elem,
10001 elem_ty.abiAlignment(target),9842 elem_ty.abiAlignment(target),
10002 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),9843 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),
10003 info.@"volatile",9844 info.@"volatile",
...@@ -11187,6 +11028,7 @@ fn compilerRtIntBits(bits: u16) u16 {...@@ -11187,6 +11028,7 @@ fn compilerRtIntBits(bits: u16) u16 {
11187}11028}
1118811029
11189fn buildAllocaInner(11030fn buildAllocaInner(
11031 context: *llvm.Context,
11190 builder: *llvm.Builder,11032 builder: *llvm.Builder,
11191 llvm_func: *llvm.Value,11033 llvm_func: *llvm.Value,
11192 di_scope_non_null: bool,11034 di_scope_non_null: bool,
...@@ -11224,7 +11066,7 @@ fn buildAllocaInner(...@@ -11224,7 +11066,7 @@ fn buildAllocaInner(
11224 // The pointer returned from this function should have the generic address space,11066 // The pointer returned from this function should have the generic address space,
11225 // if this isn't the case then cast it to the generic address space.11067 // if this isn't the case then cast it to the generic address space.
11226 if (address_space != llvm.address_space.default) {11068 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), "");
11228 }11070 }
1122911071
11230 return alloca;11072 return alloca;
src/codegen/llvm/bindings.zig-3
...@@ -287,9 +287,6 @@ pub const Type = opaque {...@@ -287,9 +287,6 @@ pub const Type = opaque {
287 pub const getUndef = LLVMGetUndef;287 pub const getUndef = LLVMGetUndef;
288 extern fn LLVMGetUndef(Ty: *Type) *Value;288 extern fn LLVMGetUndef(Ty: *Type) *Value;
289289
290 pub const pointerType = LLVMPointerType;
291 extern fn LLVMPointerType(ElementType: *Type, AddressSpace: c_uint) *Type;
292
293 pub const arrayType = LLVMArrayType;290 pub const arrayType = LLVMArrayType;
294 extern fn LLVMArrayType(ElementType: *Type, ElementCount: c_uint) *Type;291 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" {...@@ -1430,6 +1430,12 @@ test "struct has only one reference" {
1430 fn errorUnionStructReturn() error{Foo}!struct { x: u8 } {1430 fn errorUnionStructReturn() error{Foo}!struct { x: u8 } {
1431 return error.Foo;1431 return error.Foo;
1432 }1432 }
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
1433 fn optionalComptimeIntParam(comptime x: ?comptime_int) comptime_int {1439 fn optionalComptimeIntParam(comptime x: ?comptime_int) comptime_int {
1434 return x.?;1440 return x.?;
1435 }1441 }
...@@ -1446,6 +1452,14 @@ test "struct has only one reference" {...@@ -1446,6 +1452,14 @@ test "struct has only one reference" {
1446 const error_union_struct_return: *const anyopaque = &S.errorUnionStructReturn;1452 const error_union_struct_return: *const anyopaque = &S.errorUnionStructReturn;
1447 try expect(optional_struct_return != error_union_struct_return);1453 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
1449 try expectEqual(@alignOf(struct {}), S.optionalComptimeIntParam(@alignOf(struct {})));1463 try expectEqual(@alignOf(struct {}), S.optionalComptimeIntParam(@alignOf(struct {})));
1450 try expectEqual(@alignOf(struct { x: u8 }), S.errorUnionComptimeIntParam(@alignOf(struct { x: u8 })));1464 try expectEqual(@alignOf(struct { x: u8 }), S.errorUnionComptimeIntParam(@alignOf(struct { x: u8 })));
1451 try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 })));1465 try expectEqual(@sizeOf(struct { x: u16 }), S.optionalComptimeIntParam(@sizeOf(struct { x: u16 })));