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

llvm: cleanup code no longer needed with opaque pointers

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

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

src/codegen/llvm.zig+165-327
...@@ -582,7 +582,7 @@ pub const Object = struct {...@@ -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);
...@@ -2477,12 +2467,8 @@ pub const DeclGen = struct {...@@ -2477,12 +2467,8 @@ pub const DeclGen = struct {
2477 new_global.setAlignment(global.getAlignment());2467 new_global.setAlignment(global.getAlignment());
2478 if (decl.@"linksection") |section| new_global.setSection(section);2468 if (decl.@"linksection") |section| new_global.setSection(section);
2479 new_global.setInitializer(llvm_init);2469 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?2470 // TODO: How should this work then the address space of a global changed?
2484 const new_global_ptr = new_global.constBitCast(global.typeOf());2471 global.replaceAllUsesWith(new_global);
2485 global.replaceAllUsesWith(new_global_ptr);
2486 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);2472 dg.object.decl_map.putAssumeCapacity(decl_index, new_global);
2487 new_global.takeName(global);2473 new_global.takeName(global);
2488 global.deleteGlobal();2474 global.deleteGlobal();
...@@ -2781,11 +2767,7 @@ pub const DeclGen = struct {...@@ -2781,11 +2767,7 @@ pub const DeclGen = struct {
2781 }2767 }
2782 const ptr_info = t.ptrInfo().data;2768 const ptr_info = t.ptrInfo().data;
2783 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);2769 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);
2784 if (ptr_info.host_size != 0) {2770 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 },2771 },
2790 .Opaque => switch (t.tag()) {2772 .Opaque => switch (t.tag()) {
2791 .@"opaque" => {2773 .@"opaque" => {
...@@ -3108,8 +3090,7 @@ pub const DeclGen = struct {...@@ -3108,8 +3090,7 @@ pub const DeclGen = struct {
3108 defer llvm_params.deinit();3090 defer llvm_params.deinit();
31093091
3110 if (firstParamSRet(fn_info, target)) {3092 if (firstParamSRet(fn_info, target)) {
3111 const llvm_sret_ty = try dg.lowerType(fn_info.return_type);3093 try llvm_params.append(dg.context.pointerType(0));
3112 try llvm_params.append(llvm_sret_ty.pointerType(0));
3113 }3094 }
31143095
3115 if (fn_info.return_type.isError() and3096 if (fn_info.return_type.isError() and
...@@ -3131,9 +3112,7 @@ pub const DeclGen = struct {...@@ -3131,9 +3112,7 @@ pub const DeclGen = struct {
3131 try llvm_params.append(try dg.lowerType(param_ty));3112 try llvm_params.append(try dg.lowerType(param_ty));
3132 },3113 },
3133 .byref, .byref_mut => {3114 .byref, .byref_mut => {
3134 const param_ty = fn_info.param_types[it.zig_index - 1];3115 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 },3116 },
3138 .abi_sized_int => {3117 .abi_sized_int => {
3139 const param_ty = fn_info.param_types[it.zig_index - 1];3118 const param_ty = fn_info.param_types[it.zig_index - 1];
...@@ -3323,16 +3302,12 @@ pub const DeclGen = struct {...@@ -3323,16 +3302,12 @@ pub const DeclGen = struct {
3323 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);3302 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
3324 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);3303 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
33253304
3326 const llvm_var_type = try dg.lowerType(tv.ty);
3327 const llvm_actual_ptr_type = llvm_var_type.pointerType(llvm_actual_addrspace);
3328
3329 const val = try dg.resolveGlobalDecl(decl_index);3305 const val = try dg.resolveGlobalDecl(decl_index);
3330 const val_ptr = val.constBitCast(llvm_actual_ptr_type);3306 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
3331 if (llvm_actual_addrspace != llvm_wanted_addrspace) {3307 val.constAddrSpaceCast(dg.context.pointerType(llvm_wanted_addrspace))
3332 const llvm_wanted_ptr_type = llvm_var_type.pointerType(llvm_wanted_addrspace);3308 else
3333 return val_ptr.constAddrSpaceCast(llvm_wanted_ptr_type);3309 val;
3334 }3310 return addrspace_casted_ptr;
3335 return val_ptr;
3336 },3311 },
3337 .slice => {3312 .slice => {
3338 const slice = tv.val.castTag(.slice).?.data;3313 const slice = tv.val.castTag(.slice).?.data;
...@@ -3355,7 +3330,7 @@ pub const DeclGen = struct {...@@ -3355,7 +3330,7 @@ pub const DeclGen = struct {
3355 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));3330 return llvm_int.constIntToPtr(try dg.lowerType(tv.ty));
3356 },3331 },
3357 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {3332 .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => {
3358 return dg.lowerParentPtr(tv.val, tv.ty.childType());3333 return dg.lowerParentPtr(tv.val);
3359 },3334 },
3360 .null_value, .zero => {3335 .null_value, .zero => {
3361 const llvm_type = try dg.lowerType(tv.ty);3336 const llvm_type = try dg.lowerType(tv.ty);
...@@ -3363,7 +3338,7 @@ pub const DeclGen = struct {...@@ -3363,7 +3338,7 @@ pub const DeclGen = struct {
3363 },3338 },
3364 .opt_payload => {3339 .opt_payload => {
3365 const payload = tv.val.castTag(.opt_payload).?.data;3340 const payload = tv.val.castTag(.opt_payload).?.data;
3366 return dg.lowerParentPtr(payload, tv.ty);3341 return dg.lowerParentPtr(payload);
3367 },3342 },
3368 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{3343 else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{
3369 tv.ty.fmtDebug(), tag,3344 tv.ty.fmtDebug(), tag,
...@@ -3940,7 +3915,6 @@ pub const DeclGen = struct {...@@ -3940,7 +3915,6 @@ pub const DeclGen = struct {
3940 dg: *DeclGen,3915 dg: *DeclGen,
3941 ptr_val: Value,3916 ptr_val: Value,
3942 decl_index: Module.Decl.Index,3917 decl_index: Module.Decl.Index,
3943 ptr_child_ty: Type,
3944 ) Error!*llvm.Value {3918 ) Error!*llvm.Value {
3945 const decl = dg.module.declPtr(decl_index);3919 const decl = dg.module.declPtr(decl_index);
3946 dg.module.markDeclAlive(decl);3920 dg.module.markDeclAlive(decl);
...@@ -3949,62 +3923,54 @@ pub const DeclGen = struct {...@@ -3949,62 +3923,54 @@ pub const DeclGen = struct {
3949 .data = decl.ty,3923 .data = decl.ty,
3950 };3924 };
3951 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);3925 const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
3952 const llvm_ptr = try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);3926 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 }3927 }
39603928
3961 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value {3929 fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value {
3962 const target = dg.module.getTarget();3930 const target = dg.module.getTarget();
3963 var bitcast_needed: bool = undefined;3931 switch (ptr_val.tag()) {
3964 const llvm_ptr = switch (ptr_val.tag()) {
3965 .decl_ref_mut => {3932 .decl_ref_mut => {
3966 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;3933 const decl = ptr_val.castTag(.decl_ref_mut).?.data.decl_index;
3967 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);3934 return dg.lowerParentPtrDecl(ptr_val, decl);
3968 },3935 },
3969 .decl_ref => {3936 .decl_ref => {
3970 const decl = ptr_val.castTag(.decl_ref).?.data;3937 const decl = ptr_val.castTag(.decl_ref).?.data;
3971 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);3938 return dg.lowerParentPtrDecl(ptr_val, decl);
3972 },3939 },
3973 .variable => {3940 .variable => {
3974 const decl = ptr_val.castTag(.variable).?.data.owner_decl;3941 const decl = ptr_val.castTag(.variable).?.data.owner_decl;
3975 return dg.lowerParentPtrDecl(ptr_val, decl, ptr_child_ty);3942 return dg.lowerParentPtrDecl(ptr_val, decl);
3976 },3943 },
3977 .int_i64 => {3944 .int_i64 => {
3978 const int = ptr_val.castTag(.int_i64).?.data;3945 const int = ptr_val.castTag(.int_i64).?.data;
3979 const llvm_usize = try dg.lowerType(Type.usize);3946 const llvm_usize = try dg.lowerType(Type.usize);
3980 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);3947 const llvm_int = llvm_usize.constInt(@bitCast(u64, int), .False);
3981 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));3948 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3982 },3949 },
3983 .int_u64 => {3950 .int_u64 => {
3984 const int = ptr_val.castTag(.int_u64).?.data;3951 const int = ptr_val.castTag(.int_u64).?.data;
3985 const llvm_usize = try dg.lowerType(Type.usize);3952 const llvm_usize = try dg.lowerType(Type.usize);
3986 const llvm_int = llvm_usize.constInt(int, .False);3953 const llvm_int = llvm_usize.constInt(int, .False);
3987 return llvm_int.constIntToPtr((try dg.lowerType(ptr_child_ty)).pointerType(0));3954 return llvm_int.constIntToPtr(dg.context.pointerType(0));
3988 },3955 },
3989 .field_ptr => blk: {3956 .field_ptr => {
3990 const field_ptr = ptr_val.castTag(.field_ptr).?.data;3957 const field_ptr = ptr_val.castTag(.field_ptr).?.data;
3991 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, field_ptr.container_ty);3958 const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr);
3992 const parent_ty = field_ptr.container_ty;3959 const parent_ty = field_ptr.container_ty;
39933960
3994 const field_index = @intCast(u32, field_ptr.field_index);3961 const field_index = @intCast(u32, field_ptr.field_index);
3995 const llvm_u32 = dg.context.intType(32);3962 const llvm_u32 = dg.context.intType(32);
3996 switch (parent_ty.zigTypeTag()) {3963 switch (parent_ty.zigTypeTag()) {
3997 .Union => {3964 .Union => {
3998 bitcast_needed = true;
3999 if (parent_ty.containerLayout() == .Packed) {3965 if (parent_ty.containerLayout() == .Packed) {
4000 break :blk parent_llvm_ptr;3966 return parent_llvm_ptr;
4001 }3967 }
40023968
4003 const layout = parent_ty.unionGetLayout(target);3969 const layout = parent_ty.unionGetLayout(target);
4004 if (layout.payload_size == 0) {3970 if (layout.payload_size == 0) {
4005 // In this case a pointer to the union and a pointer to any3971 // In this case a pointer to the union and a pointer to any
4006 // (void) payload is the same.3972 // (void) payload is the same.
4007 break :blk parent_llvm_ptr;3973 return parent_llvm_ptr;
4008 }3974 }
4009 const llvm_pl_index = if (layout.tag_size == 0)3975 const llvm_pl_index = if (layout.tag_size == 0)
4010 03976 0
...@@ -4015,10 +3981,9 @@ pub const DeclGen = struct {...@@ -4015,10 +3981,9 @@ pub const DeclGen = struct {
4015 llvm_u32.constInt(llvm_pl_index, .False),3981 llvm_u32.constInt(llvm_pl_index, .False),
4016 };3982 };
4017 const parent_llvm_ty = try dg.lowerType(parent_ty);3983 const parent_llvm_ty = try dg.lowerType(parent_ty);
4018 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);3984 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4019 },3985 },
4020 .Struct => {3986 .Struct => {
4021 const field_ty = parent_ty.structFieldType(field_index);
4022 if (parent_ty.containerLayout() == .Packed) {3987 if (parent_ty.containerLayout() == .Packed) {
4023 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());3988 const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
4024 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);3989 const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
...@@ -4033,26 +3998,23 @@ pub const DeclGen = struct {...@@ -4033,26 +3998,23 @@ pub const DeclGen = struct {
4033 };3998 };
4034 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);3999 const byte_offset = llvm_usize.constInt(prev_bits / 8, .False);
4035 const field_addr = base_addr.constAdd(byte_offset);4000 const field_addr = base_addr.constAdd(byte_offset);
4036 bitcast_needed = false;4001 const final_llvm_ty = dg.context.pointerType(0);
4037 const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0);4002 return field_addr.constIntToPtr(final_llvm_ty);
4038 break :blk field_addr.constIntToPtr(final_llvm_ty);
4039 }4003 }
40404004
4041 var ty_buf: Type.Payload.Pointer = undefined;4005 var ty_buf: Type.Payload.Pointer = undefined;
40424006
4043 const parent_llvm_ty = try dg.lowerType(parent_ty);4007 const parent_llvm_ty = try dg.lowerType(parent_ty);
4044 if (llvmFieldIndex(parent_ty, field_index, target, &ty_buf)) |llvm_field_index| {4008 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 = .{4009 const indices: [2]*llvm.Value = .{
4047 llvm_u32.constInt(0, .False),4010 llvm_u32.constInt(0, .False),
4048 llvm_u32.constInt(llvm_field_index, .False),4011 llvm_u32.constInt(llvm_field_index, .False),
4049 };4012 };
4050 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4013 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4051 } else {4014 } else {
4052 bitcast_needed = !parent_ty.eql(ptr_child_ty, dg.module);
4053 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);4015 const llvm_index = llvm_u32.constInt(@boolToInt(parent_ty.hasRuntimeBitsIgnoreComptime()), .False);
4054 const indices: [1]*llvm.Value = .{llvm_index};4016 const indices: [1]*llvm.Value = .{llvm_index};
4055 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4017 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4056 }4018 }
4057 },4019 },
4058 .Pointer => {4020 .Pointer => {
...@@ -4062,37 +4024,34 @@ pub const DeclGen = struct {...@@ -4062,37 +4024,34 @@ pub const DeclGen = struct {
4062 llvm_u32.constInt(field_index, .False),4024 llvm_u32.constInt(field_index, .False),
4063 };4025 };
4064 const parent_llvm_ty = try dg.lowerType(parent_ty);4026 const parent_llvm_ty = try dg.lowerType(parent_ty);
4065 break :blk parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4027 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4066 },4028 },
4067 else => unreachable,4029 else => unreachable,
4068 }4030 }
4069 },4031 },
4070 .elem_ptr => blk: {4032 .elem_ptr => {
4071 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;4033 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);4034 const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr);
4073 bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module);
40744035
4075 const llvm_usize = try dg.lowerType(Type.usize);4036 const llvm_usize = try dg.lowerType(Type.usize);
4076 const indices: [1]*llvm.Value = .{4037 const indices: [1]*llvm.Value = .{
4077 llvm_usize.constInt(elem_ptr.index, .False),4038 llvm_usize.constInt(elem_ptr.index, .False),
4078 };4039 };
4079 const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);4040 const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty);
4080 break :blk elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4041 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4081 },4042 },
4082 .opt_payload_ptr => blk: {4043 .opt_payload_ptr => {
4083 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;4044 const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
4084 const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, opt_payload_ptr.container_ty);4045 const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr);
4085 var buf: Type.Payload.ElemType = undefined;4046 var buf: Type.Payload.ElemType = undefined;
40864047
4087 const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf);4048 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() or4049 if (!payload_ty.hasRuntimeBitsIgnoreComptime() or
4091 payload_ty.optionalReprIsPayload())4050 payload_ty.optionalReprIsPayload())
4092 {4051 {
4093 // In this case, we represent pointer to optional the same as pointer4052 // In this case, we represent pointer to optional the same as pointer
4094 // to the payload.4053 // to the payload.
4095 break :blk parent_llvm_ptr;4054 return parent_llvm_ptr;
4096 }4055 }
40974056
4098 const llvm_u32 = dg.context.intType(32);4057 const llvm_u32 = dg.context.intType(32);
...@@ -4101,19 +4060,17 @@ pub const DeclGen = struct {...@@ -4101,19 +4060,17 @@ pub const DeclGen = struct {
4101 llvm_u32.constInt(0, .False),4060 llvm_u32.constInt(0, .False),
4102 };4061 };
4103 const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty);4062 const opt_llvm_ty = try dg.lowerType(opt_payload_ptr.container_ty);
4104 break :blk opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4063 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4105 },4064 },
4106 .eu_payload_ptr => blk: {4065 .eu_payload_ptr => {
4107 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;4066 const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
4108 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, eu_payload_ptr.container_ty);4067 const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr);
41094068
4110 const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload();4069 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()) {4070 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4114 // In this case, we represent pointer to error union the same as pointer4071 // In this case, we represent pointer to error union the same as pointer
4115 // to the payload.4072 // to the payload.
4116 break :blk parent_llvm_ptr;4073 return parent_llvm_ptr;
4117 }4074 }
41184075
4119 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;4076 const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1;
...@@ -4123,14 +4080,9 @@ pub const DeclGen = struct {...@@ -4123,14 +4080,9 @@ pub const DeclGen = struct {
4123 llvm_u32.constInt(payload_offset, .False),4080 llvm_u32.constInt(payload_offset, .False),
4124 };4081 };
4125 const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty);4082 const eu_llvm_ty = try dg.lowerType(eu_payload_ptr.container_ty);
4126 break :blk eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);4083 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
4127 },4084 },
4128 else => unreachable,4085 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 }4086 }
4135 }4087 }
41364088
...@@ -4189,8 +4141,7 @@ pub const DeclGen = struct {...@@ -4189,8 +4141,7 @@ pub const DeclGen = struct {
4189 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);4141 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
4190 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);4142 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
4191 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {4143 const llvm_val = if (llvm_wanted_addrspace != llvm_actual_addrspace) blk: {
4192 const llvm_decl_ty = try self.lowerType(decl.ty);4144 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);4145 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
4195 } else llvm_decl_val;4146 } else llvm_decl_val;
41964147
...@@ -4471,18 +4422,11 @@ pub const FuncGen = struct {...@@ -4471,18 +4422,11 @@ pub const FuncGen = struct {
4471 global.setGlobalConstant(.True);4422 global.setGlobalConstant(.True);
4472 global.setUnnamedAddr(.True);4423 global.setUnnamedAddr(.True);
4473 global.setAlignment(tv.ty.abiAlignment(target));4424 global.setAlignment(tv.ty.abiAlignment(target));
4474 // Because of LLVM limitations for lowering certain types such as unions,4425 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 to4426 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 else4427 else
4484 bitcasted_ptr;4428 global;
4485 return casted_ptr;4429 return addrspace_casted_ptr;
4486 }4430 }
44874431
4488 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4432 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
...@@ -4770,17 +4714,7 @@ pub const FuncGen = struct {...@@ -4770,17 +4714,7 @@ pub const FuncGen = struct {
4770 load_inst.setAlignment(alignment);4714 load_inst.setAlignment(alignment);
4771 try llvm_args.append(load_inst);4715 try llvm_args.append(load_inst);
4772 } else {4716 } else {
4773 if (param_ty.zigTypeTag() == .Pointer) {4717 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 }4718 }
4785 },4719 },
4786 .byref => {4720 .byref => {
...@@ -4824,26 +4758,22 @@ pub const FuncGen = struct {...@@ -4824,26 +4758,22 @@ pub const FuncGen = struct {
4824 const param_ty = self.air.typeOf(arg);4758 const param_ty = self.air.typeOf(arg);
4825 const llvm_arg = try self.resolveInst(arg);4759 const llvm_arg = try self.resolveInst(arg);
4826 const abi_size = @intCast(c_uint, param_ty.abiSize(target));4760 const abi_size = @intCast(c_uint, param_ty.abiSize(target));
4827 const int_llvm_ty = self.dg.context.intType(abi_size * 8);4761 const int_llvm_ty = self.context.intType(abi_size * 8);
4828 const int_ptr_llvm_ty = int_llvm_ty.pointerType(0);
48294762
4830 if (isByRef(param_ty)) {4763 if (isByRef(param_ty)) {
4831 const alignment = param_ty.abiAlignment(target);4764 const alignment = param_ty.abiAlignment(target);
4832 const casted_ptr = self.builder.buildBitCast(llvm_arg, int_ptr_llvm_ty, "");4765 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);4766 load_inst.setAlignment(alignment);
4835 try llvm_args.append(load_inst);4767 try llvm_args.append(load_inst);
4836 } else {4768 } else {
4837 // LLVM does not allow bitcasting structs so we must allocate4769 // LLVM does not allow bitcasting structs so we must allocate
4838 // a local, bitcast its pointer, store, and then load.4770 // a local, store as one type, and then load as another type.
4839 const alignment = @max(4771 const alignment = @max(
4840 param_ty.abiAlignment(target),4772 param_ty.abiAlignment(target),
4841 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),4773 self.dg.object.target_data.abiAlignmentOfType(int_llvm_ty),
4842 );4774 );
4843 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);4775 const int_ptr = self.buildAlloca(int_llvm_ty, alignment);
4844 const param_llvm_ty = try self.dg.lowerType(param_ty);4776 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);4777 store_inst.setAlignment(alignment);
4848 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");4778 const load_inst = self.builder.buildLoad(int_llvm_ty, int_ptr, "");
4849 load_inst.setAlignment(alignment);4779 load_inst.setAlignment(alignment);
...@@ -4872,12 +4802,11 @@ pub const FuncGen = struct {...@@ -4872,12 +4802,11 @@ pub const FuncGen = struct {
4872 break :p p;4802 break :p p;
4873 };4803 };
48744804
4875 const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);4805 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);4806 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
4878 for (llvm_types) |field_ty, i_usize| {4807 for (llvm_types) |field_ty, i_usize| {
4879 const i = @intCast(c_uint, i_usize);4808 const i = @intCast(c_uint, i_usize);
4880 const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, "");4809 const field_ptr = self.builder.buildStructGEP(llvm_ty, arg_ptr, i, "");
4881 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");4810 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");
4882 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);4811 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
4883 llvm_args.appendAssumeCapacity(load_inst);4812 llvm_args.appendAssumeCapacity(load_inst);
...@@ -4886,7 +4815,7 @@ pub const FuncGen = struct {...@@ -4886,7 +4815,7 @@ pub const FuncGen = struct {
4886 .as_u16 => {4815 .as_u16 => {
4887 const arg = args[it.zig_index - 1];4816 const arg = args[it.zig_index - 1];
4888 const llvm_arg = try self.resolveInst(arg);4817 const llvm_arg = try self.resolveInst(arg);
4889 const casted = self.builder.buildBitCast(llvm_arg, self.dg.context.intType(16), "");4818 const casted = self.builder.buildBitCast(llvm_arg, self.context.intType(16), "");
4890 try llvm_args.append(casted);4819 try llvm_args.append(casted);
4891 },4820 },
4892 .float_array => |count| {4821 .float_array => |count| {
...@@ -4903,9 +4832,8 @@ pub const FuncGen = struct {...@@ -4903,9 +4832,8 @@ pub const FuncGen = struct {
4903 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);4832 const float_ty = try self.dg.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty).?);
4904 const array_llvm_ty = float_ty.arrayType(count);4833 const array_llvm_ty = float_ty.arrayType(count);
49054834
4906 const casted = self.builder.buildBitCast(llvm_arg, array_llvm_ty.pointerType(0), "");
4907 const alignment = arg_ty.abiAlignment(target);4835 const alignment = arg_ty.abiAlignment(target);
4908 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");4836 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
4909 load_inst.setAlignment(alignment);4837 load_inst.setAlignment(alignment);
4910 try llvm_args.append(load_inst);4838 try llvm_args.append(load_inst);
4911 },4839 },
...@@ -4921,10 +4849,9 @@ pub const FuncGen = struct {...@@ -4921,10 +4849,9 @@ pub const FuncGen = struct {
4921 llvm_arg = store_inst;4849 llvm_arg = store_inst;
4922 }4850 }
49234851
4924 const array_llvm_ty = self.dg.context.intType(elem_size).arrayType(arr_len);4852 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);4853 const alignment = arg_ty.abiAlignment(target);
4927 const load_inst = self.builder.buildLoad(array_llvm_ty, casted, "");4854 const load_inst = self.builder.buildLoad(array_llvm_ty, llvm_arg, "");
4928 load_inst.setAlignment(alignment);4855 load_inst.setAlignment(alignment);
4929 try llvm_args.append(load_inst);4856 try llvm_args.append(load_inst);
4930 },4857 },
...@@ -5028,12 +4955,10 @@ pub const FuncGen = struct {...@@ -5028,12 +4955,10 @@ pub const FuncGen = struct {
5028 if (abi_ret_ty != llvm_ret_ty) {4955 if (abi_ret_ty != llvm_ret_ty) {
5029 // In this case the function return type is honoring the calling convention by having4956 // 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 callsite4957 // a different LLVM type than the usual one. We solve this here at the callsite
5031 // by bitcasting a pointer to our canonical type, then loading it if necessary.4958 // by using our canonical type, then loading it if necessary.
5032 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);4959 const alignment = self.dg.object.target_data.abiAlignmentOfType(abi_ret_ty);
5033 const rp = self.buildAlloca(llvm_ret_ty, alignment);4960 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5034 const ptr_abi_ty = abi_ret_ty.pointerType(0);4961 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);4962 store_inst.setAlignment(alignment);
5038 if (isByRef(return_type)) {4963 if (isByRef(return_type)) {
5039 return rp;4964 return rp;
...@@ -5086,7 +5011,6 @@ pub const FuncGen = struct {...@@ -5086,7 +5011,6 @@ pub const FuncGen = struct {
5086 }5011 }
50875012
5088 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5013 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);5014 const operand = try self.resolveInst(un_op);
5091 const target = self.dg.module.getTarget();5015 const target = self.dg.module.getTarget();
5092 const alignment = ret_ty.abiAlignment(target);5016 const alignment = ret_ty.abiAlignment(target);
...@@ -5094,8 +5018,7 @@ pub const FuncGen = struct {...@@ -5094,8 +5018,7 @@ pub const FuncGen = struct {
5094 if (isByRef(ret_ty)) {5018 if (isByRef(ret_ty)) {
5095 // operand is a pointer however self.ret_ptr is null so that means5019 // operand is a pointer however self.ret_ptr is null so that means
5096 // we need to return a value.5020 // we need to return a value.
5097 const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");5021 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);5022 load_inst.setAlignment(alignment);
5100 _ = self.builder.buildRet(load_inst);5023 _ = self.builder.buildRet(load_inst);
5101 return null;5024 return null;
...@@ -5110,8 +5033,7 @@ pub const FuncGen = struct {...@@ -5110,8 +5033,7 @@ pub const FuncGen = struct {
5110 const rp = self.buildAlloca(llvm_ret_ty, alignment);5033 const rp = self.buildAlloca(llvm_ret_ty, alignment);
5111 const store_inst = self.builder.buildStore(operand, rp);5034 const store_inst = self.builder.buildStore(operand, rp);
5112 store_inst.setAlignment(alignment);5035 store_inst.setAlignment(alignment);
5113 const casted_ptr = self.builder.buildBitCast(rp, ptr_abi_ty, "");5036 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);5037 load_inst.setAlignment(alignment);
5116 _ = self.builder.buildRet(load_inst);5038 _ = self.builder.buildRet(load_inst);
5117 return null;5039 return null;
...@@ -5141,12 +5063,7 @@ pub const FuncGen = struct {...@@ -5141,12 +5063,7 @@ pub const FuncGen = struct {
5141 const ptr = try self.resolveInst(un_op);5063 const ptr = try self.resolveInst(un_op);
5142 const target = self.dg.module.getTarget();5064 const target = self.dg.module.getTarget();
5143 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);5065 const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
5144 const llvm_ret_ty = try self.dg.lowerType(ret_ty);5066 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));5067 loaded.setAlignment(ret_ty.abiAlignment(target));
5151 _ = self.builder.buildRet(loaded);5068 _ = self.builder.buildRet(loaded);
5152 return null;5069 return null;
...@@ -5178,8 +5095,8 @@ pub const FuncGen = struct {...@@ -5178,8 +5095,8 @@ pub const FuncGen = struct {
5178 const llvm_fn_name = "llvm.va_copy";5095 const llvm_fn_name = "llvm.va_copy";
5179 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5096 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5180 const param_types = [_]*llvm.Type{5097 const param_types = [_]*llvm.Type{
5181 self.dg.context.intType(8).pointerType(0),5098 self.context.pointerType(0),
5182 self.dg.context.intType(8).pointerType(0),5099 self.context.pointerType(0),
5183 };5100 };
5184 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5101 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);5102 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
...@@ -5203,7 +5120,7 @@ pub const FuncGen = struct {...@@ -5203,7 +5120,7 @@ pub const FuncGen = struct {
52035120
5204 const llvm_fn_name = "llvm.va_end";5121 const llvm_fn_name = "llvm.va_end";
5205 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5122 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5206 const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)};5123 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5207 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5124 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);5125 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
5209 };5126 };
...@@ -5224,7 +5141,7 @@ pub const FuncGen = struct {...@@ -5224,7 +5141,7 @@ pub const FuncGen = struct {
52245141
5225 const llvm_fn_name = "llvm.va_start";5142 const llvm_fn_name = "llvm.va_start";
5226 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {5143 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
5227 const param_types = [_]*llvm.Type{self.dg.context.intType(8).pointerType(0)};5144 const param_types = [_]*llvm.Type{self.context.pointerType(0)};
5228 const fn_type = llvm.functionType(self.context.voidType(), &param_types, param_types.len, .False);5145 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);5146 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
5230 };5147 };
...@@ -5417,7 +5334,7 @@ pub const FuncGen = struct {...@@ -5417,7 +5334,7 @@ pub const FuncGen = struct {
5417 // of function pointers, however the phi makes it a runtime value and therefore5334 // of function pointers, however the phi makes it a runtime value and therefore
5418 // the LLVM type has to be wrapped in a pointer.5335 // the LLVM type has to be wrapped in a pointer.
5419 if (is_body or isByRef(inst_ty)) {5336 if (is_body or isByRef(inst_ty)) {
5420 break :ty raw_llvm_ty.pointerType(0);5337 break :ty self.context.pointerType(0);
5421 }5338 }
5422 break :ty raw_llvm_ty;5339 break :ty raw_llvm_ty;
5423 };5340 };
...@@ -5482,7 +5399,7 @@ pub const FuncGen = struct {...@@ -5482,7 +5399,7 @@ pub const FuncGen = struct {
5482 const payload_ty = self.air.typeOfIndex(inst);5399 const payload_ty = self.air.typeOfIndex(inst);
5483 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;5400 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
5484 const is_unused = self.liveness.isUnused(inst);5401 const is_unused = self.liveness.isUnused(inst);
5485 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty);5402 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused);
5486 }5403 }
54875404
5488 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5405 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -5491,9 +5408,8 @@ pub const FuncGen = struct {...@@ -5491,9 +5408,8 @@ pub const FuncGen = struct {
5491 const err_union_ptr = try self.resolveInst(extra.data.ptr);5408 const err_union_ptr = try self.resolveInst(extra.data.ptr);
5492 const body = self.air.extra[extra.end..][0..extra.data.body_len];5409 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5493 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();5410 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);5411 const is_unused = self.liveness.isUnused(inst);
5496 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty);5412 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused);
5497 }5413 }
54985414
5499 fn lowerTry(5415 fn lowerTry(
...@@ -5504,7 +5420,6 @@ pub const FuncGen = struct {...@@ -5504,7 +5420,6 @@ pub const FuncGen = struct {
5504 operand_is_ptr: bool,5420 operand_is_ptr: bool,
5505 can_elide_load: bool,5421 can_elide_load: bool,
5506 is_unused: bool,5422 is_unused: bool,
5507 result_ty: Type,
5508 ) !?*llvm.Value {5423 ) !?*llvm.Value {
5509 const payload_ty = err_union_ty.errorUnionPayload();5424 const payload_ty = err_union_ty.errorUnionPayload();
5510 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();5425 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime();
...@@ -5547,12 +5462,7 @@ pub const FuncGen = struct {...@@ -5547,12 +5462,7 @@ pub const FuncGen = struct {
5547 return null;5462 return null;
5548 }5463 }
5549 if (!payload_has_bits) {5464 if (!payload_has_bits) {
5550 if (!operand_is_ptr) return null;5465 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 }5466 }
5557 const offset = errUnionPayloadOffset(payload_ty, target);5467 const offset = errUnionPayloadOffset(payload_ty, target);
5558 if (operand_is_ptr) {5468 if (operand_is_ptr) {
...@@ -6038,9 +5948,8 @@ pub const FuncGen = struct {...@@ -6038,9 +5948,8 @@ pub const FuncGen = struct {
6038 const union_llvm_ty = try self.dg.lowerType(struct_ty);5948 const union_llvm_ty = try self.dg.lowerType(struct_ty);
6039 const layout = struct_ty.unionGetLayout(target);5949 const layout = struct_ty.unionGetLayout(target);
6040 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);5950 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
6041 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");5951 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
6042 const llvm_field_ty = try self.dg.lowerType(field_ty);5952 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)) {5953 if (isByRef(field_ty)) {
6045 if (canElideLoad(self, body_tail))5954 if (canElideLoad(self, body_tail))
6046 return field_ptr;5955 return field_ptr;
...@@ -6068,7 +5977,7 @@ pub const FuncGen = struct {...@@ -6068,7 +5977,7 @@ pub const FuncGen = struct {
60685977
6069 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));5978 const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty));
6070 if (field_offset == 0) {5979 if (field_offset == 0) {
6071 return self.builder.buildBitCast(field_ptr, res_ty, "");5980 return field_ptr;
6072 }5981 }
6073 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());5982 const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth());
60745983
...@@ -6635,7 +6544,7 @@ pub const FuncGen = struct {...@@ -6635,7 +6544,7 @@ pub const FuncGen = struct {
6635 self.builder.buildLoad(optional_llvm_ty, operand, "")6544 self.builder.buildLoad(optional_llvm_ty, operand, "")
6636 else6545 else
6637 operand;6546 operand;
6638 const llvm_i8 = self.dg.context.intType(8);6547 const llvm_i8 = self.context.intType(8);
6639 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");6548 return self.builder.buildICmp(pred, loaded, llvm_i8.constNull(), "");
6640 }6549 }
66416550
...@@ -6701,16 +6610,12 @@ pub const FuncGen = struct {...@@ -6701,16 +6610,12 @@ pub const FuncGen = struct {
6701 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6610 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6702 const operand = try self.resolveInst(ty_op.operand);6611 const operand = try self.resolveInst(ty_op.operand);
6703 const optional_ty = self.air.typeOf(ty_op.operand).childType();6612 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;6613 var buf: Type.Payload.ElemType = undefined;
6706 const payload_ty = optional_ty.optionalChild(&buf);6614 const payload_ty = optional_ty.optionalChild(&buf);
6707 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6615 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6708 // We have a pointer to a zero-bit value and we need to return6616 // We have a pointer to a zero-bit value and we need to return
6709 // a pointer to a zero-bit value.6617 // a pointer to a zero-bit value.
67106618 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 }6619 }
6715 if (optional_ty.optionalReprIsPayload()) {6620 if (optional_ty.optionalReprIsPayload()) {
6716 // The payload and the optional are the same value.6621 // The payload and the optional are the same value.
...@@ -6726,17 +6631,13 @@ pub const FuncGen = struct {...@@ -6726,17 +6631,13 @@ pub const FuncGen = struct {
6726 const ty_op = self.air.instructions.items(.data)[inst].ty_op;6631 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
6727 const operand = try self.resolveInst(ty_op.operand);6632 const operand = try self.resolveInst(ty_op.operand);
6728 const optional_ty = self.air.typeOf(ty_op.operand).childType();6633 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;6634 var buf: Type.Payload.ElemType = undefined;
6731 const payload_ty = optional_ty.optionalChild(&buf);6635 const payload_ty = optional_ty.optionalChild(&buf);
6732 const non_null_bit = self.context.intType(8).constInt(1, .False);6636 const non_null_bit = self.context.intType(8).constInt(1, .False);
6733 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6637 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.6638 // 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);6639 _ = self.builder.buildStore(non_null_bit, operand);
67366640 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 }6641 }
6741 if (optional_ty.optionalReprIsPayload()) {6642 if (optional_ty.optionalReprIsPayload()) {
6742 // The payload and the optional are the same value.6643 // The payload and the optional are the same value.
...@@ -6794,11 +6695,7 @@ pub const FuncGen = struct {...@@ -6794,11 +6695,7 @@ pub const FuncGen = struct {
6794 const target = self.dg.module.getTarget();6695 const target = self.dg.module.getTarget();
67956696
6796 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {6697 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
6797 if (!operand_is_ptr) return null;6698 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 }6699 }
6803 const offset = errUnionPayloadOffset(payload_ty, target);6700 const offset = errUnionPayloadOffset(payload_ty, target);
6804 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);6701 const err_union_llvm_ty = try self.dg.lowerType(err_union_ty);
...@@ -6834,7 +6731,7 @@ pub const FuncGen = struct {...@@ -6834,7 +6731,7 @@ pub const FuncGen = struct {
6834 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {6731 if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
6835 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);6732 const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
6836 if (operand_is_ptr) {6733 if (operand_is_ptr) {
6837 return self.builder.buildBitCast(operand, err_llvm_ty.pointerType(0), "");6734 return operand;
6838 } else {6735 } else {
6839 return err_llvm_ty.constInt(0, .False);6736 return err_llvm_ty.constInt(0, .False);
6840 }6737 }
...@@ -7104,14 +7001,8 @@ pub const FuncGen = struct {...@@ -7104,14 +7001,8 @@ pub const FuncGen = struct {
7104 const llvm_slice_ty = try self.dg.lowerType(inst_ty);7001 const llvm_slice_ty = try self.dg.lowerType(inst_ty);
71057002
7106 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`7003 // 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 to7004 // 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.7005 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, "");7006 return self.builder.buildInsertValue(partial, len, 1, "");
7116 }7007 }
71177008
...@@ -7636,7 +7527,7 @@ pub const FuncGen = struct {...@@ -7636,7 +7527,7 @@ pub const FuncGen = struct {
7636 .neg => {7527 .neg => {
7637 // In this case we can generate a softfloat negation by XORing the7528 // In this case we can generate a softfloat negation by XORing the
7638 // bits with a constant.7529 // bits with a constant.
7639 const int_llvm_ty = self.dg.context.intType(float_bits);7530 const int_llvm_ty = self.context.intType(float_bits);
7640 const one = int_llvm_ty.constInt(1, .False);7531 const one = int_llvm_ty.constInt(1, .False);
7641 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);7532 const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False);
7642 const sign_mask = one.constShl(shift_amt);7533 const sign_mask = one.constShl(shift_amt);
...@@ -8045,8 +7936,8 @@ pub const FuncGen = struct {...@@ -8045,8 +7936,8 @@ pub const FuncGen = struct {
8045 const target = self.dg.module.getTarget();7936 const target = self.dg.module.getTarget();
80467937
8047 if (operand_is_ref and result_is_ref) {7938 if (operand_is_ref and result_is_ref) {
8048 // They are both pointers; just do a bitcast on the pointers :)7939 // They are both pointers, so just return the same opaque pointer :)
8049 return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");7940 return operand;
8050 }7941 }
80517942
8052 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {7943 if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
...@@ -8061,9 +7952,7 @@ pub const FuncGen = struct {...@@ -8061,9 +7952,7 @@ pub const FuncGen = struct {
8061 const array_ptr = self.buildAlloca(llvm_dest_ty, null);7952 const array_ptr = self.buildAlloca(llvm_dest_ty, null);
8062 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;7953 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8063 if (bitcast_ok) {7954 if (bitcast_ok) {
8064 const llvm_vector_ty = try self.dg.lowerType(operand_ty);7955 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));7956 llvm_store.setAlignment(inst_ty.abiAlignment(target));
8068 } else {7957 } else {
8069 // If the ABI size of the element type is not evenly divisible by size in bits;7958 // If the ABI size of the element type is not evenly divisible by size in bits;
...@@ -8092,9 +7981,7 @@ pub const FuncGen = struct {...@@ -8092,9 +7981,7 @@ pub const FuncGen = struct {
80927981
8093 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;7982 const bitcast_ok = elem_ty.bitSize(target) == elem_ty.abiSize(target) * 8;
8094 if (bitcast_ok) {7983 if (bitcast_ok) {
8095 const llvm_vector_ptr_ty = llvm_vector_ty.pointerType(0);7984 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 completely7985 // 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.7986 // different alignment. This means we need to enforce the alignment of this load.
8100 vector.setAlignment(elem_ty.abiAlignment(target));7987 vector.setAlignment(elem_ty.abiAlignment(target));
...@@ -8124,20 +8011,15 @@ pub const FuncGen = struct {...@@ -8124,20 +8011,15 @@ pub const FuncGen = struct {
8124 }8011 }
81258012
8126 if (operand_is_ref) {8013 if (operand_is_ref) {
8127 // Bitcast the operand pointer, then load.8014 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));8015 load_inst.setAlignment(operand_ty.abiAlignment(target));
8131 return load_inst;8016 return load_inst;
8132 }8017 }
81338018
8134 if (result_is_ref) {8019 if (result_is_ref) {
8135 // Bitcast the result pointer, then store.
8136 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));8020 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8137 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8021 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8138 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8022 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);8023 store_inst.setAlignment(alignment);
8142 return result_ptr;8024 return result_ptr;
8143 }8025 }
...@@ -8145,12 +8027,10 @@ pub const FuncGen = struct {...@@ -8145,12 +8027,10 @@ pub const FuncGen = struct {
8145 if (llvm_dest_ty.getTypeKind() == .Struct) {8027 if (llvm_dest_ty.getTypeKind() == .Struct) {
8146 // Both our operand and our result are values, not pointers,8028 // Both our operand and our result are values, not pointers,
8147 // but LLVM won't let us bitcast struct values.8029 // but LLVM won't let us bitcast struct values.
8148 // Therefore, we store operand to bitcasted alloca, then load for result.8030 // Therefore, we store operand to alloca, then load for result.
8149 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));8031 const alignment = @max(operand_ty.abiAlignment(target), inst_ty.abiAlignment(target));
8150 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);8032 const result_ptr = self.buildAlloca(llvm_dest_ty, alignment);
8151 const operand_llvm_ty = try self.dg.lowerType(operand_ty);8033 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);8034 store_inst.setAlignment(alignment);
8155 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");8035 const load_inst = self.builder.buildLoad(llvm_dest_ty, result_ptr, "");
8156 load_inst.setAlignment(alignment);8036 load_inst.setAlignment(alignment);
...@@ -8248,7 +8128,7 @@ pub const FuncGen = struct {...@@ -8248,7 +8128,7 @@ pub const FuncGen = struct {
8248 /// Use this instead of builder.buildAlloca, because this function makes sure to8128 /// Use this instead of builder.buildAlloca, because this function makes sure to
8249 /// put the alloca instruction at the top of the function!8129 /// put the alloca instruction at the top of the function!
8250 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {8130 fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type, alignment: ?c_uint) *llvm.Value {
8251 return buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());8131 return buildAllocaInner(self.context, self.builder, self.llvm_func, self.di_scope != null, llvm_ty, alignment, self.dg.module.getTarget());
8252 }8132 }
82538133
8254 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {8134 fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -8282,13 +8162,11 @@ pub const FuncGen = struct {...@@ -8282,13 +8162,11 @@ pub const FuncGen = struct {
8282 const target = self.dg.module.getTarget();8162 const target = self.dg.module.getTarget();
8283 const operand_size = operand_ty.abiSize(target);8163 const operand_size = operand_ty.abiSize(target);
8284 const u8_llvm_ty = self.context.intType(8);8164 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);8165 const fill_char = u8_llvm_ty.constInt(0xaa, .False);
8288 const dest_ptr_align = ptr_ty.ptrAlignment(target);8166 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8289 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8167 const usize_llvm_ty = try self.dg.lowerType(Type.usize);
8290 const len = usize_llvm_ty.constInt(operand_size, .False);8168 const len = usize_llvm_ty.constInt(operand_size, .False);
8291 _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());8169 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
8292 if (self.dg.module.comp.bin_file.options.valgrind) {8170 if (self.dg.module.comp.bin_file.options.valgrind) {
8293 self.valgrindMarkUndef(dest_ptr, len);8171 self.valgrindMarkUndef(dest_ptr, len);
8294 }8172 }
...@@ -8365,7 +8243,7 @@ pub const FuncGen = struct {...@@ -8365,7 +8243,7 @@ pub const FuncGen = struct {
8365 const llvm_i32 = self.context.intType(32);8243 const llvm_i32 = self.context.intType(32);
8366 const llvm_fn_name = "llvm.frameaddress.p0";8244 const llvm_fn_name = "llvm.frameaddress.p0";
8367 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {8245 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8368 const llvm_p0i8 = self.context.intType(8).pointerType(0);8246 const llvm_p0i8 = self.context.pointerType(0);
8369 const param_types = [_]*llvm.Type{llvm_i32};8247 const param_types = [_]*llvm.Type{llvm_i32};
8370 const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False);8248 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);8249 break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type);
...@@ -8388,14 +8266,13 @@ pub const FuncGen = struct {...@@ -8388,14 +8266,13 @@ pub const FuncGen = struct {
8388 fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value {8266 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;8267 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
8390 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;8268 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
8391 var ptr = try self.resolveInst(extra.ptr);8269 const ptr = try self.resolveInst(extra.ptr);
8392 var expected_value = try self.resolveInst(extra.expected_value);8270 var expected_value = try self.resolveInst(extra.expected_value);
8393 var new_value = try self.resolveInst(extra.new_value);8271 var new_value = try self.resolveInst(extra.new_value);
8394 const operand_ty = self.air.typeOf(extra.ptr).elemType();8272 const operand_ty = self.air.typeOf(extra.ptr).elemType();
8395 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8273 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
8396 if (opt_abi_ty) |abi_ty| {8274 if (opt_abi_ty) |abi_ty| {
8397 // operand needs widening and truncating8275 // operand needs widening and truncating
8398 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
8399 if (operand_ty.isSignedInt()) {8276 if (operand_ty.isSignedInt()) {
8400 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");8277 expected_value = self.builder.buildSExt(expected_value, abi_ty, "");
8401 new_value = self.builder.buildSExt(new_value, abi_ty, "");8278 new_value = self.builder.buildSExt(new_value, abi_ty, "");
...@@ -8447,7 +8324,6 @@ pub const FuncGen = struct {...@@ -8447,7 +8324,6 @@ pub const FuncGen = struct {
8447 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);8324 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, op == .Xchg);
8448 if (opt_abi_ty) |abi_ty| {8325 if (opt_abi_ty) |abi_ty| {
8449 // operand needs widening and truncating or bitcasting.8326 // 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)8327 const casted_operand = if (is_float)
8452 self.builder.buildBitCast(operand, abi_ty, "")8328 self.builder.buildBitCast(operand, abi_ty, "")
8453 else if (is_signed_int)8329 else if (is_signed_int)
...@@ -8457,7 +8333,7 @@ pub const FuncGen = struct {...@@ -8457,7 +8333,7 @@ pub const FuncGen = struct {
84578333
8458 const uncasted_result = self.builder.buildAtomicRmw(8334 const uncasted_result = self.builder.buildAtomicRmw(
8459 op,8335 op,
8460 casted_ptr,8336 ptr,
8461 casted_operand,8337 casted_operand,
8462 ordering,8338 ordering,
8463 single_threaded,8339 single_threaded,
...@@ -8476,11 +8352,10 @@ pub const FuncGen = struct {...@@ -8476,11 +8352,10 @@ pub const FuncGen = struct {
84768352
8477 // It's a pointer but we need to treat it as an int.8353 // It's a pointer but we need to treat it as an int.
8478 const usize_llvm_ty = try self.dg.lowerType(Type.usize);8354 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, "");8355 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
8481 const uncasted_result = self.builder.buildAtomicRmw(8356 const uncasted_result = self.builder.buildAtomicRmw(
8482 op,8357 op,
8483 casted_ptr,8358 ptr,
8484 casted_operand,8359 casted_operand,
8485 ordering,8360 ordering,
8486 single_threaded,8361 single_threaded,
...@@ -8508,8 +8383,7 @@ pub const FuncGen = struct {...@@ -8508,8 +8383,7 @@ pub const FuncGen = struct {
85088383
8509 if (opt_abi_llvm_ty) |abi_llvm_ty| {8384 if (opt_abi_llvm_ty) |abi_llvm_ty| {
8510 // operand needs widening and truncating8385 // operand needs widening and truncating
8511 const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), "");8386 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);8387 load_inst.setAlignment(ptr_alignment);
8514 load_inst.setVolatile(ptr_volatile);8388 load_inst.setVolatile(ptr_volatile);
8515 load_inst.setOrdering(ordering);8389 load_inst.setOrdering(ordering);
...@@ -8531,13 +8405,12 @@ pub const FuncGen = struct {...@@ -8531,13 +8405,12 @@ pub const FuncGen = struct {
8531 const ptr_ty = self.air.typeOf(bin_op.lhs);8405 const ptr_ty = self.air.typeOf(bin_op.lhs);
8532 const operand_ty = ptr_ty.childType();8406 const operand_ty = ptr_ty.childType();
8533 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;8407 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime()) return null;
8534 var ptr = try self.resolveInst(bin_op.lhs);8408 const ptr = try self.resolveInst(bin_op.lhs);
8535 var element = try self.resolveInst(bin_op.rhs);8409 var element = try self.resolveInst(bin_op.rhs);
8536 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);8410 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);
85378411
8538 if (opt_abi_ty) |abi_ty| {8412 if (opt_abi_ty) |abi_ty| {
8539 // operand needs widening8413 // operand needs widening
8540 ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");
8541 if (operand_ty.isSignedInt()) {8414 if (operand_ty.isSignedInt()) {
8542 element = self.builder.buildSExt(element, abi_ty, "");8415 element = self.builder.buildSExt(element, abi_ty, "");
8543 } else {8416 } else {
...@@ -8557,15 +8430,13 @@ pub const FuncGen = struct {...@@ -8557,15 +8430,13 @@ pub const FuncGen = struct {
8557 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;8430 const val_is_undef = if (self.air.value(extra.lhs)) |val| val.isUndefDeep() else false;
8558 const len = try self.resolveInst(extra.rhs);8431 const len = try self.resolveInst(extra.rhs);
8559 const u8_llvm_ty = self.context.intType(8);8432 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;8433 const fill_char = if (val_is_undef) u8_llvm_ty.constInt(0xaa, .False) else value;
8563 const target = self.dg.module.getTarget();8434 const target = self.dg.module.getTarget();
8564 const dest_ptr_align = ptr_ty.ptrAlignment(target);8435 const dest_ptr_align = ptr_ty.ptrAlignment(target);
8565 _ = self.builder.buildMemSet(dest_ptr_u8, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());8436 _ = self.builder.buildMemSet(dest_ptr, fill_char, len, dest_ptr_align, ptr_ty.isVolatilePtr());
85668437
8567 if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) {8438 if (val_is_undef and self.dg.module.comp.bin_file.options.valgrind) {
8568 self.valgrindMarkUndef(dest_ptr_u8, len);8439 self.valgrindMarkUndef(dest_ptr, len);
8569 }8440 }
8570 return null;8441 return null;
8571 }8442 }
...@@ -8578,15 +8449,12 @@ pub const FuncGen = struct {...@@ -8578,15 +8449,12 @@ pub const FuncGen = struct {
8578 const src_ptr = try self.resolveInst(extra.lhs);8449 const src_ptr = try self.resolveInst(extra.lhs);
8579 const src_ptr_ty = self.air.typeOf(extra.lhs);8450 const src_ptr_ty = self.air.typeOf(extra.lhs);
8580 const len = try self.resolveInst(extra.rhs);8451 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();8452 const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr();
8585 const target = self.dg.module.getTarget();8453 const target = self.dg.module.getTarget();
8586 _ = self.builder.buildMemCpy(8454 _ = self.builder.buildMemCpy(
8587 dest_ptr_u8,8455 dest_ptr,
8588 dest_ptr_ty.ptrAlignment(target),8456 dest_ptr_ty.ptrAlignment(target),
8589 src_ptr_u8,8457 src_ptr,
8590 src_ptr_ty.ptrAlignment(target),8458 src_ptr_ty.ptrAlignment(target),
8591 len,8459 len,
8592 is_volatile,8460 is_volatile,
...@@ -8780,8 +8648,8 @@ pub const FuncGen = struct {...@@ -8780,8 +8648,8 @@ pub const FuncGen = struct {
8780 const error_set_ty = self.air.getRefType(ty_op.ty);8648 const error_set_ty = self.air.getRefType(ty_op.ty);
87818649
8782 const names = error_set_ty.errorSetNames();8650 const names = error_set_ty.errorSetNames();
8783 const valid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Valid");8651 const valid_block = self.context.appendBasicBlock(self.llvm_func, "Valid");
8784 const invalid_block = self.dg.context.appendBasicBlock(self.llvm_func, "Invalid");8652 const invalid_block = self.context.appendBasicBlock(self.llvm_func, "Invalid");
8785 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");8653 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));8654 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
87878655
...@@ -8807,7 +8675,7 @@ pub const FuncGen = struct {...@@ -8807,7 +8675,7 @@ pub const FuncGen = struct {
88078675
8808 self.builder.positionBuilderAtEnd(end_block);8676 self.builder.positionBuilderAtEnd(end_block);
88098677
8810 const llvm_type = self.dg.context.intType(1);8678 const llvm_type = self.context.intType(1);
8811 const incoming_values: [2]*llvm.Value = .{8679 const incoming_values: [2]*llvm.Value = .{
8812 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),8680 llvm_type.constInt(1, .False), llvm_type.constInt(0, .False),
8813 };8681 };
...@@ -8869,13 +8737,13 @@ pub const FuncGen = struct {...@@ -8869,13 +8737,13 @@ pub const FuncGen = struct {
8869 }8737 }
8870 }8738 }
88718739
8872 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");8740 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
8873 self.builder.positionBuilderAtEnd(entry_block);8741 self.builder.positionBuilderAtEnd(entry_block);
8874 self.builder.clearCurrentDebugLocation();8742 self.builder.clearCurrentDebugLocation();
88758743
8876 const fields = enum_ty.enumFields();8744 const fields = enum_ty.enumFields();
8877 const named_block = self.dg.context.appendBasicBlock(fn_val, "Named");8745 const named_block = self.context.appendBasicBlock(fn_val, "Named");
8878 const unnamed_block = self.dg.context.appendBasicBlock(fn_val, "Unnamed");8746 const unnamed_block = self.context.appendBasicBlock(fn_val, "Unnamed");
8879 const tag_int_value = fn_val.getParam(0);8747 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()));8748 const switch_instr = self.builder.buildSwitch(tag_int_value, unnamed_block, @intCast(c_uint, fields.count()));
88818749
...@@ -8893,10 +8761,10 @@ pub const FuncGen = struct {...@@ -8893,10 +8761,10 @@ pub const FuncGen = struct {
8893 switch_instr.addCase(this_tag_int_value, named_block);8761 switch_instr.addCase(this_tag_int_value, named_block);
8894 }8762 }
8895 self.builder.positionBuilderAtEnd(named_block);8763 self.builder.positionBuilderAtEnd(named_block);
8896 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(1, .False));8764 _ = self.builder.buildRet(self.context.intType(1).constInt(1, .False));
88978765
8898 self.builder.positionBuilderAtEnd(unnamed_block);8766 self.builder.positionBuilderAtEnd(unnamed_block);
8899 _ = self.builder.buildRet(self.dg.context.intType(1).constInt(0, .False));8767 _ = self.builder.buildRet(self.context.intType(1).constInt(0, .False));
8900 return fn_val;8768 return fn_val;
8901 }8769 }
89028770
...@@ -8955,12 +8823,12 @@ pub const FuncGen = struct {...@@ -8955,12 +8823,12 @@ pub const FuncGen = struct {
8955 }8823 }
8956 }8824 }
89578825
8958 const entry_block = self.dg.context.appendBasicBlock(fn_val, "Entry");8826 const entry_block = self.context.appendBasicBlock(fn_val, "Entry");
8959 self.builder.positionBuilderAtEnd(entry_block);8827 self.builder.positionBuilderAtEnd(entry_block);
8960 self.builder.clearCurrentDebugLocation();8828 self.builder.clearCurrentDebugLocation();
89618829
8962 const fields = enum_ty.enumFields();8830 const fields = enum_ty.enumFields();
8963 const bad_value_block = self.dg.context.appendBasicBlock(fn_val, "BadValue");8831 const bad_value_block = self.context.appendBasicBlock(fn_val, "BadValue");
8964 const tag_int_value = fn_val.getParam(0);8832 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()));8833 const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count()));
89668834
...@@ -8969,7 +8837,7 @@ pub const FuncGen = struct {...@@ -8969,7 +8837,7 @@ pub const FuncGen = struct {
8969 };8837 };
89708838
8971 for (fields.keys()) |name, field_index| {8839 for (fields.keys()) |name, field_index| {
8972 const str_init = self.dg.context.constString(name.ptr, @intCast(c_uint, name.len), .False);8840 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
8973 const str_init_llvm_ty = str_init.typeOf();8841 const str_init_llvm_ty = str_init.typeOf();
8974 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");8842 const str_global = self.dg.object.llvm_module.addGlobal(str_init_llvm_ty, "");
8975 str_global.setInitializer(str_init);8843 str_global.setInitializer(str_init);
...@@ -8990,7 +8858,7 @@ pub const FuncGen = struct {...@@ -8990,7 +8858,7 @@ pub const FuncGen = struct {
8990 slice_global.setUnnamedAddr(.True);8858 slice_global.setUnnamedAddr(.True);
8991 slice_global.setAlignment(slice_alignment);8859 slice_global.setAlignment(slice_alignment);
89928860
8993 const return_block = self.dg.context.appendBasicBlock(fn_val, "Name");8861 const return_block = self.context.appendBasicBlock(fn_val, "Name");
8994 const this_tag_int_value = int: {8862 const this_tag_int_value = int: {
8995 var tag_val_payload: Value.Payload.U32 = .{8863 var tag_val_payload: Value.Payload.U32 = .{
8996 .base = .{ .tag = .enum_field_index },8864 .base = .{ .tag = .enum_field_index },
...@@ -9042,7 +8910,7 @@ pub const FuncGen = struct {...@@ -9042,7 +8910,7 @@ pub const FuncGen = struct {
9042 const slice_llvm_ty = try self.dg.lowerType(slice_ty);8910 const slice_llvm_ty = try self.dg.lowerType(slice_ty);
90438911
9044 const error_name_table_ptr = try self.getErrorNameTable();8912 const error_name_table_ptr = try self.getErrorNameTable();
9045 const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0);8913 const ptr_slice_llvm_ty = self.context.pointerType(0);
9046 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");8914 const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, "");
9047 const indices = [_]*llvm.Value{operand};8915 const indices = [_]*llvm.Value{operand};
9048 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");8916 const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, "");
...@@ -9285,7 +9153,7 @@ pub const FuncGen = struct {...@@ -9285,7 +9153,7 @@ pub const FuncGen = struct {
9285 if (result_ty.containerLayout() == .Packed) {9153 if (result_ty.containerLayout() == .Packed) {
9286 const struct_obj = result_ty.castTag(.@"struct").?.data;9154 const struct_obj = result_ty.castTag(.@"struct").?.data;
9287 const big_bits = struct_obj.backing_int_ty.bitSize(target);9155 const big_bits = struct_obj.backing_int_ty.bitSize(target);
9288 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));9156 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
9289 const fields = struct_obj.fields.values();9157 const fields = struct_obj.fields.values();
9290 comptime assert(Type.packed_struct_layout_version == 2);9158 comptime assert(Type.packed_struct_layout_version == 2);
9291 var running_int: *llvm.Value = int_llvm_ty.constNull();9159 var running_int: *llvm.Value = int_llvm_ty.constNull();
...@@ -9296,7 +9164,7 @@ pub const FuncGen = struct {...@@ -9296,7 +9164,7 @@ pub const FuncGen = struct {
92969164
9297 const non_int_val = try self.resolveInst(elem);9165 const non_int_val = try self.resolveInst(elem);
9298 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));9166 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9299 const small_int_ty = self.dg.context.intType(ty_bit_size);9167 const small_int_ty = self.context.intType(ty_bit_size);
9300 const small_int_val = if (field.ty.isPtrAtRuntime())9168 const small_int_val = if (field.ty.isPtrAtRuntime())
9301 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9169 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9302 else9170 else
...@@ -9410,11 +9278,11 @@ pub const FuncGen = struct {...@@ -9410,11 +9278,11 @@ pub const FuncGen = struct {
94109278
9411 if (union_obj.layout == .Packed) {9279 if (union_obj.layout == .Packed) {
9412 const big_bits = union_ty.bitSize(target);9280 const big_bits = union_ty.bitSize(target);
9413 const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits));9281 const int_llvm_ty = self.context.intType(@intCast(c_uint, big_bits));
9414 const field = union_obj.fields.values()[extra.field_index];9282 const field = union_obj.fields.values()[extra.field_index];
9415 const non_int_val = try self.resolveInst(extra.init);9283 const non_int_val = try self.resolveInst(extra.init);
9416 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));9284 const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
9417 const small_int_ty = self.dg.context.intType(ty_bit_size);9285 const small_int_ty = self.context.intType(ty_bit_size);
9418 const small_int_val = if (field.ty.isPtrAtRuntime())9286 const small_int_val = if (field.ty.isPtrAtRuntime())
9419 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")9287 self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
9420 else9288 else
...@@ -9444,9 +9312,9 @@ pub const FuncGen = struct {...@@ -9444,9 +9312,9 @@ pub const FuncGen = struct {
9444 }9312 }
9445 assert(isByRef(union_ty));9313 assert(isByRef(union_ty));
9446 // The llvm type of the alloca will be the named LLVM union type, and will not9314 // 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. We9315 // 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 to9316 // We must construct the correct unnamed struct type here, in order to then set
9449 // then set the fields appropriately.9317 // the fields appropriately.
9450 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);9318 const result_ptr = self.buildAlloca(union_llvm_ty, layout.abi_align);
9451 const llvm_payload = try self.resolveInst(extra.init);9319 const llvm_payload = try self.resolveInst(extra.init);
9452 assert(union_obj.haveFieldTypes());9320 assert(union_obj.haveFieldTypes());
...@@ -9489,8 +9357,6 @@ pub const FuncGen = struct {...@@ -9489,8 +9357,6 @@ pub const FuncGen = struct {
9489 break :t self.context.structType(&fields, fields_len, .False);9357 break :t self.context.structType(&fields, fields_len, .False);
9490 };9358 };
94919359
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 the9360 // Now we follow the layout as expressed above with GEP instructions to set the
9495 // tag and the payload.9361 // tag and the payload.
9496 const index_type = self.context.intType(32);9362 const index_type = self.context.intType(32);
...@@ -9510,7 +9376,7 @@ pub const FuncGen = struct {...@@ -9510,7 +9376,7 @@ pub const FuncGen = struct {
9510 index_type.constNull(),9376 index_type.constNull(),
9511 };9377 };
9512 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9378 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9513 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");9379 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
9514 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);9380 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
9515 return result_ptr;9381 return result_ptr;
9516 }9382 }
...@@ -9522,7 +9388,7 @@ pub const FuncGen = struct {...@@ -9522,7 +9388,7 @@ pub const FuncGen = struct {
9522 index_type.constNull(),9388 index_type.constNull(),
9523 };9389 };
9524 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;9390 const len: c_uint = if (field_size == layout.payload_size) 2 else 3;
9525 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, len, "");9391 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, len, "");
9526 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);9392 try self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic);
9527 }9393 }
9528 {9394 {
...@@ -9530,7 +9396,7 @@ pub const FuncGen = struct {...@@ -9530,7 +9396,7 @@ pub const FuncGen = struct {
9530 index_type.constNull(),9396 index_type.constNull(),
9531 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),9397 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
9532 };9398 };
9533 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, casted_ptr, &indices, indices.len, "");9399 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
9534 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);9400 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
9535 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);9401 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
9536 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);9402 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
...@@ -9579,8 +9445,7 @@ pub const FuncGen = struct {...@@ -9579,8 +9445,7 @@ pub const FuncGen = struct {
9579 .data => {},9445 .data => {},
9580 }9446 }
95819447
9582 const llvm_u8 = self.context.intType(8);9448 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);9449 const llvm_u32 = self.context.intType(32);
95859450
9586 const llvm_fn_name = "llvm.prefetch.p0";9451 const llvm_fn_name = "llvm.prefetch.p0";
...@@ -9595,10 +9460,9 @@ pub const FuncGen = struct {...@@ -9595,10 +9460,9 @@ pub const FuncGen = struct {
9595 };9460 };
95969461
9597 const ptr = try self.resolveInst(prefetch.ptr);9462 const ptr = try self.resolveInst(prefetch.ptr);
9598 const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, "");
95999463
9600 const params = [_]*llvm.Value{9464 const params = [_]*llvm.Value{
9601 ptr_u8,9465 ptr,
9602 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),9466 llvm_u32.constInt(@enumToInt(prefetch.rw), .False),
9603 llvm_u32.constInt(prefetch.locality, .False),9467 llvm_u32.constInt(prefetch.locality, .False),
9604 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),9468 llvm_u32.constInt(@enumToInt(prefetch.cache), .False),
...@@ -9625,8 +9489,7 @@ pub const FuncGen = struct {...@@ -9625,8 +9489,7 @@ pub const FuncGen = struct {
96259489
9626 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);9490 const slice_ty = Type.initTag(.const_slice_u8_sentinel_0);
9627 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());9491 const slice_alignment = slice_ty.abiAlignment(self.dg.module.getTarget());
9628 const llvm_slice_ty = try self.dg.lowerType(slice_ty);9492 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
96309493
9631 const error_name_table_global = self.dg.object.llvm_module.addGlobal(llvm_slice_ptr_ty, "__zig_err_name_table");9494 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());9495 error_name_table_global.setInitializer(llvm_slice_ptr_ty.getUndef());
...@@ -9699,7 +9562,7 @@ pub const FuncGen = struct {...@@ -9699,7 +9562,7 @@ pub const FuncGen = struct {
9699 non_null_bit: *llvm.Value,9562 non_null_bit: *llvm.Value,
9700 ) !?*llvm.Value {9563 ) !?*llvm.Value {
9701 const optional_llvm_ty = try self.dg.lowerType(optional_ty);9564 const optional_llvm_ty = try self.dg.lowerType(optional_ty);
9702 const non_null_field = self.builder.buildZExt(non_null_bit, self.dg.context.intType(8), "");9565 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
97039566
9704 if (isByRef(optional_ty)) {9567 if (isByRef(optional_ty)) {
9705 const target = self.dg.module.getTarget();9568 const target = self.dg.module.getTarget();
...@@ -9740,31 +9603,24 @@ pub const FuncGen = struct {...@@ -9740,31 +9603,24 @@ pub const FuncGen = struct {
9740 .Packed => {9603 .Packed => {
9741 const result_ty = self.air.typeOfIndex(inst);9604 const result_ty = self.air.typeOfIndex(inst);
9742 const result_ty_info = result_ty.ptrInfo().data;9605 const result_ty_info = result_ty.ptrInfo().data;
9743 const result_llvm_ty = try self.dg.lowerType(result_ty);
97449606
9745 if (result_ty_info.host_size != 0) {9607 if (result_ty_info.host_size != 0) {
9746 // From LLVM's perspective, a pointer to a packed struct and a pointer9608 // 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 the9609 // 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 shift9610 // Zig pointer type which provides information for how to mask and shift
9749 // out the relevant bits when accessing the pointee.9611 // out the relevant bits when accessing the pointee.
9750 // Here we perform a bitcast because we want to use the host_size9612 return struct_ptr;
9751 // as the llvm pointer element type.
9752 return self.builder.buildBitCast(struct_ptr, result_llvm_ty, "");
9753 }9613 }
97549614
9755 // We have a pointer to a packed struct field that happens to be byte-aligned.9615 // 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.9616 // Offset our operand pointer by the correct number of bytes.
9757 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);9617 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, target);
9758 if (byte_offset == 0) {9618 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);9619 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);9620 const llvm_usize = try self.dg.lowerType(Type.usize);
9764 const llvm_index = llvm_usize.constInt(byte_offset, .False);9621 const llvm_index = llvm_usize.constInt(byte_offset, .False);
9765 const indices: [1]*llvm.Value = .{llvm_index};9622 const indices: [1]*llvm.Value = .{llvm_index};
9766 const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, "");9623 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
9767 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
9768 },9624 },
9769 else => {9625 else => {
9770 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);9626 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
...@@ -9777,39 +9633,25 @@ pub const FuncGen = struct {...@@ -9777,39 +9633,25 @@ pub const FuncGen = struct {
9777 // end of the struct. Treat our struct pointer as an array of two and get9633 // 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 of9634 // the index to the element at index `1` to get a pointer to the end of
9779 // the struct.9635 // the struct.
9780 const llvm_u32 = self.dg.context.intType(32);9636 const llvm_u32 = self.context.intType(32);
9781 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);9637 const llvm_index = llvm_u32.constInt(@boolToInt(struct_ty.hasRuntimeBitsIgnoreComptime()), .False);
9782 const indices: [1]*llvm.Value = .{llvm_index};9638 const indices: [1]*llvm.Value = .{llvm_index};
9783 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");9639 return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, "");
9784 }9640 }
9785 },9641 },
9786 },9642 },
9787 .Union => return self.unionFieldPtr(inst, struct_ptr, struct_ty),9643 .Union => {
9644 const layout = struct_ty.unionGetLayout(target);
9645 if (layout.payload_size == 0 or struct_ty.containerLayout() == .Packed) return struct_ptr;
9646 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9647 const union_llvm_ty = try self.dg.lowerType(struct_ty);
9648 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
9649 return union_field_ptr;
9650 },
9788 else => unreachable,9651 else => unreachable,
9789 }9652 }
9790 }9653 }
97919654
9792 fn unionFieldPtr(
9793 self: *FuncGen,
9794 inst: Air.Inst.Index,
9795 union_ptr: *llvm.Value,
9796 union_ty: Type,
9797 ) !?*llvm.Value {
9798 const target = self.dg.module.getTarget();
9799 const layout = union_ty.unionGetLayout(target);
9800 const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
9801 if (layout.payload_size == 0) {
9802 return self.builder.buildBitCast(union_ptr, result_llvm_ty, "");
9803 }
9804 if (union_ty.containerLayout() == .Packed) {
9805 return self.builder.buildBitCast(union_ptr, result_llvm_ty, "");
9806 }
9807 const payload_index = @boolToInt(layout.tag_align >= layout.payload_align);
9808 const union_llvm_ty = try self.dg.lowerType(union_ty);
9809 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, union_ptr, payload_index, "");
9810 return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
9811 }
9812
9813 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {9655 fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value {
9814 const id = llvm.lookupIntrinsicID(name.ptr, name.len);9656 const id = llvm.lookupIntrinsicID(name.ptr, name.len);
9815 assert(id != 0);9657 assert(id != 0);
...@@ -9828,13 +9670,12 @@ pub const FuncGen = struct {...@@ -9828,13 +9670,12 @@ pub const FuncGen = struct {
9828 const target = fg.dg.module.getTarget();9670 const target = fg.dg.module.getTarget();
9829 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));9671 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(target));
9830 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);9672 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);9673 const llvm_usize = fg.context.intType(Type.usize.intInfo(target).bits);
9833 const size_bytes = pointee_type.abiSize(target);9674 const size_bytes = pointee_type.abiSize(target);
9834 _ = fg.builder.buildMemCpy(9675 _ = fg.builder.buildMemCpy(
9835 fg.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""),9676 result_ptr,
9836 result_align,9677 result_align,
9837 fg.builder.buildBitCast(ptr, llvm_ptr_u8, ""),9678 ptr,
9838 ptr_alignment,9679 ptr_alignment,
9839 llvm_usize.constInt(size_bytes, .False),9680 llvm_usize.constInt(size_bytes, .False),
9840 is_volatile,9681 is_volatile,
...@@ -9855,7 +9696,7 @@ pub const FuncGen = struct {...@@ -9855,7 +9696,7 @@ pub const FuncGen = struct {
98559696
9856 assert(info.vector_index != .runtime);9697 assert(info.vector_index != .runtime);
9857 if (info.vector_index != .none) {9698 if (info.vector_index != .none) {
9858 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);9699 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9859 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);9700 const vec_elem_ty = try self.dg.lowerType(info.pointee_type);
9860 const vec_ty = vec_elem_ty.vectorType(info.host_size);9701 const vec_ty = vec_elem_ty.vectorType(info.host_size);
98619702
...@@ -9878,8 +9719,7 @@ pub const FuncGen = struct {...@@ -9878,8 +9719,7 @@ pub const FuncGen = struct {
9878 }9719 }
98799720
9880 const int_elem_ty = self.context.intType(info.host_size * 8);9721 const int_elem_ty = self.context.intType(info.host_size * 8);
9881 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");9722 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);9723 containing_int.setAlignment(ptr_alignment);
9884 containing_int.setVolatile(ptr_volatile);9724 containing_int.setVolatile(ptr_volatile);
98859725
...@@ -9894,8 +9734,7 @@ pub const FuncGen = struct {...@@ -9894,8 +9734,7 @@ pub const FuncGen = struct {
98949734
9895 const same_size_int = self.context.intType(elem_bits);9735 const same_size_int = self.context.intType(elem_bits);
9896 const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");9736 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), "");9737 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);9738 store_inst.setAlignment(result_align);
9900 return result_ptr;9739 return result_ptr;
9901 }9740 }
...@@ -9933,7 +9772,7 @@ pub const FuncGen = struct {...@@ -9933,7 +9772,7 @@ pub const FuncGen = struct {
99339772
9934 assert(info.vector_index != .runtime);9773 assert(info.vector_index != .runtime);
9935 if (info.vector_index != .none) {9774 if (info.vector_index != .none) {
9936 const index_u32 = self.dg.context.intType(32).constInt(@enumToInt(info.vector_index), .False);9775 const index_u32 = self.context.intType(32).constInt(@enumToInt(info.vector_index), .False);
9937 const vec_elem_ty = try self.dg.lowerType(elem_ty);9776 const vec_elem_ty = try self.dg.lowerType(elem_ty);
9938 const vec_ty = vec_elem_ty.vectorType(info.host_size);9777 const vec_ty = vec_elem_ty.vectorType(info.host_size);
99399778
...@@ -9952,8 +9791,7 @@ pub const FuncGen = struct {...@@ -9952,8 +9791,7 @@ pub const FuncGen = struct {
99529791
9953 if (info.host_size != 0) {9792 if (info.host_size != 0) {
9954 const int_elem_ty = self.context.intType(info.host_size * 8);9793 const int_elem_ty = self.context.intType(info.host_size * 8);
9955 const int_ptr = self.builder.buildBitCast(ptr, int_elem_ty.pointerType(0), "");9794 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);9795 assert(ordering == .NotAtomic);
9958 containing_int.setAlignment(ptr_alignment);9796 containing_int.setAlignment(ptr_alignment);
9959 containing_int.setVolatile(ptr_volatile);9797 containing_int.setVolatile(ptr_volatile);
...@@ -9978,7 +9816,7 @@ pub const FuncGen = struct {...@@ -9978,7 +9816,7 @@ pub const FuncGen = struct {
9978 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");9816 const shifted_value = self.builder.buildShl(extended_value, shift_amt, "");
9979 const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, "");9817 const ored_value = self.builder.buildOr(shifted_value, anded_containing_int, "");
99809818
9981 const store_inst = self.builder.buildStore(ored_value, int_ptr);9819 const store_inst = self.builder.buildStore(ored_value, ptr);
9982 assert(ordering == .NotAtomic);9820 assert(ordering == .NotAtomic);
9983 store_inst.setAlignment(ptr_alignment);9821 store_inst.setAlignment(ptr_alignment);
9984 store_inst.setVolatile(ptr_volatile);9822 store_inst.setVolatile(ptr_volatile);
...@@ -9992,12 +9830,11 @@ pub const FuncGen = struct {...@@ -9992,12 +9830,11 @@ pub const FuncGen = struct {
9992 return;9830 return;
9993 }9831 }
9994 assert(ordering == .NotAtomic);9832 assert(ordering == .NotAtomic);
9995 const llvm_ptr_u8 = self.context.intType(8).pointerType(0);
9996 const size_bytes = elem_ty.abiSize(target);9833 const size_bytes = elem_ty.abiSize(target);
9997 _ = self.builder.buildMemCpy(9834 _ = self.builder.buildMemCpy(
9998 self.builder.buildBitCast(ptr, llvm_ptr_u8, ""),9835 ptr,
9999 ptr_alignment,9836 ptr_alignment,
10000 self.builder.buildBitCast(elem, llvm_ptr_u8, ""),9837 elem,
10001 elem_ty.abiAlignment(target),9838 elem_ty.abiAlignment(target),
10002 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),9839 self.context.intType(Type.usize.intInfo(target).bits).constInt(size_bytes, .False),
10003 info.@"volatile",9840 info.@"volatile",
...@@ -11187,6 +11024,7 @@ fn compilerRtIntBits(bits: u16) u16 {...@@ -11187,6 +11024,7 @@ fn compilerRtIntBits(bits: u16) u16 {
11187}11024}
1118811025
11189fn buildAllocaInner(11026fn buildAllocaInner(
11027 context: *llvm.Context,
11190 builder: *llvm.Builder,11028 builder: *llvm.Builder,
11191 llvm_func: *llvm.Value,11029 llvm_func: *llvm.Value,
11192 di_scope_non_null: bool,11030 di_scope_non_null: bool,
...@@ -11224,7 +11062,7 @@ fn buildAllocaInner(...@@ -11224,7 +11062,7 @@ fn buildAllocaInner(
11224 // The pointer returned from this function should have the generic address space,11062 // 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.11063 // if this isn't the case then cast it to the generic address space.
11226 if (address_space != llvm.address_space.default) {11064 if (address_space != llvm.address_space.default) {
11227 return builder.buildAddrSpaceCast(alloca, llvm_ty.pointerType(llvm.address_space.default), "");11065 return builder.buildAddrSpaceCast(alloca, context.pointerType(llvm.address_space.default), "");
11228 }11066 }
1122911067
11230 return alloca;11068 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