| ... | @@ -6767,6 +6767,9 @@ pub const FuncGen = struct { | ... | @@ -6767,6 +6767,9 @@ pub const FuncGen = struct { |
| 6767 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); | 6767 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); |
| 6768 | } | 6768 | } |
| 6769 | | 6769 | |
| | 6770 | /// This function always performs a copy. For isByRef=true types, it creates a new |
| | 6771 | /// alloca and copies the value into it, then returns the alloca instruction. |
| | 6772 | /// For isByRef=false types, it creates a load instruction and returns it. |
| 6770 | fn load(self: *FuncGen, ptr: *const llvm.Value, ptr_ty: Type) !?*const llvm.Value { | 6773 | fn load(self: *FuncGen, ptr: *const llvm.Value, ptr_ty: Type) !?*const llvm.Value { |
| 6771 | const info = ptr_ty.ptrInfo().data; | 6774 | const info = ptr_ty.ptrInfo().data; |
| 6772 | if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null; | 6775 | if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null; |
| ... | @@ -6775,7 +6778,25 @@ pub const FuncGen = struct { | ... | @@ -6775,7 +6778,25 @@ pub const FuncGen = struct { |
| 6775 | const ptr_alignment = ptr_ty.ptrAlignment(target); | 6778 | const ptr_alignment = ptr_ty.ptrAlignment(target); |
| 6776 | const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr()); | 6779 | const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr()); |
| 6777 | if (info.host_size == 0) { | 6780 | if (info.host_size == 0) { |
| 6778 | if (isByRef(info.pointee_type)) return ptr; | 6781 | if (isByRef(info.pointee_type)) { |
| | 6782 | const elem_llvm_ty = try self.dg.llvmType(info.pointee_type); |
| | 6783 | const result_align = info.pointee_type.abiAlignment(target); |
| | 6784 | const max_align = @maximum(result_align, ptr_alignment); |
| | 6785 | const result_ptr = self.buildAlloca(elem_llvm_ty); |
| | 6786 | result_ptr.setAlignment(max_align); |
| | 6787 | const llvm_ptr_u8 = self.context.intType(8).pointerType(0); |
| | 6788 | const llvm_usize = self.context.intType(Type.usize.intInfo(target).bits); |
| | 6789 | const size_bytes = info.pointee_type.abiSize(target); |
| | 6790 | _ = self.builder.buildMemCpy( |
| | 6791 | self.builder.buildBitCast(result_ptr, llvm_ptr_u8, ""), |
| | 6792 | max_align, |
| | 6793 | self.builder.buildBitCast(ptr, llvm_ptr_u8, ""), |
| | 6794 | max_align, |
| | 6795 | llvm_usize.constInt(size_bytes, .False), |
| | 6796 | info.@"volatile", |
| | 6797 | ); |
| | 6798 | return result_ptr; |
| | 6799 | } |
| 6779 | const llvm_inst = self.builder.buildLoad(ptr, ""); | 6800 | const llvm_inst = self.builder.buildLoad(ptr, ""); |
| 6780 | llvm_inst.setAlignment(ptr_alignment); | 6801 | llvm_inst.setAlignment(ptr_alignment); |
| 6781 | llvm_inst.setVolatile(ptr_volatile); | 6802 | llvm_inst.setVolatile(ptr_volatile); |