| ... | @@ -1968,7 +1968,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, | ... | @@ -1968,7 +1968,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, |
| 1968 | if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { | 1968 | if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { |
| 1969 | LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), | 1969 | LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), |
| 1970 | ptr_type->data.pointer.vector_index, false); | 1970 | ptr_type->data.pointer.vector_index, false); |
| 1971 | LLVMValueRef loaded_vector = gen_load(g, ptr, ptr_type, ""); | 1971 | uint32_t vec_len = ptr_type->data.pointer.host_int_bytes; |
| | 1972 | LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, ptr_type->data.pointer.child_type), vec_len); |
| | 1973 | LLVMValueRef loaded_vector = gen_load_untyped(g, vec_llvm_ty, ptr, |
| | 1974 | get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); |
| 1972 | LLVMValueRef new_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value, | 1975 | LLVMValueRef new_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value, |
| 1973 | index_val, ""); | 1976 | index_val, ""); |
| 1974 | gen_store(g, new_vector, ptr, ptr_type); | 1977 | gen_store(g, new_vector, ptr, ptr_type); |
| ... | @@ -1985,7 +1988,8 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, | ... | @@ -1985,7 +1988,8 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, |
| 1985 | | 1988 | |
| 1986 | LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); | 1989 | LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); |
| 1987 | LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); | 1990 | LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); |
| 1988 | LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); | 1991 | LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr, |
| | 1992 | get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); |
| 1989 | uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); | 1993 | uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); |
| 1990 | assert(host_bit_count == host_int_bytes * 8); | 1994 | assert(host_bit_count == host_int_bytes * 8); |
| 1991 | uint32_t size_in_bits = type_size_bits(g, child_type); | 1995 | 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_ | ... | @@ -2296,8 +2300,9 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2296 | fn_walk->data.attrs.gen_i += 1; | 2300 | fn_walk->data.attrs.gen_i += 1; |
| 2297 | break; | 2301 | break; |
| 2298 | case FnWalkIdCall: { | 2302 | case FnWalkIdCall: { |
| 2299 | LLVMTypeRef ptr_elem_llvm_ty = LLVMIntType((unsigned)ty_size * 8); | 2303 | LLVMTypeRef int_type_ref = LLVMIntType((unsigned)ty_size * 8); |
| 2300 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, ptr_elem_llvm_ty, val, ""); | 2304 | LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, LLVMPointerType(int_type_ref, 0), ""); |
| | 2305 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, int_type_ref, bitcasted, ""); |
| 2301 | fn_walk->data.call.gen_param_values->append(loaded); | 2306 | fn_walk->data.call.gen_param_values->append(loaded); |
| 2302 | break; | 2307 | break; |
| 2303 | } | 2308 | } |
| ... | @@ -2365,14 +2370,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ | ... | @@ -2365,14 +2370,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2365 | break; | 2370 | break; |
| 2366 | } | 2371 | } |
| 2367 | case FnWalkIdCall: { | 2372 | case FnWalkIdCall: { |
| | 2373 | LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, val, LLVMPointerType(abi_type, 0), ""); |
| 2368 | if (number_of_regs == 1) { | 2374 | if (number_of_regs == 1) { |
| 2369 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, val, ""); | 2375 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, abi_ptr_to_struct, ""); |
| 2370 | fn_walk->data.call.gen_param_values->append(loaded); | 2376 | fn_walk->data.call.gen_param_values->append(loaded); |
| 2371 | break; | 2377 | break; |
| 2372 | } | 2378 | } |
| 2373 | for (uint32_t i = 0; i < number_of_regs; i += 1) { | 2379 | for (uint32_t i = 0; i < number_of_regs; i += 1) { |
| 2374 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder, | 2380 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder, |
| 2375 | abi_type, val, i, ""); | 2381 | abi_type, abi_ptr_to_struct, i, ""); |
| 2376 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, | 2382 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, |
| 2377 | ZigLLVMGetGEPResultElementType(adjusted_ptr_to_struct), | 2383 | ZigLLVMGetGEPResultElementType(adjusted_ptr_to_struct), |
| 2378 | adjusted_ptr_to_struct, ""); | 2384 | adjusted_ptr_to_struct, ""); |
| ... | @@ -2410,13 +2416,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ | ... | @@ -2410,13 +2416,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2410 | LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); | 2416 | LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); |
| 2411 | gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); | 2417 | gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); |
| 2412 | } else { | 2418 | } else { |
| | 2419 | LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, var->value_ref, LLVMPointerType(abi_type, 0), ""); |
| 2413 | for (uint32_t i = 0; i < number_of_regs; i += 1) { | 2420 | for (uint32_t i = 0; i < number_of_regs; i += 1) { |
| 2414 | LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i + i); | 2421 | LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i + i); |
| 2415 | LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false); | 2422 | LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false); |
| 2416 | LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false); | 2423 | LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false); |
| 2417 | LLVMValueRef indices[] = { zero, index }; | 2424 | LLVMValueRef indices[] = { zero, index }; |
| 2418 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder, | 2425 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder, |
| 2419 | abi_type, var->value_ref, indices, 2, ""); | 2426 | abi_type, abi_ptr_to_struct, indices, 2, ""); |
| 2420 | LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct); | 2427 | LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct); |
| 2421 | } | 2428 | } |
| 2422 | fn_walk->data.inits.gen_i += 1; | 2429 | fn_walk->data.inits.gen_i += 1; |
| ... | @@ -2745,7 +2752,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar | ... | @@ -2745,7 +2752,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar |
| 2745 | if (fn_val == nullptr) { | 2752 | if (fn_val == nullptr) { |
| 2746 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, g->any_frame_header_llvm_ty, | 2753 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, g->any_frame_header_llvm_ty, |
| 2747 | target_frame_ptr, frame_fn_ptr_index, ""); | 2754 | target_frame_ptr, frame_fn_ptr_index, ""); |
| 2748 | fn_val = LLVMBuildLoad2(g->builder, LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), | 2755 | fn_val = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(fn_ptr_ptr), |
| 2749 | fn_ptr_ptr, ""); | 2756 | fn_ptr_ptr, ""); |
| 2750 | } | 2757 | } |
| 2751 | LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), | 2758 | LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), |
| ... | @@ -2855,7 +2862,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { | ... | @@ -2855,7 +2862,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { |
| 2855 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), | 2862 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 2856 | g->cur_frame_ptr, frame_ret_start + 1, ""); | 2863 | g->cur_frame_ptr, frame_ret_start + 1, ""); |
| 2857 | LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad2(g->builder, | 2864 | LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad2(g->builder, |
| 2858 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), awaiter_ret_ptr_ptr, ""); | 2865 | ZigLLVMGetGEPResultElementType(awaiter_ret_ptr_ptr), awaiter_ret_ptr_ptr, ""); |
| 2859 | LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr)); | 2866 | LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr)); |
| 2860 | LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, ""); | 2867 | LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, ""); |
| 2861 | LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block); | 2868 | LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block); |
| ... | @@ -2878,7 +2885,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { | ... | @@ -2878,7 +2885,7 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { |
| 2878 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), | 2885 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 2879 | g->cur_frame_ptr, frame_index_trace_arg(g, ret_type) + 1, ""); | 2886 | g->cur_frame_ptr, frame_index_trace_arg(g, ret_type) + 1, ""); |
| 2880 | LLVMValueRef dest_trace_ptr = LLVMBuildLoad2(g->builder, | 2887 | LLVMValueRef dest_trace_ptr = LLVMBuildLoad2(g->builder, |
| 2881 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), | 2888 | ZigLLVMGetGEPResultElementType(awaiter_trace_ptr_ptr), |
| 2882 | awaiter_trace_ptr_ptr, ""); | 2889 | awaiter_trace_ptr_ptr, ""); |
| 2883 | bool is_llvm_alloca; | 2890 | bool is_llvm_alloca; |
| 2884 | LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); | 2891 | 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 | ... | @@ -2902,12 +2909,18 @@ static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVM |
| 2902 | ZigType *return_type = g->cur_fn->type_entry->data.fn.gen_return_type; | 2909 | ZigType *return_type = g->cur_fn->type_entry->data.fn.gen_return_type; |
| 2903 | size_t size = type_size(g, return_type); | 2910 | size_t size = type_size(g, return_type); |
| 2904 | LLVMTypeRef abi_return_type = get_llvm_c_abi_type(g, return_type); | 2911 | LLVMTypeRef abi_return_type = get_llvm_c_abi_type(g, return_type); |
| | 2912 | LLVMTypeRef abi_return_type_pointer = LLVMPointerType(abi_return_type, 0); |
| 2905 | | 2913 | |
| 2906 | if (size < 8) { | 2914 | if (size < 8) { |
| 2907 | return LLVMBuildLoad2(g->builder, abi_return_type, value, ""); | 2915 | LLVMValueRef bitcast = LLVMBuildBitCast(g->builder, value, abi_return_type_pointer, ""); |
| | 2916 | return LLVMBuildLoad2(g->builder, abi_return_type, bitcast, ""); |
| 2908 | } else { | 2917 | } else { |
| | 2918 | LLVMTypeRef i8ptr = LLVMPointerType(LLVMInt8Type(), 0); |
| | 2919 | LLVMValueRef bc_location = LLVMBuildBitCast(g->builder, location, i8ptr, ""); |
| | 2920 | LLVMValueRef bc_value = LLVMBuildBitCast(g->builder, value, i8ptr, ""); |
| | 2921 | |
| 2909 | LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false); | 2922 | LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false); |
| 2910 | ZigLLVMBuildMemCpy(g->builder, location, 8, value, return_type->abi_align, len, false); | 2923 | ZigLLVMBuildMemCpy(g->builder, bc_location, 8, bc_value, return_type->abi_align, len, false); |
| 2911 | return LLVMBuildLoad2(g->builder, abi_return_type, location, ""); | 2924 | return LLVMBuildLoad2(g->builder, abi_return_type, location, ""); |
| 2912 | } | 2925 | } |
| 2913 | } | 2926 | } |
| ... | @@ -4144,20 +4157,21 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable, | ... | @@ -4144,20 +4157,21 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable, |
| 4144 | bool actual_is_ptr = handle_is_ptr(g, actual_type); | 4157 | bool actual_is_ptr = handle_is_ptr(g, actual_type); |
| 4145 | if (wanted_is_ptr == actual_is_ptr) { | 4158 | if (wanted_is_ptr == actual_is_ptr) { |
| 4146 | // We either bitcast the value directly or bitcast the pointer which does a pointer cast | 4159 | // We either bitcast the value directly or bitcast the pointer which does a pointer cast |
| 4147 | if (wanted_is_ptr) { | 4160 | LLVMTypeRef wanted_type_ref = wanted_is_ptr ? |
| 4148 | return value; | 4161 | LLVMPointerType(get_llvm_type(g, wanted_type), 0) : get_llvm_type(g, wanted_type); |
| 4149 | } else { | 4162 | return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); |
| 4150 | LLVMTypeRef wanted_type_ref = get_llvm_type(g, wanted_type); | | |
| 4151 | return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); | | |
| 4152 | } | | |
| 4153 | } else if (actual_is_ptr) { | 4163 | } else if (actual_is_ptr) { |
| 4154 | // A scalar is wanted but we got a pointer | 4164 | // A scalar is wanted but we got a pointer |
| | 4165 | LLVMTypeRef wanted_elem_type_ref = get_llvm_type(g, wanted_type); |
| | 4166 | LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, |
| | 4167 | LLVMPointerType(wanted_elem_type_ref, 0), ""); |
| 4155 | uint32_t alignment = get_abi_alignment(g, actual_type); | 4168 | uint32_t alignment = get_abi_alignment(g, actual_type); |
| 4156 | return gen_load_untyped(g, get_llvm_type(g, wanted_type), value, alignment, false, ""); | 4169 | return gen_load_untyped(g, wanted_elem_type_ref, bitcasted_ptr, alignment, false, ""); |
| 4157 | } else { | 4170 | } else { |
| 4158 | // A pointer is wanted but we got a scalar | 4171 | // A pointer is wanted but we got a scalar |
| 4159 | assert(actual_type->id == ZigTypeIdPointer); | 4172 | assert(actual_type->id == ZigTypeIdPointer); |
| 4160 | return value; | 4173 | LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0); |
| | 4174 | return LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, ""); |
| 4161 | } | 4175 | } |
| 4162 | } | 4176 | } |
| 4163 | | 4177 | |
| ... | @@ -4434,7 +4448,9 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, | ... | @@ -4434,7 +4448,9 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, |
| 4434 | if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { | 4448 | if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { |
| 4435 | LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), | 4449 | LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), |
| 4436 | ptr_type->data.pointer.vector_index, false); | 4450 | ptr_type->data.pointer.vector_index, false); |
| 4437 | LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, get_llvm_type(g, child_type), ptr, ""); | 4451 | uint32_t vec_len = ptr_type->data.pointer.host_int_bytes; |
| | 4452 | LLVMTypeRef vec_llvm_ty = LLVMVectorType(get_llvm_type(g, child_type), vec_len); |
| | 4453 | LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, vec_llvm_ty, ptr, ""); |
| 4438 | return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, ""); | 4454 | return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, ""); |
| 4439 | } | 4455 | } |
| 4440 | | 4456 | |
| ... | @@ -4446,10 +4462,11 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, | ... | @@ -4446,10 +4462,11 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, |
| 4446 | | 4462 | |
| 4447 | LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); | 4463 | LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); |
| 4448 | LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); | 4464 | LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); |
| 4449 | LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); | 4465 | LLVMValueRef containing_int = gen_load_untyped(g, LLVMIntType(host_int_bytes * 8), int_ptr, |
| | 4466 | get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile, ""); |
| 4450 | | 4467 | |
| 4451 | uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); | 4468 | uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); |
| 4452 | assert(host_bit_count == host_int_bytes * 8); | 4469 | ir_assert(host_bit_count == host_int_bytes * 8, &instruction->base); |
| 4453 | uint32_t size_in_bits = type_size_bits(g, child_type); | 4470 | uint32_t size_in_bits = type_size_bits(g, child_type); |
| 4454 | | 4471 | |
| 4455 | uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host; | 4472 | 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 | ... | @@ -4750,13 +4767,15 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4750 | size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; | 4767 | size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; |
| 4751 | if (host_int_bytes != 0) { | 4768 | if (host_int_bytes != 0) { |
| 4752 | uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type); | 4769 | uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type); |
| | 4770 | LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0); |
| | 4771 | LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, ""); |
| 4753 | assert(size_in_bits % 8 == 0); | 4772 | assert(size_in_bits % 8 == 0); |
| 4754 | LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, | 4773 | LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, |
| 4755 | size_in_bits / 8, false); | 4774 | size_in_bits / 8, false); |
| 4756 | LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, ""); | 4775 | LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, ""); |
| 4757 | LLVMValueRef indices[] = { byte_offset }; | 4776 | LLVMValueRef indices[] = { byte_offset }; |
| 4758 | LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), | 4777 | LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), |
| 4759 | array_ptr, indices, 1, ""); | 4778 | u8_array_ptr, indices, 1, ""); |
| 4760 | return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), ""); | 4779 | return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), ""); |
| 4761 | } | 4780 | } |
| 4762 | } | 4781 | } |
| ... | @@ -4802,8 +4821,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 | ... | @@ -4802,8 +4821,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4802 | assert(ptr_index != SIZE_MAX); | 4821 | assert(ptr_index != SIZE_MAX); |
| 4803 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type), | 4822 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type), |
| 4804 | array_ptr, (unsigned)ptr_index, ""); | 4823 | array_ptr, (unsigned)ptr_index, ""); |
| 4805 | LLVMValueRef ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_ptr), ptr_ptr, 0, | 4824 | LLVMValueRef ptr = gen_load_untyped(g, |
| 4806 | false, ""); | 4825 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), ptr_ptr, 0, false, ""); |
| 4807 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type); | 4826 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type); |
| 4808 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, ptr, &subscript_value, 1, ""); | 4827 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, ptr, &subscript_value, 1, ""); |
| 4809 | } else if (array_type->id == ZigTypeIdVector) { | 4828 | } else if (array_type->id == ZigTypeIdVector) { |
| ... | @@ -4938,8 +4957,10 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { | ... | @@ -4938,8 +4957,10 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { |
| 4938 | static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { | 4957 | static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { |
| 4939 | assert(g->need_frame_size_prefix_data); | 4958 | assert(g->need_frame_size_prefix_data); |
| 4940 | LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type; | 4959 | LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type; |
| | 4960 | LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0); |
| | 4961 | LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, ""); |
| 4941 | LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true); | 4962 | LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true); |
| 4942 | LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, fn_val, &negative_one, 1, ""); | 4963 | LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, casted_fn_val, &negative_one, 1, ""); |
| 4943 | LLVMValueRef load_inst = LLVMBuildLoad2(g->builder, usize_llvm_type, prefix_ptr, ""); | 4964 | LLVMValueRef load_inst = LLVMBuildLoad2(g->builder, usize_llvm_type, prefix_ptr, ""); |
| 4944 | | 4965 | |
| 4945 | // Some architectures (e.g SPARCv9) has different alignment requirements between a | 4966 | // 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 | ... | @@ -4980,17 +5001,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 4980 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; | 5001 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 4981 | | 5002 | |
| 4982 | LLVMValueRef fn_val; | 5003 | LLVMValueRef fn_val; |
| | 5004 | LLVMTypeRef fn_llvm_ty; |
| 4983 | ZigType *fn_type; | 5005 | ZigType *fn_type; |
| 4984 | bool callee_is_async; | 5006 | bool callee_is_async; |
| 4985 | if (instruction->fn_entry) { | 5007 | if (instruction->fn_entry) { |
| 4986 | fn_val = fn_llvm_value(g, instruction->fn_entry); | 5008 | fn_val = fn_llvm_value(g, instruction->fn_entry); |
| 4987 | fn_type = instruction->fn_entry->type_entry; | 5009 | fn_type = instruction->fn_entry->type_entry; |
| 4988 | callee_is_async = fn_is_async(instruction->fn_entry); | 5010 | callee_is_async = fn_is_async(instruction->fn_entry); |
| | 5011 | fn_llvm_ty = LLVMGlobalGetValueType(fn_val); |
| 4989 | } else { | 5012 | } else { |
| 4990 | assert(instruction->fn_ref); | 5013 | assert(instruction->fn_ref); |
| 4991 | fn_val = ir_llvm_value(g, instruction->fn_ref); | 5014 | fn_val = ir_llvm_value(g, instruction->fn_ref); |
| 4992 | fn_type = instruction->fn_ref->value->type; | 5015 | fn_type = instruction->fn_ref->value->type; |
| 4993 | callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; | 5016 | callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; |
| | 5017 | fn_llvm_ty = fn_type->data.fn.raw_type_ref; |
| 4994 | } | 5018 | } |
| 4995 | | 5019 | |
| 4996 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; | 5020 | 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 | ... | @@ -5251,6 +5275,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5251 | CalcLLVMFieldIndex arg_calc_start = {0}; | 5275 | CalcLLVMFieldIndex arg_calc_start = {0}; |
| 5252 | frame_index_arg_calc(g, &arg_calc_start, fn_type->data.fn.fn_type_id.return_type); | 5276 | frame_index_arg_calc(g, &arg_calc_start, fn_type->data.fn.fn_type_id.return_type); |
| 5253 | | 5277 | |
| | 5278 | LLVMValueRef casted_frame; |
| 5254 | LLVMTypeRef casted_frame_llvm_ty; | 5279 | LLVMTypeRef casted_frame_llvm_ty; |
| 5255 | if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) { | 5280 | if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) { |
| 5256 | // We need the frame type to be a pointer to a struct that includes the args | 5281 | // 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 | ... | @@ -5282,15 +5307,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5282 | } | 5307 | } |
| 5283 | LLVMTypeRef frame_with_args_type = LLVMStructType(field_types, field_count, false); | 5308 | LLVMTypeRef frame_with_args_type = LLVMStructType(field_types, field_count, false); |
| 5284 | heap::c_allocator.deallocate(field_types, field_count); | 5309 | heap::c_allocator.deallocate(field_types, field_count); |
| | 5310 | LLVMTypeRef ptr_frame_with_args_type = LLVMPointerType(frame_with_args_type, 0); |
| | 5311 | |
| | 5312 | casted_frame = LLVMBuildBitCast(g->builder, frame_result_loc, ptr_frame_with_args_type, ""); |
| 5285 | casted_frame_llvm_ty = frame_with_args_type; | 5313 | casted_frame_llvm_ty = frame_with_args_type; |
| 5286 | } else { | 5314 | } else { |
| | 5315 | casted_frame = frame_result_loc; |
| 5287 | casted_frame_llvm_ty = frame_struct_llvm_ty; | 5316 | casted_frame_llvm_ty = frame_struct_llvm_ty; |
| 5288 | } | 5317 | } |
| 5289 | | 5318 | |
| 5290 | CalcLLVMFieldIndex arg_calc = arg_calc_start; | 5319 | CalcLLVMFieldIndex arg_calc = arg_calc_start; |
| 5291 | for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { | 5320 | for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { |
| 5292 | calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i)); | 5321 | calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i)); |
| 5293 | LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, frame_result_loc, arg_calc.field_index - 1, ""); | 5322 | LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, casted_frame, arg_calc.field_index - 1, ""); |
| 5294 | gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true), | 5323 | gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true), |
| 5295 | gen_param_values.at(arg_i)); | 5324 | gen_param_values.at(arg_i)); |
| 5296 | } | 5325 | } |
| ... | @@ -5384,7 +5413,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI | ... | @@ -5384,7 +5413,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5384 | } | 5413 | } |
| 5385 | | 5414 | |
| 5386 | if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) { | 5415 | if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) { |
| 5387 | result = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, | 5416 | result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, |
| 5388 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); | 5417 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); |
| 5389 | } else if (instruction->modifier == CallModifierAsync) { | 5418 | } else if (instruction->modifier == CallModifierAsync) { |
| 5390 | zig_panic("TODO @asyncCall of non-async function"); | 5419 | zig_panic("TODO @asyncCall of non-async function"); |
| ... | @@ -5398,7 +5427,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI | ... | @@ -5398,7 +5427,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5398 | old_stack_ref = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stacksave_fn_val), stacksave_fn_val, nullptr, 0, ""); | 5427 | old_stack_ref = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stacksave_fn_val), stacksave_fn_val, nullptr, 0, ""); |
| 5399 | } | 5428 | } |
| 5400 | gen_set_stack_pointer(g, new_stack_addr); | 5429 | gen_set_stack_pointer(g, new_stack_addr); |
| 5401 | result = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, | 5430 | result = ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, |
| 5402 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); | 5431 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); |
| 5403 | if (src_return_type->id != ZigTypeIdUnreachable) { | 5432 | if (src_return_type->id != ZigTypeIdUnreachable) { |
| 5404 | LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); | 5433 | LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); |
| ... | @@ -5567,7 +5596,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, | ... | @@ -5567,7 +5596,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, |
| 5567 | | 5596 | |
| 5568 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type), | 5597 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type), |
| 5569 | union_ptr, union_type->data.unionation.gen_union_index, ""); | 5598 | union_ptr, union_type->data.unionation.gen_union_index, ""); |
| 5570 | return union_field_ptr; | 5599 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| | 5600 | return bitcasted_union_field_ptr; |
| 5571 | } | 5601 | } |
| 5572 | | 5602 | |
| 5573 | static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { | 5603 | 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 | ... | @@ -5707,7 +5737,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A |
| 5707 | param_values[param_index] = value_ref; | 5737 | param_values[param_index] = value_ref; |
| 5708 | // In the case of indirect inputs, LLVM requires the callsite to have an elementtype(<ty>) attribute. | 5738 | // In the case of indirect inputs, LLVM requires the callsite to have an elementtype(<ty>) attribute. |
| 5709 | if (buf_ptr(asm_input->constraint)[0] == '*') { | 5739 | if (buf_ptr(asm_input->constraint)[0] == '*') { |
| 5710 | param_needs_attr[param_index] = elem_type_ref; | 5740 | param_needs_attr[param_index] = elem_type_ref ? elem_type_ref : |
| | 5741 | get_llvm_type(g, type->data.pointer.child_type); |
| 5711 | } | 5742 | } |
| 5712 | } | 5743 | } |
| 5713 | for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { | 5744 | 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) { | ... | @@ -6148,7 +6179,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { |
| 6148 | LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); | 6179 | LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); |
| 6149 | | 6180 | |
| 6150 | LLVMValueRef fields[] = { | 6181 | LLVMValueRef fields[] = { |
| 6151 | LLVMConstInBoundsGEP2(LLVMInt8Type(), str_global, array_ptr_indices, 2), | 6182 | LLVMConstInBoundsGEP2(LLVMGlobalGetValueType(str_global), str_global, array_ptr_indices, 2), |
| 6152 | LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), | 6183 | LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), |
| 6153 | }; | 6184 | }; |
| 6154 | LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, u8_slice_type), fields, 2); | 6185 | 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 | ... | @@ -6266,7 +6297,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, Stag |
| 6266 | | 6297 | |
| 6267 | size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; | 6298 | size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 6268 | LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder, | 6299 | LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder, |
| 6269 | get_llvm_type(g, instruction->target->value->type->data.pointer.child_type), | 6300 | get_llvm_type(g, target_type), |
| 6270 | target_val, (unsigned)ptr_index, ""); | 6301 | target_val, (unsigned)ptr_index, ""); |
| 6271 | ptr_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_val_ptr), ptr_val_ptr, 0, false, ""); | 6302 | ptr_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_val_ptr), ptr_val_ptr, 0, false, ""); |
| 6272 | } else { | 6303 | } else { |
| ... | @@ -6909,7 +6940,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { | ... | @@ -6909,7 +6940,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { |
| 6909 | | 6940 | |
| 6910 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), | 6941 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), |
| 6911 | &g->builtin_types.entry_i32->llvm_type, 1, false); | 6942 | &g->builtin_types.entry_i32->llvm_type, 1, false); |
| 6912 | g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0i8", fn_type); | 6943 | g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0", fn_type); |
| 6913 | assert(LLVMGetIntrinsicID(g->frame_address_fn_val)); | 6944 | assert(LLVMGetIntrinsicID(g->frame_address_fn_val)); |
| 6914 | | 6945 | |
| 6915 | return g->frame_address_fn_val; | 6946 | return g->frame_address_fn_val; |
| ... | @@ -7285,9 +7316,10 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable, | ... | @@ -7285,9 +7316,10 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable, |
| 7285 | LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr, false); | 7316 | LLVMTypeRef actual_abi_type = get_atomic_abi_type(g, instruction->ptr, false); |
| 7286 | if (actual_abi_type != nullptr) { | 7317 | if (actual_abi_type != nullptr) { |
| 7287 | // operand needs widening and truncating | 7318 | // operand needs widening and truncating |
| 7288 | ptr = LLVMBuildBitCast(g->builder, ptr, | 7319 | ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(actual_abi_type, 0), ""); |
| 7289 | LLVMPointerType(actual_abi_type, 0), ""); | 7320 | LLVMValueRef load_inst = gen_load_untyped(g, actual_abi_type, ptr, |
| 7290 | LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, ""); | 7321 | get_ptr_align(g, instruction->ptr->value->type), |
| | 7322 | instruction->ptr->value->type->data.pointer.is_volatile, ""); |
| 7291 | LLVMSetOrdering(load_inst, ordering); | 7323 | LLVMSetOrdering(load_inst, ordering); |
| 7292 | return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), ""); | 7324 | return LLVMBuildTrunc(g->builder, load_inst, get_llvm_type(g, operand_type), ""); |
| 7293 | } | 7325 | } |
| ... | @@ -7503,10 +7535,12 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable, | ... | @@ -7503,10 +7535,12 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable, |
| 7503 | ZigType *elem_type = vector_type->data.vector.elem_type; | 7535 | ZigType *elem_type = vector_type->data.vector.elem_type; |
| 7504 | bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; | 7536 | bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; |
| 7505 | if (bitcast_ok) { | 7537 | if (bitcast_ok) { |
| | 7538 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr, |
| | 7539 | LLVMPointerType(vector_type_ref, 0), ""); |
| 7506 | ZigType *array_type = instruction->array->value->type; | 7540 | ZigType *array_type = instruction->array->value->type; |
| 7507 | assert(array_type->id == ZigTypeIdArray); | 7541 | assert(array_type->id == ZigTypeIdArray); |
| 7508 | uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type); | 7542 | uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type); |
| 7509 | return gen_load_untyped(g, vector_type_ref, array_ptr, alignment, false, ""); | 7543 | return gen_load_untyped(g, vector_type_ref, casted_ptr, alignment, false, ""); |
| 7510 | } else { | 7544 | } else { |
| 7511 | // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast | 7545 | // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast |
| 7512 | // will not work, and we fall back to insertelement. | 7546 | // 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 | ... | @@ -8060,28 +8094,32 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co |
| 8060 | LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); | 8094 | LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); |
| 8061 | | 8095 | |
| 8062 | ZigType *usize = g->builtin_types.entry_usize; | 8096 | ZigType *usize = g->builtin_types.entry_usize; |
| | 8097 | LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_const_val->type); |
| | 8098 | LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(array_llvm_ty, 0)); |
| 8063 | LLVMValueRef indices[] = { | 8099 | LLVMValueRef indices[] = { |
| 8064 | LLVMConstNull(usize->llvm_type), | 8100 | LLVMConstNull(usize->llvm_type), |
| 8065 | LLVMConstInt(usize->llvm_type, index, false), | 8101 | LLVMConstInt(usize->llvm_type, index, false), |
| 8066 | }; | 8102 | }; |
| 8067 | return LLVMConstInBoundsGEP2(get_llvm_type(g, array_const_val->type), base_ptr, indices, 2); | 8103 | return LLVMConstInBoundsGEP2(array_llvm_ty, casted_base_ptr, indices, 2); |
| 8068 | } | 8104 | } |
| 8069 | | 8105 | |
| 8070 | static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) { | 8106 | static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) { |
| 8071 | ConstParent *parent = &struct_const_val->parent; | 8107 | ConstParent *parent = &struct_const_val->parent; |
| 8072 | LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); | 8108 | LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); |
| 8073 | | 8109 | |
| 8074 | ZigType *u32 = g->builtin_types.entry_u32; | | |
| 8075 | LLVMValueRef indices[] = { | 8110 | LLVMValueRef indices[] = { |
| 8076 | LLVMConstNull(get_llvm_type(g, u32)), | 8111 | LLVMConstNull(LLVMInt32Type()), |
| 8077 | LLVMConstInt(get_llvm_type(g, u32), field_index, false), | 8112 | LLVMConstInt(LLVMInt32Type(), field_index, false), |
| 8078 | }; | 8113 | }; |
| 8079 | | 8114 | |
| 8080 | // The structure pointed by base_ptr may include trailing padding for | 8115 | // The structure pointed by base_ptr may include trailing padding for |
| 8081 | // alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>. | 8116 | // alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>. |
| 8082 | // Add an extra bitcast as we're only interested in the %T part. | 8117 | // Add an extra bitcast as we're only interested in the %T part. |
| 8083 | assert(handle_is_ptr(g, struct_const_val->type)); | 8118 | assert(handle_is_ptr(g, struct_const_val->type)); |
| 8084 | return LLVMConstInBoundsGEP2(get_llvm_type(g, struct_const_val->type), base_ptr, indices, 2); | 8119 | |
| | 8120 | LLVMTypeRef struct_llvm_ty = get_llvm_type(g, struct_const_val->type); |
| | 8121 | LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, LLVMPointerType(struct_llvm_ty, 0)); |
| | 8122 | return LLVMConstInBoundsGEP2(struct_llvm_ty, casted_base_ptr, indices, 2); |
| 8085 | } | 8123 | } |
| 8086 | | 8124 | |
| 8087 | static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { | 8125 | 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) { | ... | @@ -9398,7 +9436,7 @@ static void do_code_gen(CodeGen *g) { |
| 9398 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), | 9436 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9399 | g->cur_frame_ptr, frame_ret_start, ""); | 9437 | g->cur_frame_ptr, frame_ret_start, ""); |
| 9400 | g->cur_ret_ptr = LLVMBuildLoad2(g->builder, | 9438 | g->cur_ret_ptr = LLVMBuildLoad2(g->builder, |
| 9401 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), cur_ret_ptr_ptr, ""); | 9439 | ZigLLVMGetGEPResultElementType(cur_ret_ptr_ptr), cur_ret_ptr_ptr, ""); |
| 9402 | } | 9440 | } |
| 9403 | uint32_t trace_field_index_stack = UINT32_MAX; | 9441 | uint32_t trace_field_index_stack = UINT32_MAX; |
| 9404 | if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) { | 9442 | if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) { |