mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
more LLVM backend fixes
more carnage from opaque pointers API
This commit is contained in:
parent
99318e7a95
commit
30b98d3973
@ -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(<ty>) 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)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user