authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-04 17:32:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-04 17:32:46-07:00
logac5c6b6061c6454a891c22a8258069370b57c05b
tree703979074915bba1b28d2ecf4b742df2fa9a1031
parent169ad1aac745857965db8fe7565aa45b8d8cea0f

stage2 LLVM backend: opaque pointer fixes


2 files changed, 80 insertions(+), 43 deletions(-)

src/codegen/llvm.zig+75-43
...@@ -2523,16 +2523,7 @@ pub const DeclGen = struct {...@@ -2523,16 +2523,7 @@ pub const DeclGen = struct {
2523 if (ptr_info.host_size != 0) {2523 if (ptr_info.host_size != 0) {
2524 return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace);2524 return dg.context.intType(ptr_info.host_size * 8).pointerType(llvm_addrspace);
2525 }2525 }
2526 const elem_ty = ptr_info.pointee_type;2526 const llvm_elem_ty = try dg.lowerPtrElemTy(ptr_info.pointee_type);
2527 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
2528 .Opaque, .Fn => true,
2529 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
2530 else => elem_ty.hasRuntimeBitsIgnoreComptime(),
2531 };
2532 const llvm_elem_ty = if (lower_elem_ty)
2533 try dg.lowerType(elem_ty)
2534 else
2535 dg.context.intType(8);
2536 return llvm_elem_ty.pointerType(llvm_addrspace);2527 return llvm_elem_ty.pointerType(llvm_addrspace);
2537 },2528 },
2538 .Opaque => switch (t.tag()) {2529 .Opaque => switch (t.tag()) {
...@@ -2917,6 +2908,23 @@ pub const DeclGen = struct {...@@ -2917,6 +2908,23 @@ pub const DeclGen = struct {
2917 );2908 );
2918 }2909 }
29192910
2911 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
2912 /// being a zero bit type, but it should still be lowered as an i8 in such case.
2913 /// There are other similar cases handled here as well.
2914 fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*const llvm.Type {
2915 const lower_elem_ty = switch (elem_ty.zigTypeTag()) {
2916 .Opaque, .Fn => true,
2917 .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(),
2918 else => elem_ty.hasRuntimeBitsIgnoreComptime(),
2919 };
2920 const llvm_elem_ty = if (lower_elem_ty)
2921 try dg.lowerType(elem_ty)
2922 else
2923 dg.context.intType(8);
2924
2925 return llvm_elem_ty;
2926 }
2927
2920 fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*const llvm.Value {2928 fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*const llvm.Value {
2921 if (tv.val.isUndef()) {2929 if (tv.val.isUndef()) {
2922 const llvm_type = try dg.lowerType(tv.ty);2930 const llvm_type = try dg.lowerType(tv.ty);
...@@ -4674,8 +4682,8 @@ pub const FuncGen = struct {...@@ -4674,8 +4682,8 @@ pub const FuncGen = struct {
4674 _ = self.builder.buildBr(end_block);4682 _ = self.builder.buildBr(end_block);
46754683
4676 self.builder.positionBuilderAtEnd(both_pl_block);4684 self.builder.positionBuilderAtEnd(both_pl_block);
4677 const lhs_payload = self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty);4685 const lhs_payload = try self.optPayloadHandle(opt_llvm_ty, lhs, scalar_ty);
4678 const rhs_payload = self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty);4686 const rhs_payload = try self.optPayloadHandle(opt_llvm_ty, rhs, scalar_ty);
4679 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);4687 const payload_cmp = try self.cmp(lhs_payload, rhs_payload, payload_ty, op);
4680 _ = self.builder.buildBr(end_block);4688 _ = self.builder.buildBr(end_block);
4681 const both_pl_block_end = self.builder.getInsertBlock();4689 const both_pl_block_end = self.builder.getInsertBlock();
...@@ -5133,7 +5141,8 @@ pub const FuncGen = struct {...@@ -5133,7 +5141,8 @@ pub const FuncGen = struct {
51335141
5134 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5142 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5135 const slice_ptr = try self.resolveInst(ty_op.operand);5143 const slice_ptr = try self.resolveInst(ty_op.operand);
5136 const slice_llvm_ty = try self.dg.lowerType(self.air.typeOf(ty_op.operand).childType());5144 const slice_ptr_ty = self.air.typeOf(ty_op.operand);
5145 const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType());
51375146
5138 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");5147 return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, "");
5139 }5148 }
...@@ -5145,7 +5154,7 @@ pub const FuncGen = struct {...@@ -5145,7 +5154,7 @@ pub const FuncGen = struct {
51455154
5146 const slice = try self.resolveInst(bin_op.lhs);5155 const slice = try self.resolveInst(bin_op.lhs);
5147 const index = try self.resolveInst(bin_op.rhs);5156 const index = try self.resolveInst(bin_op.rhs);
5148 const llvm_elem_ty = try self.dg.lowerType(slice_ty.childType());5157 const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType());
5149 const base_ptr = self.builder.buildExtractValue(slice, 0, "");5158 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
5150 const indices: [1]*const llvm.Value = .{index};5159 const indices: [1]*const llvm.Value = .{index};
5151 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5160 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
...@@ -5160,7 +5169,7 @@ pub const FuncGen = struct {...@@ -5160,7 +5169,7 @@ pub const FuncGen = struct {
51605169
5161 const slice = try self.resolveInst(bin_op.lhs);5170 const slice = try self.resolveInst(bin_op.lhs);
5162 const index = try self.resolveInst(bin_op.rhs);5171 const index = try self.resolveInst(bin_op.rhs);
5163 const llvm_elem_ty = try self.dg.lowerType(slice_ty.childType());5172 const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType());
5164 const base_ptr = self.builder.buildExtractValue(slice, 0, "");5173 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
5165 const indices: [1]*const llvm.Value = .{index};5174 const indices: [1]*const llvm.Value = .{index};
5166 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");5175 return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
...@@ -5195,9 +5204,10 @@ pub const FuncGen = struct {...@@ -5195,9 +5204,10 @@ pub const FuncGen = struct {
5195 const ptr_ty = self.air.typeOf(bin_op.lhs);5204 const ptr_ty = self.air.typeOf(bin_op.lhs);
5196 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;5205 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
51975206
5198 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());5207 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
5199 const base_ptr = try self.resolveInst(bin_op.lhs);5208 const base_ptr = try self.resolveInst(bin_op.lhs);
5200 const rhs = try self.resolveInst(bin_op.rhs);5209 const rhs = try self.resolveInst(bin_op.rhs);
5210 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
5201 const ptr = if (ptr_ty.isSinglePointer()) ptr: {5211 const ptr = if (ptr_ty.isSinglePointer()) ptr: {
5202 // If this is a single-item pointer to an array, we need another index in the GEP.5212 // If this is a single-item pointer to an array, we need another index in the GEP.
5203 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };5213 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };
...@@ -5220,7 +5230,7 @@ pub const FuncGen = struct {...@@ -5220,7 +5230,7 @@ pub const FuncGen = struct {
52205230
5221 const base_ptr = try self.resolveInst(bin_op.lhs);5231 const base_ptr = try self.resolveInst(bin_op.lhs);
5222 const rhs = try self.resolveInst(bin_op.rhs);5232 const rhs = try self.resolveInst(bin_op.rhs);
5223 const llvm_elem_ty = try self.dg.lowerType(elem_ty);5233 const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty);
5224 if (ptr_ty.isSinglePointer()) {5234 if (ptr_ty.isSinglePointer()) {
5225 // If this is a single-item pointer to an array, we need another index in the GEP.5235 // If this is a single-item pointer to an array, we need another index in the GEP.
5226 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };5236 const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs };
...@@ -5555,7 +5565,9 @@ pub const FuncGen = struct {...@@ -5555,7 +5565,9 @@ pub const FuncGen = struct {
5555 const max_param_count = inputs.len + outputs.len;5565 const max_param_count = inputs.len + outputs.len;
5556 const llvm_param_types = try arena.alloc(*const llvm.Type, max_param_count);5566 const llvm_param_types = try arena.alloc(*const llvm.Type, max_param_count);
5557 const llvm_param_values = try arena.alloc(*const llvm.Value, max_param_count);5567 const llvm_param_values = try arena.alloc(*const llvm.Value, max_param_count);
5558 const llvm_param_attrs = try arena.alloc(bool, max_param_count);5568 // This stores whether we need to add an elementtype attribute and
5569 // if so, the element type itself.
5570 const llvm_param_attrs = try arena.alloc(?*const llvm.Type, max_param_count);
5559 const target = self.dg.module.getTarget();5571 const target = self.dg.module.getTarget();
55605572
5561 var llvm_ret_i: usize = 0;5573 var llvm_ret_i: usize = 0;
...@@ -5573,7 +5585,7 @@ pub const FuncGen = struct {...@@ -5573,7 +5585,7 @@ pub const FuncGen = struct {
5573 // for the string, we still use the next u32 for the null terminator.5585 // for the string, we still use the next u32 for the null terminator.
5574 extra_i += (constraint.len + name.len + (2 + 3)) / 4;5586 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
55755587
5576 try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1);5588 try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 3);
5577 if (total_i != 0) {5589 if (total_i != 0) {
5578 llvm_constraints.appendAssumeCapacity(',');5590 llvm_constraints.appendAssumeCapacity(',');
5579 }5591 }
...@@ -5582,8 +5594,10 @@ pub const FuncGen = struct {...@@ -5582,8 +5594,10 @@ pub const FuncGen = struct {
5582 // Pass any non-return outputs indirectly, if the constraint accepts a memory location5594 // Pass any non-return outputs indirectly, if the constraint accepts a memory location
5583 llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);5595 llvm_ret_indirect[i] = (output != .none) and constraintAllowsMemory(constraint);
5584 if (output != .none) {5596 if (output != .none) {
5585 try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1);
5586 const output_inst = try self.resolveInst(output);5597 const output_inst = try self.resolveInst(output);
5598 const output_ty = self.air.typeOf(output);
5599 assert(output_ty.zigTypeTag() == .Pointer);
5600 const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType());
55875601
5588 if (llvm_ret_indirect[i]) {5602 if (llvm_ret_indirect[i]) {
5589 // Pass the result by reference as an indirect output (e.g. "=*m")5603 // Pass the result by reference as an indirect output (e.g. "=*m")
...@@ -5591,11 +5605,11 @@ pub const FuncGen = struct {...@@ -5591,11 +5605,11 @@ pub const FuncGen = struct {
55915605
5592 llvm_param_values[llvm_param_i] = output_inst;5606 llvm_param_values[llvm_param_i] = output_inst;
5593 llvm_param_types[llvm_param_i] = output_inst.typeOf();5607 llvm_param_types[llvm_param_i] = output_inst.typeOf();
5594 llvm_param_attrs[llvm_param_i] = true;5608 llvm_param_attrs[llvm_param_i] = elem_llvm_ty;
5595 llvm_param_i += 1;5609 llvm_param_i += 1;
5596 } else {5610 } else {
5597 // Pass the result directly (e.g. "=r")5611 // Pass the result directly (e.g. "=r")
5598 llvm_ret_types[llvm_ret_i] = output_inst.typeOf().getElementType();5612 llvm_ret_types[llvm_ret_i] = elem_llvm_ty;
5599 llvm_ret_i += 1;5613 llvm_ret_i += 1;
5600 }5614 }
5601 } else {5615 } else {
...@@ -5633,7 +5647,9 @@ pub const FuncGen = struct {...@@ -5633,7 +5647,9 @@ pub const FuncGen = struct {
56335647
5634 const arg_llvm_value = try self.resolveInst(input);5648 const arg_llvm_value = try self.resolveInst(input);
5635 const arg_ty = self.air.typeOf(input);5649 const arg_ty = self.air.typeOf(input);
5650 var llvm_elem_ty: ?*const llvm.Type = null;
5636 if (isByRef(arg_ty)) {5651 if (isByRef(arg_ty)) {
5652 llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty);
5637 if (constraintAllowsMemory(constraint)) {5653 if (constraintAllowsMemory(constraint)) {
5638 llvm_param_values[llvm_param_i] = arg_llvm_value;5654 llvm_param_values[llvm_param_i] = arg_llvm_value;
5639 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();5655 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
...@@ -5677,7 +5693,12 @@ pub const FuncGen = struct {...@@ -5677,7 +5693,12 @@ pub const FuncGen = struct {
56775693
5678 // In the case of indirect inputs, LLVM requires the callsite to have5694 // In the case of indirect inputs, LLVM requires the callsite to have
5679 // an elementtype(<ty>) attribute.5695 // an elementtype(<ty>) attribute.
5680 llvm_param_attrs[llvm_param_i] = constraint[0] == '*';5696 if (constraint[0] == '*') {
5697 llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse
5698 try self.dg.lowerPtrElemTy(arg_ty.childType());
5699 } else {
5700 llvm_param_attrs[llvm_param_i] = null;
5701 }
56815702
5682 llvm_param_i += 1;5703 llvm_param_i += 1;
5683 total_i += 1;5704 total_i += 1;
...@@ -5812,10 +5833,9 @@ pub const FuncGen = struct {...@@ -5812,10 +5833,9 @@ pub const FuncGen = struct {
5812 .Auto,5833 .Auto,
5813 "",5834 "",
5814 );5835 );
5815 for (llvm_param_attrs[0..param_count]) |need_elem_ty, i| {5836 for (llvm_param_attrs[0..param_count]) |llvm_elem_ty, i| {
5816 if (need_elem_ty) {5837 if (llvm_elem_ty) |llvm_ty| {
5817 const elem_ty = llvm_param_types[i].getElementType();5838 llvm.setCallElemTypeAttr(call, i, llvm_ty);
5818 llvm.setCallElemTypeAttr(call, i, elem_ty);
5819 }5839 }
5820 }5840 }
58215841
...@@ -6558,7 +6578,7 @@ pub const FuncGen = struct {...@@ -6558,7 +6578,7 @@ pub const FuncGen = struct {
6558 const base_ptr = try self.resolveInst(bin_op.lhs);6578 const base_ptr = try self.resolveInst(bin_op.lhs);
6559 const offset = try self.resolveInst(bin_op.rhs);6579 const offset = try self.resolveInst(bin_op.rhs);
6560 const ptr_ty = self.air.typeOf(bin_op.lhs);6580 const ptr_ty = self.air.typeOf(bin_op.lhs);
6561 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());6581 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
6562 if (ptr_ty.ptrSize() == .One) {6582 if (ptr_ty.ptrSize() == .One) {
6563 // It's a pointer to an array, so according to LLVM we need an extra GEP index.6583 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
6564 const indices: [2]*const llvm.Value = .{6584 const indices: [2]*const llvm.Value = .{
...@@ -6580,7 +6600,7 @@ pub const FuncGen = struct {...@@ -6580,7 +6600,7 @@ pub const FuncGen = struct {
6580 const offset = try self.resolveInst(bin_op.rhs);6600 const offset = try self.resolveInst(bin_op.rhs);
6581 const negative_offset = self.builder.buildNeg(offset, "");6601 const negative_offset = self.builder.buildNeg(offset, "");
6582 const ptr_ty = self.air.typeOf(bin_op.lhs);6602 const ptr_ty = self.air.typeOf(bin_op.lhs);
6583 const llvm_elem_ty = try self.dg.lowerType(ptr_ty.childType());6603 const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType());
6584 if (ptr_ty.ptrSize() == .One) {6604 if (ptr_ty.ptrSize() == .One) {
6585 // It's a pointer to an array, so according to LLVM we need an extra GEP index.6605 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
6586 const indices: [2]*const llvm.Value = .{6606 const indices: [2]*const llvm.Value = .{
...@@ -7564,7 +7584,7 @@ pub const FuncGen = struct {...@@ -7564,7 +7584,7 @@ pub const FuncGen = struct {
7564 if (self.liveness.isUnused(inst)) return null;7584 if (self.liveness.isUnused(inst)) return null;
75657585
7566 const llvm_i32 = self.context.intType(32);7586 const llvm_i32 = self.context.intType(32);
7567 const llvm_fn_name = "llvm.frameaddress.p0i8";7587 const llvm_fn_name = "llvm.frameaddress.p0";
7568 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {7588 const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
7569 const llvm_p0i8 = self.context.intType(8).pointerType(0);7589 const llvm_p0i8 = self.context.intType(8).pointerType(0);
7570 const param_types = [_]*const llvm.Type{llvm_i32};7590 const param_types = [_]*const llvm.Type{llvm_i32};
...@@ -7694,20 +7714,31 @@ pub const FuncGen = struct {...@@ -7694,20 +7714,31 @@ pub const FuncGen = struct {
7694 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;7714 const atomic_load = self.air.instructions.items(.data)[inst].atomic_load;
7695 const ptr = try self.resolveInst(atomic_load.ptr);7715 const ptr = try self.resolveInst(atomic_load.ptr);
7696 const ptr_ty = self.air.typeOf(atomic_load.ptr);7716 const ptr_ty = self.air.typeOf(atomic_load.ptr);
7697 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst))7717 const ptr_info = ptr_ty.ptrInfo().data;
7718 if (!ptr_info.@"volatile" and self.liveness.isUnused(inst))
7719 return null;
7720 const elem_ty = ptr_info.pointee_type;
7721 if (!elem_ty.hasRuntimeBitsIgnoreComptime())
7698 return null;7722 return null;
7699 const ordering = toLlvmAtomicOrdering(atomic_load.order);7723 const ordering = toLlvmAtomicOrdering(atomic_load.order);
7700 const operand_ty = ptr_ty.elemType();7724 const opt_abi_llvm_ty = self.dg.getAtomicAbiType(elem_ty, false);
7701 const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false);7725 const target = self.dg.module.getTarget();
7726 const ptr_alignment = ptr_info.alignment(target);
7727 const ptr_volatile = llvm.Bool.fromBool(ptr_info.@"volatile");
7728 const elem_llvm_ty = try self.dg.lowerType(elem_ty);
77027729
7703 if (opt_abi_ty) |abi_ty| {7730 if (opt_abi_llvm_ty) |abi_llvm_ty| {
7704 // operand needs widening and truncating7731 // operand needs widening and truncating
7705 const casted_ptr = self.builder.buildBitCast(ptr, abi_ty.pointerType(0), "");7732 const casted_ptr = self.builder.buildBitCast(ptr, abi_llvm_ty.pointerType(0), "");
7706 const load_inst = (try self.load(casted_ptr, ptr_ty)).?;7733 const load_inst = self.builder.buildLoad(abi_llvm_ty, casted_ptr, "");
7734 load_inst.setAlignment(ptr_alignment);
7735 load_inst.setVolatile(ptr_volatile);
7707 load_inst.setOrdering(ordering);7736 load_inst.setOrdering(ordering);
7708 return self.builder.buildTrunc(load_inst, try self.dg.lowerType(operand_ty), "");7737 return self.builder.buildTrunc(load_inst, elem_llvm_ty, "");
7709 }7738 }
7710 const load_inst = (try self.load(ptr, ptr_ty)).?;7739 const load_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
7740 load_inst.setAlignment(ptr_alignment);
7741 load_inst.setVolatile(ptr_volatile);
7711 load_inst.setOrdering(ordering);7742 load_inst.setOrdering(ordering);
7712 return load_inst;7743 return load_inst;
7713 }7744 }
...@@ -8508,7 +8539,7 @@ pub const FuncGen = struct {...@@ -8508,7 +8539,7 @@ pub const FuncGen = struct {
8508 const llvm_ptr_u8 = llvm_u8.pointerType(0);8539 const llvm_ptr_u8 = llvm_u8.pointerType(0);
8509 const llvm_u32 = self.context.intType(32);8540 const llvm_u32 = self.context.intType(32);
85108541
8511 const llvm_fn_name = "llvm.prefetch.p0i8";8542 const llvm_fn_name = "llvm.prefetch.p0";
8512 const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {8543 const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: {
8513 // declare void @llvm.prefetch(i8*, i32, i32, i32)8544 // declare void @llvm.prefetch(i8*, i32, i32, i32)
8514 const llvm_void = self.context.voidType();8545 const llvm_void = self.context.voidType();
...@@ -8660,7 +8691,7 @@ pub const FuncGen = struct {...@@ -8660,7 +8691,7 @@ pub const FuncGen = struct {
8660 opt_llvm_ty: *const llvm.Type,8691 opt_llvm_ty: *const llvm.Type,
8661 opt_handle: *const llvm.Value,8692 opt_handle: *const llvm.Value,
8662 opt_ty: Type,8693 opt_ty: Type,
8663 ) *const llvm.Value {8694 ) !*const llvm.Value {
8664 var buf: Type.Payload.ElemType = undefined;8695 var buf: Type.Payload.ElemType = undefined;
8665 const payload_ty = opt_ty.optionalChild(&buf);8696 const payload_ty = opt_ty.optionalChild(&buf);
86668697
...@@ -8673,7 +8704,8 @@ pub const FuncGen = struct {...@@ -8673,7 +8704,8 @@ pub const FuncGen = struct {
8673 }8704 }
8674 const target = fg.dg.module.getTarget();8705 const target = fg.dg.module.getTarget();
8675 const payload_alignment = payload_ty.abiAlignment(target);8706 const payload_alignment = payload_ty.abiAlignment(target);
8676 const load_inst = fg.builder.buildLoad(payload_ptr.getGEPResultElementType(), payload_ptr, "");8707 const payload_llvm_ty = try fg.dg.lowerType(payload_ty);
8708 const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");
8677 load_inst.setAlignment(payload_alignment);8709 load_inst.setAlignment(payload_alignment);
8678 return load_inst;8710 return load_inst;
8679 }8711 }
...@@ -8758,7 +8790,7 @@ pub const FuncGen = struct {...@@ -8758,7 +8790,7 @@ pub const FuncGen = struct {
8758 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");8790 return self.builder.buildBitCast(new_ptr, result_llvm_ty, "");
8759 },8791 },
8760 else => {8792 else => {
8761 const struct_llvm_ty = try self.dg.lowerType(struct_ty);8793 const struct_llvm_ty = try self.dg.lowerPtrElemTy(struct_ty);
87628794
8763 var ty_buf: Type.Payload.Pointer = undefined;8795 var ty_buf: Type.Payload.Pointer = undefined;
8764 if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| {8796 if (llvmFieldIndex(struct_ty, field_index, target, &ty_buf)) |llvm_field_index| {
...@@ -8815,7 +8847,7 @@ pub const FuncGen = struct {...@@ -8815,7 +8847,7 @@ pub const FuncGen = struct {
8815 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null;8847 if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null;
88168848
8817 const target = self.dg.module.getTarget();8849 const target = self.dg.module.getTarget();
8818 const ptr_alignment = ptr_ty.ptrAlignment(target);8850 const ptr_alignment = info.alignment(target);
8819 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());8851 const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr());
8820 if (info.host_size == 0) {8852 if (info.host_size == 0) {
8821 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);8853 const elem_llvm_ty = try self.dg.lowerType(info.pointee_type);
src/type.zig+5
...@@ -6229,6 +6229,11 @@ pub const Type = extern union {...@@ -6229,6 +6229,11 @@ pub const Type = extern union {
6229 mutable: bool = true, // TODO rename this to const, not mutable6229 mutable: bool = true, // TODO rename this to const, not mutable
6230 @"volatile": bool = false,6230 @"volatile": bool = false,
6231 size: std.builtin.Type.Pointer.Size = .One,6231 size: std.builtin.Type.Pointer.Size = .One,
6232
6233 pub fn alignment(data: Data, target: Target) u32 {
6234 if (data.@"align" != 0) return data.@"align";
6235 return abiAlignment(data.pointee_type, target);
6236 }
6232 };6237 };
6233 };6238 };
62346239