From 30b98d39731a8645d7a344a24e77a96161cc97a8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 2 Aug 2022 16:48:58 -0700 Subject: [PATCH] more LLVM backend fixes more carnage from opaque pointers API --- src/stage1/codegen.cpp | 128 ++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 45 deletions(-) diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 960800317e..5b2b8c4941 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -1968,7 +1968,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), ptr_type->data.pointer.vector_index, false); - LLVMValueRef loaded_vector = gen_load(g, ptr, ptr_type, ""); + uint32_t vec_len = ptr_type->data.pointer.host_int_bytes; + LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, ptr_type->data.pointer.child_type), vec_len); + LLVMValueRef loaded_vector = gen_load_untyped(g, vec_llvm_ty, ptr, + get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); LLVMValueRef new_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value, index_val, ""); gen_store(g, new_vector, ptr, ptr_type); @@ -1985,7 +1988,8 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); - LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); + LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr, + get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); assert(host_bit_count == host_int_bytes * 8); uint32_t size_in_bits = type_size_bits(g, child_type); @@ -2296,8 +2300,9 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ fn_walk->data.attrs.gen_i += 1; break; case FnWalkIdCall: { - LLVMTypeRef ptr_elem_llvm_ty = LLVMIntType((unsigned)ty_size * 8); - LLVMValueRef loaded = LLVMBuildLoad2(g->builder, ptr_elem_llvm_ty, val, ""); + LLVMTypeRef int_type_ref = LLVMIntType((unsigned)ty_size * 8); + LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, LLVMPointerType(int_type_ref, 0), ""); + LLVMValueRef loaded = LLVMBuildLoad2(g->builder, int_type_ref, bitcasted, ""); fn_walk->data.call.gen_param_values->append(loaded); break; } @@ -2365,14 +2370,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ break; } case FnWalkIdCall: { + LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, val, LLVMPointerType(abi_type, 0), ""); if (number_of_regs == 1) { - LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, val, ""); + LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, abi_ptr_to_struct, ""); fn_walk->data.call.gen_param_values->append(loaded); break; } for (uint32_t i = 0; i < number_of_regs; i += 1) { LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder, - abi_type, val, i, ""); + abi_type, abi_ptr_to_struct, i, ""); LLVMValueRef loaded = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(adjusted_ptr_to_struct), adjusted_ptr_to_struct, ""); @@ -2410,13 +2416,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); } else { + LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, var->value_ref, LLVMPointerType(abi_type, 0), ""); for (uint32_t i = 0; i < number_of_regs; i += 1) { LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i + i); LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false); LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false); LLVMValueRef indices[] = { zero, index }; LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder, - abi_type, var->value_ref, indices, 2, ""); + abi_type, abi_ptr_to_struct, indices, 2, ""); LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct); } fn_walk->data.inits.gen_i += 1; @@ -2745,7 +2752,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar if (fn_val == nullptr) { LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, g->any_frame_header_llvm_ty, target_frame_ptr, frame_fn_ptr_index, ""); - fn_val = LLVMBuildLoad2(g->builder, LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), + fn_val = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(fn_ptr_ptr), fn_ptr_ptr, ""); } LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), @@ -2855,7 +2862,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), g->cur_frame_ptr, frame_ret_start + 1, ""); LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad2(g->builder, - LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), awaiter_ret_ptr_ptr, ""); + ZigLLVMGetGEPResultElementType(awaiter_ret_ptr_ptr), awaiter_ret_ptr_ptr, ""); LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr)); LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, ""); LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block); @@ -2878,7 +2885,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), g->cur_frame_ptr, frame_index_trace_arg(g, ret_type) + 1, ""); LLVMValueRef dest_trace_ptr = LLVMBuildLoad2(g->builder, - LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), + ZigLLVMGetGEPResultElementType(awaiter_trace_ptr_ptr), awaiter_trace_ptr_ptr, ""); bool is_llvm_alloca; LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); @@ -2902,12 +2909,18 @@ static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVM ZigType *return_type = g->cur_fn->type_entry->data.fn.gen_return_type; size_t size = type_size(g, return_type); LLVMTypeRef abi_return_type = get_llvm_c_abi_type(g, return_type); + LLVMTypeRef abi_return_type_pointer = LLVMPointerType(abi_return_type, 0); if (size < 8) { - return LLVMBuildLoad2(g->builder, abi_return_type, value, ""); + LLVMValueRef bitcast = LLVMBuildBitCast(g->builder, value, abi_return_type_pointer, ""); + return LLVMBuildLoad2(g->builder, abi_return_type, bitcast, ""); } else { + LLVMTypeRef i8ptr = LLVMPointerType(LLVMInt8Type(), 0); + LLVMValueRef bc_location = LLVMBuildBitCast(g->builder, location, i8ptr, ""); + LLVMValueRef bc_value = LLVMBuildBitCast(g->builder, value, i8ptr, ""); + LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false); - ZigLLVMBuildMemCpy(g->builder, location, 8, value, return_type->abi_align, len, false); + ZigLLVMBuildMemCpy(g->builder, bc_location, 8, bc_value, return_type->abi_align, len, false); return LLVMBuildLoad2(g->builder, abi_return_type, location, ""); } } @@ -4144,20 +4157,21 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable, bool actual_is_ptr = handle_is_ptr(g, actual_type); if (wanted_is_ptr == actual_is_ptr) { // We either bitcast the value directly or bitcast the pointer which does a pointer cast - if (wanted_is_ptr) { - return value; - } else { - LLVMTypeRef wanted_type_ref = get_llvm_type(g, wanted_type); - return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); - } + LLVMTypeRef wanted_type_ref = wanted_is_ptr ? + LLVMPointerType(get_llvm_type(g, wanted_type), 0) : get_llvm_type(g, wanted_type); + return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); } else if (actual_is_ptr) { // A scalar is wanted but we got a pointer + LLVMTypeRef wanted_elem_type_ref = get_llvm_type(g, wanted_type); + LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, + LLVMPointerType(wanted_elem_type_ref, 0), ""); uint32_t alignment = get_abi_alignment(g, actual_type); - return gen_load_untyped(g, get_llvm_type(g, wanted_type), value, alignment, false, ""); + return gen_load_untyped(g, wanted_elem_type_ref, bitcasted_ptr, alignment, false, ""); } else { // A pointer is wanted but we got a scalar assert(actual_type->id == ZigTypeIdPointer); - return value; + LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0); + return LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, ""); } } @@ -4434,7 +4448,9 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), ptr_type->data.pointer.vector_index, false); - LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, get_llvm_type(g, child_type), ptr, ""); + uint32_t vec_len = ptr_type->data.pointer.host_int_bytes; + LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, child_type), vec_len); + LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, vec_llvm_ty, ptr, ""); return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, ""); } @@ -4446,10 +4462,11 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); - LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); + LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr, + get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); - assert(host_bit_count == host_int_bytes * 8); + ir_assert(host_bit_count == host_int_bytes * 8, &instruction->base); uint32_t size_in_bits = type_size_bits(g, child_type); uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host; @@ -4750,13 +4767,15 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; if (host_int_bytes != 0) { uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type); + LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0); + LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, ""); assert(size_in_bits % 8 == 0); LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, size_in_bits / 8, false); LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, ""); LLVMValueRef indices[] = { byte_offset }; LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), - array_ptr, indices, 1, ""); + u8_array_ptr, indices, 1, ""); return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), ""); } } @@ -4802,8 +4821,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 assert(ptr_index != SIZE_MAX); LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type), array_ptr, (unsigned)ptr_index, ""); - LLVMValueRef ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_ptr), ptr_ptr, 0, - false, ""); + LLVMValueRef ptr = gen_load_untyped(g, + LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), ptr_ptr, 0, false, ""); LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type); return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, ptr, &subscript_value, 1, ""); } else if (array_type->id == ZigTypeIdVector) { @@ -4938,8 +4957,10 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { assert(g->need_frame_size_prefix_data); LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type; + LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0); + LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, ""); LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true); - LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, fn_val, &negative_one, 1, ""); + LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, casted_fn_val, &negative_one, 1, ""); LLVMValueRef load_inst = LLVMBuildLoad2(g->builder, usize_llvm_type, prefix_ptr, ""); // Some architectures (e.g SPARCv9) has different alignment requirements between a @@ -4980,17 +5001,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; LLVMValueRef fn_val; + LLVMTypeRef fn_llvm_ty; ZigType *fn_type; bool callee_is_async; if (instruction->fn_entry) { fn_val = fn_llvm_value(g, instruction->fn_entry); fn_type = instruction->fn_entry->type_entry; callee_is_async = fn_is_async(instruction->fn_entry); + fn_llvm_ty = LLVMGlobalGetValueType(fn_val); } else { assert(instruction->fn_ref); fn_val = ir_llvm_value(g, instruction->fn_ref); fn_type = instruction->fn_ref->value->type; callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; + fn_llvm_ty = fn_type->data.fn.raw_type_ref; } FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; @@ -5251,6 +5275,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI CalcLLVMFieldIndex arg_calc_start = {0}; frame_index_arg_calc(g, &arg_calc_start, fn_type->data.fn.fn_type_id.return_type); + LLVMValueRef casted_frame; LLVMTypeRef casted_frame_llvm_ty; if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) { // We need the frame type to be a pointer to a struct that includes the args @@ -5282,15 +5307,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI } LLVMTypeRef frame_with_args_type = LLVMStructType(field_types, field_count, false); heap::c_allocator.deallocate(field_types, field_count); + LLVMTypeRef ptr_frame_with_args_type = LLVMPointerType(frame_with_args_type, 0); + + casted_frame = LLVMBuildBitCast(g->builder, frame_result_loc, ptr_frame_with_args_type, ""); casted_frame_llvm_ty = frame_with_args_type; } else { + casted_frame = frame_result_loc; casted_frame_llvm_ty = frame_struct_llvm_ty; } CalcLLVMFieldIndex arg_calc = arg_calc_start; for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i)); - LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, frame_result_loc, arg_calc.field_index - 1, ""); + LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, casted_frame, arg_calc.field_index - 1, ""); gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true), gen_param_values.at(arg_i)); } @@ -5384,7 +5413,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI } if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) { - result = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, + result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); } else if (instruction->modifier == CallModifierAsync) { zig_panic("TODO @asyncCall of non-async function"); @@ -5398,7 +5427,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI old_stack_ref = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stacksave_fn_val), stacksave_fn_val, nullptr, 0, ""); } gen_set_stack_pointer(g, new_stack_addr); - result = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, + result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); if (src_return_type->id != ZigTypeIdUnreachable) { LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); @@ -5567,7 +5596,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type), union_ptr, union_type->data.unionation.gen_union_index, ""); - return union_field_ptr; + LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); + return bitcasted_union_field_ptr; } static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { @@ -5707,7 +5737,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A param_values[param_index] = value_ref; // In the case of indirect inputs, LLVM requires the callsite to have an elementtype() attribute. if (buf_ptr(asm_input->constraint)[0] == '*') { - param_needs_attr[param_index] = elem_type_ref; + param_needs_attr[param_index] = elem_type_ref ? elem_type_ref : + get_llvm_type(g, type->data.pointer.child_type); } } for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { @@ -6148,7 +6179,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); LLVMValueRef fields[] = { - LLVMConstInBoundsGEP2(LLVMInt8Type(), str_global, array_ptr_indices, 2), + LLVMConstInBoundsGEP2(LLVMGlobalGetValueType(str_global), str_global, array_ptr_indices, 2), LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), }; LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, u8_slice_type), fields, 2); @@ -6266,7 +6297,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, Stag size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder, - get_llvm_type(g, instruction->target->value->type->data.pointer.child_type), + get_llvm_type(g, target_type), target_val, (unsigned)ptr_index, ""); ptr_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_val_ptr), ptr_val_ptr, 0, false, ""); } else { @@ -6909,7 +6940,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), &g->builtin_types.entry_i32->llvm_type, 1, false); - g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0i8", fn_type); + g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0", fn_type); assert(LLVMGetIntrinsicID(g->frame_address_fn_val)); return g->frame_address_fn_val; @@ -7285,9 +7316,10 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable, LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr, false); if (actual_abi_type != nullptr) { // operand needs widening and truncating - ptr = LLVMBuildBitCast(g->builder, ptr, - LLVMPointerType(actual_abi_type, 0), ""); - LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, ""); + ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(actual_abi_type, 0), ""); + LLVMValueRef load_inst = gen_load_untyped(g, actual_abi_type, ptr, + get_ptr_align(g, instruction->ptr->value->type), + instruction->ptr->value->type->data.pointer.is_volatile, ""); LLVMSetOrdering(load_inst, ordering); return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), ""); } @@ -7503,10 +7535,12 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable, ZigType *elem_type = vector_type->data.vector.elem_type; bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; if (bitcast_ok) { + LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr, + LLVMPointerType(vector_type_ref, 0), ""); ZigType *array_type = instruction->array->value->type; assert(array_type->id == ZigTypeIdArray); uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type); - return gen_load_untyped(g, vector_type_ref, array_ptr, alignment, false, ""); + return gen_load_untyped(g, vector_type_ref, casted_ptr, alignment, false, ""); } else { // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast // will not work, and we fall back to insertelement. @@ -8060,28 +8094,32 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); ZigType *usize = g->builtin_types.entry_usize; + LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_const_val->type); + LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(array_llvm_ty, 0)); LLVMValueRef indices[] = { LLVMConstNull(usize->llvm_type), LLVMConstInt(usize->llvm_type, index, false), }; - return LLVMConstInBoundsGEP2(get_llvm_type(g, array_const_val->type), base_ptr, indices, 2); + return LLVMConstInBoundsGEP2(array_llvm_ty, casted_base_ptr, indices, 2); } static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) { ConstParent *parent = &struct_const_val->parent; LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); - ZigType *u32 = g->builtin_types.entry_u32; LLVMValueRef indices[] = { - LLVMConstNull(get_llvm_type(g, u32)), - LLVMConstInt(get_llvm_type(g, u32), field_index, false), + LLVMConstNull(LLVMInt32Type()), + LLVMConstInt(LLVMInt32Type(), field_index, false), }; // The structure pointed by base_ptr may include trailing padding for // alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>. // Add an extra bitcast as we're only interested in the %T part. assert(handle_is_ptr(g, struct_const_val->type)); - return LLVMConstInBoundsGEP2(get_llvm_type(g, struct_const_val->type), base_ptr, indices, 2); + + LLVMTypeRef struct_llvm_ty = get_llvm_type(g, struct_const_val->type); + LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(struct_llvm_ty, 0)); + return LLVMConstInBoundsGEP2(struct_llvm_ty, casted_base_ptr, indices, 2); } static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { @@ -9398,7 +9436,7 @@ static void do_code_gen(CodeGen *g) { get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), g->cur_frame_ptr, frame_ret_start, ""); g->cur_ret_ptr = LLVMBuildLoad2(g->builder, - LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), cur_ret_ptr_ptr, ""); + ZigLLVMGetGEPResultElementType(cur_ret_ptr_ptr), cur_ret_ptr_ptr, ""); } uint32_t trace_field_index_stack = UINT32_MAX; if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) {