aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-09-13 15:39:19 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-09-13 15:39:19 -0700
commit716d9237cb757c15217b21964fde8e755aabe853 (patch)
tree92760021e4d49af92db2d37701f4a303d32d69ac /src/stage1/codegen.cpp
parentfda6d44778f3faf53c66945a0db65be68113416f (diff)
parent0a4cfb81bcca0ca514758049f8d7d99224537f93 (diff)
downloadzig-716d9237cb757c15217b21964fde8e755aabe853.tar.gz
zig-716d9237cb757c15217b21964fde8e755aabe853.zip
Merge remote-tracking branch 'origin/llvm15'
Upgrade to LLVM 15
Diffstat (limited to 'src/stage1/codegen.cpp')
-rw-r--r--src/stage1/codegen.cpp911
1 files changed, 548 insertions, 363 deletions
diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp
index cc6c0f22a7..55aa73a3b7 100644
--- a/src/stage1/codegen.cpp
+++ b/src/stage1/codegen.cpp
@@ -88,8 +88,8 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val);
static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr);
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr,
- LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
- LLVMValueRef result_loc, bool non_async);
+ LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr,
+ ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async);
static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
@@ -223,7 +223,7 @@ static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
if (g->unwind_tables) {
- addLLVMFnAttr(fn_val, "uwtable");
+ addLLVMFnAttrStr(fn_val, "uwtable", "sync");
}
}
@@ -911,14 +911,12 @@ static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr,
return gen_store_untyped(g, value, ptr, alignment, ptr_type->data.pointer.is_volatile);
}
-static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alignment, bool is_volatile,
- const char *name)
+static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMTypeRef elem_llvm_ty, LLVMValueRef ptr,
+ uint32_t alignment, bool is_volatile, const char *name)
{
- LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, name);
+ LLVMValueRef result = LLVMBuildLoad2(g->builder, elem_llvm_ty, ptr, name);
if (is_volatile) LLVMSetVolatile(result, true);
- if (alignment == 0) {
- LLVMSetAlignment(result, LLVMABIAlignmentOfType(g->target_data_ref, LLVMGetElementType(LLVMTypeOf(ptr))));
- } else {
+ if (alignment != 0) {
LLVMSetAlignment(result, alignment);
}
return result;
@@ -927,7 +925,9 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alig
static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) {
assert(ptr_type->id == ZigTypeIdPointer);
uint32_t alignment = get_ptr_align(g, ptr_type);
- return gen_load_untyped(g, ptr, alignment, ptr_type->data.pointer.is_volatile, name);
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type);
+ bool is_volatile = ptr_type->data.pointer.is_volatile;
+ return gen_load_untyped(g, elem_llvm_ty, ptr, alignment, is_volatile, name);
}
static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) {
@@ -1090,7 +1090,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
msg_arg,
stack_trace_arg,
};
- ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, "");
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, "");
if (!stack_trace_is_llvm_alloca) {
// The stack trace argument is not in the stack of the caller, so
// we'd like to set tail call here, but because slices (the type of msg_arg) are
@@ -1161,7 +1161,7 @@ static LLVMValueRef gen_prefetch(CodeGen *g) {
LLVMInt32Type(),
};
LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 4, false);
- g->prefetch = LLVMAddFunction(g->module, "llvm.prefetch.p0i8", fn_type);
+ g->prefetch = LLVMAddFunction(g->module, "llvm.prefetch.p0", fn_type);
assert(LLVMGetIntrinsicID(g->prefetch));
return g->prefetch;
@@ -1265,26 +1265,37 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
LLVMValueRef address_value = LLVMGetParam(fn_val, 1);
size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
- LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, "");
+ LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ err_ret_trace_ptr, (unsigned)index_field_index, "");
size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");
+ LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ err_ret_trace_ptr, (unsigned)addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)ptr_field_index, "");
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
-
- LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
- LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)len_field_index, "");
+
+ LLVMValueRef len_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
+ LLVMValueRef index_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(index_field_ptr),
+ index_field_ptr, 0, false, "");
LLVMValueRef len_val_minus_one = LLVMBuildSub(g->builder, len_value, LLVMConstInt(usize_type_ref, 1, false), "");
LLVMValueRef masked_val = LLVMBuildAnd(g->builder, index_val, len_val_minus_one, "");
LLVMValueRef address_indices[] = {
masked_val,
};
- LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
- LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, "");
+ LLVMValueRef ptr_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
+ LLVMValueRef address_slot = LLVMBuildInBoundsGEP2(g->builder, usize_type_ref, ptr_value, address_indices, 1, "");
gen_store_untyped(g, address_value, address_slot, 0, false);
@@ -1340,7 +1351,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_i32));
- LLVMValueRef return_address_ptr = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef return_address_ptr = LLVMBuildCall2(g->builder,
+ LLVMGlobalGetValueType(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, "");
LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, "");
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
@@ -1355,7 +1367,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block);
LLVMValueRef args[] = { err_ret_trace_ptr, return_address };
- ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(add_error_return_trace_addr_fn_val),
+ add_error_return_trace_addr_fn_val, args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
LLVMBuildRetVoid(g->builder);
@@ -1446,25 +1459,32 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMConstNull(usize_ty->llvm_type),
err_val,
};
- LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");
+ LLVMValueRef err_name_val = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGlobalGetValueType(g->err_name_table),
+ g->err_name_table, err_table_indices, 2, "");
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_ptr_index, "");
- LLVMValueRef err_name_ptr = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(err_name_val), err_name_val, slice_ptr_index, "");
+ LLVMValueRef err_name_ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
- LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(err_name_val), err_name_val, slice_len_index, "");
+ LLVMValueRef err_name_len = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false);
// Points to the beginning of msg_buffer
LLVMValueRef msg_buffer_ptr_indices[] = {
LLVMConstNull(usize_ty->llvm_type),
};
- LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, "");
+ LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer,
+ msg_buffer_ptr_indices, 1, "");
// Points to the beginning of the constant prefix message
LLVMValueRef msg_prefix_ptr_indices[] = {
LLVMConstNull(usize_ty->llvm_type),
};
- LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1);
+ LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP2(LLVMInt8Type(), msg_prefix, msg_prefix_ptr_indices, 1);
// Build the message using the prefix...
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false);
@@ -1472,16 +1492,18 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMValueRef msg_buffer_ptr_after_indices[] = {
msg_prefix_len,
};
- LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, "");
+ LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer, msg_buffer_ptr_after_indices, 1, "");
ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false);
// Set the slice pointer
- LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, "");
+ LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, str_type), msg_slice, slice_ptr_index, "");
gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false);
// Set the slice length
LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, "");
- LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, "");
+ LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, str_type), msg_slice, slice_len_index, "");
gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false);
// Call panic()
@@ -1522,13 +1544,15 @@ static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *sc
err_ret_trace_val,
err_val,
};
- call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2,
+ call_instruction = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(safety_crash_err_fn),
+ safety_crash_err_fn, args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
} else {
LLVMValueRef args[] = {
err_val,
};
- call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1,
+ call_instruction = ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(safety_crash_err_fn),
+ safety_crash_err_fn, args, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
if (!is_llvm_alloca) {
@@ -1573,7 +1597,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
static void add_sentinel_check(CodeGen *g, LLVMValueRef sentinel_elem_ptr, ZigValue *sentinel) {
LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, "");
- LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, "");
+ LLVMValueRef actual_sentinel = gen_load_untyped(g, LLVMTypeOf(expected_sentinel), sentinel_elem_ptr, 0, false, "");
LLVMValueRef ok_bit;
if (sentinel->type->id == ZigTypeIdFloat) {
ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, actual_sentinel, expected_sentinel, "");
@@ -1706,7 +1730,7 @@ static LLVMValueRef gen_soft_float_widen_or_shorten(CodeGen *g, ZigType *actual_
func_ref = LLVMAddFunction(g->module, fn_name, fn_type);
}
- result = LLVMBuildCall(g->builder, func_ref, &expr_val, 1, "");
+ result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &expr_val, 1, "");
// On non-Arm platforms we need to bitcast __trunc<>fhf2 result back to f16
if (castTruncatedToF16) {
@@ -1852,7 +1876,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul
val1,
val2,
};
- LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
if (operand_type->id == ZigTypeIdVector) {
@@ -1944,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);
@@ -1961,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);
@@ -2272,9 +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_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
- LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, ptr_to_int_type_ref, "");
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, bitcasted, "");
+ 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;
}
@@ -2344,16 +2372,16 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
case FnWalkIdCall: {
LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, val, LLVMPointerType(abi_type, 0), "");
if (number_of_regs == 1) {
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, abi_ptr_to_struct, "");
+ 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 zero = LLVMConstInt(LLVMInt32Type(), 0, false);
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false);
- LLVMValueRef indices[] = { zero, index };
- LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, "");
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, adjusted_ptr_to_struct, "");
+ LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder,
+ abi_type, abi_ptr_to_struct, i, "");
+ LLVMTypeRef field_llvm_ty = LLVMStructGetTypeAtIndex(abi_type, i);
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, field_llvm_ty,
+ adjusted_ptr_to_struct, "");
fn_walk->data.call.gen_param_values->append(loaded);
}
break;
@@ -2394,7 +2422,8 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false);
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false);
LLVMValueRef indices[] = { zero, index };
- LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, "");
+ LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder,
+ abi_type, abi_ptr_to_struct, indices, 2, "");
LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct);
}
fn_walk->data.inits.gen_i += 1;
@@ -2573,8 +2602,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
LLVMBasicBlockRef non_null_block = LLVMAppendBasicBlock(fn_val, "NonNull");
- LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
- LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
+ LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+ LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frame_index");
+ LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frames_left");
LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);
@@ -2589,18 +2619,27 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, non_null_block);
size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
+ LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr,
(unsigned)src_index_field_index, "");
- LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
+ LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr,
(unsigned)src_addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_addresses_field_ptr),
+ src_addresses_field_ptr, (unsigned)ptr_field_index, "");
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
- LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
- LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
- LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, "");
+ LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_addresses_field_ptr),
+ src_addresses_field_ptr, (unsigned)len_field_index, "");
+ LLVMValueRef src_index_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_index_field_ptr), src_index_field_ptr, "");
+ LLVMValueRef src_ptr_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_ptr_field_ptr), src_ptr_field_ptr, "");
+ LLVMValueRef src_len_val = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(src_len_field_ptr), src_len_field_ptr, "");
LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, "");
LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap");
LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap");
@@ -2608,14 +2647,14 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block);
LLVMPositionBuilderAtEnd(g->builder, no_wrap_block);
- LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
+ LLVMValueRef usize_zero = LLVMConstNull(usize_type_ref);
LLVMBuildStore(g->builder, usize_zero, frame_index_ptr);
LLVMBuildStore(g->builder, src_index_val, frames_left_ptr);
LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, "");
LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block);
LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block);
- LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false);
+ LLVMValueRef usize_one = LLVMConstInt(usize_type_ref, 1, false);
LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, "");
LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, "");
LLVMBuildStore(g->builder, mod_len, frame_index_ptr);
@@ -2623,12 +2662,15 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildBr(g->builder, loop_block);
LLVMPositionBuilderAtEnd(g->builder, loop_block);
- LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
- LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
- LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
+ LLVMValueRef ptr_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, "");
+ LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ usize_type_ref, src_ptr_val, &ptr_index, 1, "");
+ LLVMValueRef this_addr_val = LLVMBuildLoad2(g->builder, ZigLLVMGetGEPResultElementType(addr_ptr),
+ addr_ptr, "");
LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
- ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
- LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(add_error_return_trace_addr_fn_val),
+ add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, "");
+ LLVMValueRef prev_frames_left = LLVMBuildLoad2(g->builder, usize_type_ref, frames_left_ptr, "");
LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue");
@@ -2639,7 +2681,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, continue_block);
LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr);
- LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
+ LLVMValueRef prev_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, "");
LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, "");
LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, "");
LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr);
@@ -2666,13 +2708,14 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executabl
bool is_llvm_alloca;
LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope,
&is_llvm_alloca);
- ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(return_err_fn), return_err_fn, &my_err_trace_val, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
if (fn_is_async(g->cur_fn) && codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
- LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
- frame_index_trace_arg(g, ret_type), "");
+ ZigType *frame_type = get_fn_frame_type(g, g->cur_fn);
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, frame_type),
+ g->cur_frame_ptr, frame_index_trace_arg(g, ret_type), "");
LLVMBuildStore(g->builder, my_err_trace_val, trace_ptr_ptr);
}
@@ -2702,16 +2745,21 @@ static void gen_assert_resume_id(CodeGen *g, Stage1AirInst *source_instr, Resume
LLVMPositionBuilderAtEnd(g->builder, end_bb);
}
-static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, ResumeId resume_id) {
+static LLVMValueRef gen_resume(CodeGen *g, LLVMTypeRef fn_llvm_ty, LLVMValueRef fn_val,
+ LLVMValueRef target_frame_ptr, ResumeId resume_id)
+{
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
if (fn_val == nullptr) {
- LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_fn_ptr_index, "");
- fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, "");
+ 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, ZigLLVMGetGEPResultElementType(fn_ptr_ptr),
+ fn_ptr_ptr, "");
}
LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
LLVMConstInt(usize_type_ref, resume_id, false));
LLVMValueRef args[] = {target_frame_ptr, arg_val};
- return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, "");
+ return ZigLLVMBuildCall(g->builder, fn_llvm_ty, fn_val, args, 2, ZigLLVM_Fast,
+ ZigLLVM_CallAttrAuto, "");
}
static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) {
@@ -2733,11 +2781,11 @@ static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) {
LLVMSetTailCall(call_inst, true);
}
-static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, LLVMValueRef val,
- LLVMAtomicOrdering order)
+static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr,
+ LLVMValueRef val, LLVMAtomicOrdering order)
{
if (g->is_single_threaded) {
- LLVMValueRef loaded = LLVMBuildLoad(g->builder, ptr, "");
+ LLVMValueRef loaded = LLVMBuildLoad2(g->builder, LLVMTypeOf(val), ptr, "");
LLVMValueRef modified;
switch (op) {
case LLVMAtomicRMWBinOpXchg:
@@ -2811,8 +2859,11 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
// If the awaiter result pointer is non-null, we need to copy the result to there.
LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult");
LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd");
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, "");
- LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, "");
+ LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ 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,
+ 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);
@@ -2831,21 +2882,26 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
LLVMPositionBuilderAtEnd(g->builder, copy_end_block);
if (codegen_fn_has_err_ret_tracing_arg(g, ret_type)) {
- LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
- frame_index_trace_arg(g, ret_type) + 1, "");
- LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, "");
+ LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ 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,
+ 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);
LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(get_merge_err_ret_traces_fn_val(g)),
+ get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
}
// Resume the caller by tail calling them.
ZigType *any_frame_type = get_any_frame_type(g, ret_type);
- LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, get_llvm_type(g, any_frame_type), "");
- LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn);
+ LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val,
+ get_llvm_type(g, any_frame_type), "");
+ LLVMValueRef call_inst = gen_resume(g, g->anyframe_fn_type, nullptr, their_frame_ptr, ResumeIdReturn);
set_tail_call_if_appropriate(g, call_inst);
LLVMBuildRetVoid(g->builder);
}
@@ -2853,13 +2909,12 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) {
static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVMValueRef value) {
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) {
LLVMValueRef bitcast = LLVMBuildBitCast(g->builder, value, abi_return_type_pointer, "");
- return LLVMBuildLoad(g->builder, bitcast, "");
+ return LLVMBuildLoad2(g->builder, abi_return_type, bitcast, "");
} else {
LLVMTypeRef i8ptr = LLVMPointerType(LLVMInt8Type(), 0);
LLVMValueRef bc_location = LLVMBuildBitCast(g->builder, location, i8ptr, "");
@@ -2867,7 +2922,7 @@ static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVM
LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false);
ZigLLVMBuildMemCpy(g->builder, bc_location, 8, bc_value, return_type->abi_align, len, false);
- return LLVMBuildLoad(g->builder, location, "");
+ return LLVMBuildLoad2(g->builder, abi_return_type, location, "");
}
}
@@ -2903,19 +2958,21 @@ static LLVMValueRef ir_render_return(CodeGen *g, Stage1Air *executable, Stage1Ai
} else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync &&
handle_is_ptr(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
{
+ LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type);
if (instruction->operand == nullptr) {
- LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
} else {
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
- LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, value, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
}
} else if (instruction->operand == nullptr) {
if (g->cur_ret_ptr == nullptr) {
LLVMBuildRetVoid(g->builder);
} else {
- LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
+ LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type);
+ LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, "");
LLVMBuildRet(g->builder, by_val_value);
}
} else {
@@ -3011,20 +3068,18 @@ static LLVMValueRef gen_soft_float_un_op(CodeGen *g, LLVMValueRef op, ZigType *o
float_un_op_to_name(op_id), libc_float_suffix(g, scalar_type));
LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, 1, scalar_type->llvm_type, scalar_type->llvm_type);
- LLVMValueRef result;
if (vector_len == 0) {
- return LLVMBuildCall(g->builder, func_ref, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &op, 1, "");
} else {
- result = build_alloca(g, operand_type, "", 0);
+ LLVMValueRef result = LLVMGetUndef(operand_type->llvm_type);
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
LLVMValueRef param = LLVMBuildExtractElement(g->builder, op, index_value, "");
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, &param, 1, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, &param, 1, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
- return LLVMBuildLoad(g->builder, result, "");
+ return result;
}
}
@@ -3038,7 +3093,7 @@ static LLVMValueRef gen_float_un_op(CodeGen *g, LLVMValueRef operand, ZigType *o
return gen_soft_float_un_op(g, operand, operand_type, op);
}
LLVMValueRef float_op_fn = get_float_fn(g, operand_type, ZigLLVMFnIdFloatOp, op);
- return LLVMBuildCall(g->builder, float_op_fn, &operand, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(float_op_fn), float_op_fn, &operand, 1, "");
}
enum DivKind {
@@ -3404,7 +3459,7 @@ static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref,
}
LLVMValueRef params[1] = {value_ref};
- return LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
}
static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) {
@@ -3440,7 +3495,7 @@ static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref,
}
LLVMValueRef params[1] = {value_ref};
- LLVMValueRef result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ LLVMValueRef result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
if ((wider_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) {
result = LLVMBuildBitCast(g->builder, result, wider_type->llvm_type, "");
@@ -3553,12 +3608,12 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL
LLVMValueRef result;
if (vector_len == 0) {
LLVMValueRef params[2] = {op1_value, op2_value};
- result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
result = add_icmp(g, result, res_icmp);
} else {
ZigType *alloca_ty = operand_type;
if (res_icmp != NONE) alloca_ty = get_vector_type(g, vector_len, g->builtin_types.entry_bool);
- result = build_alloca(g, alloca_ty, "", 0);
+ result = LLVMGetUndef(alloca_ty->llvm_type);
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
@@ -3567,13 +3622,10 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL
LLVMBuildExtractElement(g->builder, op1_value, index_value, ""),
LLVMBuildExtractElement(g->builder, op2_value, index_value, ""),
};
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, param_count, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, param_count, "");
call_result = add_icmp(g, call_result, res_icmp);
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
-
- result = LLVMBuildLoad(g->builder, result, "");
}
// Some operations are implemented as compound ops and require us to perform some
@@ -3703,7 +3755,9 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
}
// TODO runtime safety
- return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, scalar_type->data.pointer.child_type);
+ return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, op1_value,
+ &subscript_value, 1, "");
} else if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
return float_op[add_sub_mul](g->builder, op1_value, op2_value, "");
@@ -4044,20 +4098,22 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, Stage1Air *execu
assert(array_type->id == ZigTypeIdArray);
if (type_has_bits(g, actual_type)) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type),
+ result_loc, ptr_index, "");
LLVMValueRef indices[] = {
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
};
LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
- LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
+ LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ get_llvm_type(g, array_type), expr_val, indices, 2, "");
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
} else if (ir_want_runtime_safety(g, &instruction->base) && ptr_index != SIZE_MAX) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, ptr_index, "");
gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr);
}
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, len_index, "");
LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
array_type->data.array.len, false);
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
@@ -4107,10 +4163,11 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable,
return LLVMBuildBitCast(g->builder, value, wanted_type_ref, "");
} else if (actual_is_ptr) {
// A scalar is wanted but we got a pointer
- LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0);
- LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, "");
+ 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, bitcasted_ptr, 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);
@@ -4298,32 +4355,26 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) {
uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0;
- uint16_t num_bits = operand_type->data.floating.bit_count;
+ uint16_t num_bits = operand_type->id == ZigTypeIdVector ?
+ operand_type->data.vector.elem_type->data.floating.bit_count :
+ operand_type->data.floating.bit_count;
ZigType *iX_type = get_int_type(g, true, num_bits);
- LLVMValueRef sign_mask = LLVMConstInt(iX_type->llvm_type, 1, false);
- sign_mask = LLVMConstShl(sign_mask, LLVMConstInt(iX_type->llvm_type, num_bits - 1, false));
+ LLVMValueRef sign_mask = LLVMConstShl(
+ LLVMConstInt(iX_type->llvm_type, 1, false),
+ LLVMConstInt(iX_type->llvm_type, num_bits - 1, false));
- if (vector_len == 0) {
- LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_type->llvm_type, "");
- LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask, "");
+ LLVMValueRef sign_mask_splat = (vector_len == 0) ? sign_mask :
+ LLVMBuildVectorSplat(g->builder, vector_len, sign_mask, "");
- return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, "");
- } else {
- LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
- ZigType *iX_vector_type = get_vector_type(g, vector_len, iX_type);
+ LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand,
+ (vector_len == 0) ?
+ iX_type->llvm_type :
+ get_vector_type(g, vector_len, iX_type)->llvm_type,
+ "");
- LLVMValueRef result = build_alloca(g, iX_vector_type, "", 0);
- LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_vector_type->llvm_type, "");
- for (uint32_t i = 0; i < vector_len; i++) {
- LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
- LLVMValueRef elem = LLVMBuildExtractElement(g->builder, bitcasted_operand, index_value, "");
- LLVMValueRef result_elem = LLVMBuildXor(g->builder, elem, sign_mask, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- result_elem, index_value, "");
- }
- return LLVMBuildBitCast(g->builder, LLVMBuildLoad(g->builder, result, ""), operand_type->llvm_type, "");
- }
+ LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask_splat, "");
+ return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, "");
}
static LLVMValueRef gen_negation(CodeGen *g, Stage1AirInst *inst, Stage1AirInst *operand, bool wrapping) {
@@ -4398,7 +4449,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 = LLVMBuildLoad(g->builder, 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, "");
}
@@ -4410,10 +4463,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;
@@ -4524,7 +4578,8 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
zero,
LLVMConstInt(usize_type_ref, i, false),
};
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGetAllocatedType(array_ptr), array_ptr, indexes, 2, "");
LLVMBuildStore(g->builder, array_elements[i], elem_ptr);
}
@@ -4545,7 +4600,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default
LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(asm_template), buf_len(asm_template),
buf_ptr(asm_constraints), buf_len(asm_constraints), asm_has_side_effects, asm_is_alignstack,
LLVMInlineAsmDialectATT, false);
- return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, "");
+ return LLVMBuildCall2(g->builder, function_type, asm_fn, param_values, input_and_output_count, "");
}
}
zig_unreachable();
@@ -4719,10 +4774,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
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 = LLVMBuildInBoundsGEP(g->builder, u8_array_ptr, indices, 1, "");
+ LLVMValueRef indices[] = { byte_offset };
+ LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(),
+ u8_array_ptr, indices, 1, "");
return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), "");
}
}
@@ -4730,14 +4784,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
subscript_value
};
- return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ return LLVMBuildInBoundsGEP2(g->builder, get_llvm_type(g, array_type), array_ptr,
+ indices, 2, "");
} else if (array_type->id == ZigTypeIdPointer) {
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- LLVMValueRef indices[] = {
- subscript_value
- };
- return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, "");
+ LLVMValueRef indices[] = { subscript_value };
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type);
+ return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, indices, 1, "");
} else if (array_type->id == ZigTypeIdStruct) {
LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
assert(array_type->data.structure.special == StructSpecialSlice);
@@ -4752,22 +4806,26 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
}
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
if (safety_check_on) {
size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(len_index != SIZE_MAX);
- LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
- LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
+ LLVMValueRef len_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type),
+ array_ptr, (unsigned)len_index, "");
+ LLVMValueRef len = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_ptr), len_ptr,
+ 0, false, "");
LLVMIntPredicate upper_op = (ptr_type->data.pointer.sentinel != nullptr) ? LLVMIntULE : LLVMIntULT;
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, upper_op, len);
}
size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(ptr_index != SIZE_MAX);
- LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");
- LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");
- return LLVMBuildInBoundsGEP(g->builder, ptr, &subscript_value, 1, "");
+ LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type),
+ array_ptr, (unsigned)ptr_index, "");
+ 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) {
return array_ptr_ptr;
} else {
@@ -4775,12 +4833,16 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1
}
}
-static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, "");
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, "");
+static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMTypeRef new_stack_llvm_ty,
+ LLVMValueRef new_stack)
+{
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_ptr_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_len_index, "");
- LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, "");
- LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
+ LLVMValueRef ptr_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(ptr_field_ptr),
+ ptr_field_ptr, 0, false, "");
+ LLVMValueRef len_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(len_field_ptr),
+ len_field_ptr, 0, false, "");
LLVMValueRef ptr_addr = LLVMBuildPtrToInt(g->builder, ptr_value, LLVMTypeOf(len_value), "");
LLVMValueRef end_addr = LLVMBuildNUWAdd(g->builder, ptr_addr, len_value, "");
@@ -4804,7 +4866,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) {
aligned_end_addr,
};
- LLVMBuildCall(g->builder, write_register_fn_val, params, 2, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(write_register_fn_val), write_register_fn_val, params, 2, "");
}
static void render_async_spills(CodeGen *g) {
@@ -4834,7 +4896,9 @@ static void render_async_spills(CodeGen *g) {
}
calc_llvm_field_index_add(g, &arg_calc, var->var_type);
- var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, arg_calc.field_index - 1, var->name);
+ var->value_ref = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, arg_calc.field_index - 1, var->name);
if (var->decl_node) {
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
var->name, import->data.structure.root_struct->di_file,
@@ -4852,7 +4916,9 @@ static void render_async_spills(CodeGen *g) {
continue;
size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index;
- instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
+ instruction->base.llvm_value = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, gen_index,
instruction->name_hint);
}
}
@@ -4895,8 +4961,8 @@ static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) {
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 = LLVMBuildInBoundsGEP(g->builder, casted_fn_val, &negative_one, 1, "");
- LLVMValueRef load_inst = LLVMBuildLoad(g->builder, prefix_ptr, "");
+ 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
// function/usize pointer and also require all loads to be aligned.
@@ -4910,17 +4976,23 @@ static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) {
static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMValueRef addrs_field_ptr) {
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
+ LLVMTypeRef stack_trace_llvm_ty = get_llvm_type(g, get_stack_trace_type(g));
- LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, "");
+ LLVMValueRef index_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 0, "");
LLVMBuildStore(g->builder, zero, index_ptr);
- LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, "");
- LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, "");
+ LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 1, "");
+ LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_slice_ptr),
+ addrs_slice_ptr, slice_ptr_index, "");
LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) };
- LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, addrs_field_ptr, indices, 2, "");
+ LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_field_ptr), addrs_field_ptr, indices, 2, "");
LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr);
- LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, "");
+ LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addrs_slice_ptr),
+ addrs_slice_ptr, slice_len_index, "");
LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
}
@@ -4930,17 +5002,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;
@@ -4961,29 +5036,40 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *anyframe_type = nullptr;
LLVMValueRef frame_result_loc_uncasted = nullptr;
LLVMValueRef frame_result_loc;
+ LLVMTypeRef frame_struct_llvm_ty;
LLVMValueRef awaiter_init_val;
LLVMValueRef ret_ptr;
if (callee_is_async) {
if (instruction->new_stack == nullptr) {
if (instruction->modifier == CallModifierAsync) {
frame_result_loc = result_loc;
+ if (result_loc != nullptr) {
+ ir_assert(instruction->result_loc->value->type->id == ZigTypeIdPointer, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->result_loc->value->type->data.pointer.child_type);
+ } else {
+ frame_struct_llvm_ty = nullptr;
+ }
} else {
ir_assert(instruction->frame_result_loc != nullptr, &instruction->base);
frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc);
ir_assert(instruction->fn_entry != nullptr, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->fn_entry->frame_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
- LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), "");
+ LLVMPointerType(frame_struct_llvm_ty, 0), "");
}
} else {
if (instruction->new_stack->value->type->id == ZigTypeIdPointer &&
instruction->new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame)
{
frame_result_loc = ir_llvm_value(g, instruction->new_stack);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->new_stack->value->type->data.pointer.child_type);
} else {
LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack);
+ LLVMTypeRef frame_slice_llvm_ty = get_llvm_type(g, instruction->new_stack->value->type);
if (ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef given_len_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_len_index, "");
- LLVMValueRef given_frame_len = LLVMBuildLoad(g->builder, given_len_ptr, "");
+ LLVMValueRef given_len_ptr = LLVMBuildStructGEP2(g->builder,
+ frame_slice_llvm_ty, frame_slice_ptr, slice_len_index, "");
+ LLVMValueRef given_frame_len = LLVMBuildLoad2(g->builder, usize_type_ref, given_len_ptr, "");
LLVMValueRef actual_frame_len = gen_frame_size(g, fn_val);
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "FrameSizeCheckFail");
@@ -4998,11 +5084,14 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
need_frame_ptr_ptr_spill = true;
- LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
- LLVMValueRef frame_ptr = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
+ LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_slice_llvm_ty,
+ frame_slice_ptr, slice_ptr_index, "");
+ LLVMValueRef frame_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(frame_ptr_ptr), frame_ptr_ptr, "");
if (instruction->fn_entry == nullptr) {
anyframe_type = get_any_frame_type(g, src_return_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, get_llvm_type(g, anyframe_type), "");
+ frame_struct_llvm_ty = anyframe_type->data.any_frame.struct_llvm_ty;
} else {
ZigType *frame_type = get_fn_frame_type(g, instruction->fn_entry);
if ((err = type_resolve(g, frame_type, ResolveStatusLLVMFull)))
@@ -5010,6 +5099,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *ptr_frame_type = get_pointer_to_type(g, frame_type, false);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr,
get_llvm_type(g, ptr_frame_type), "");
+ frame_struct_llvm_ty = get_llvm_type(g, frame_type);
}
}
}
@@ -5019,7 +5109,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (ret_has_bits) {
// Use the result location which is inside the frame if this is an async call.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
}
} else {
awaiter_init_val = zero;
@@ -5030,7 +5121,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ret_ptr = result_loc;
} else {
// no result location provided to @asyncCall - use the one inside the frame.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
}
}
}
@@ -5050,20 +5142,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (ret_has_bits) {
if (result_loc == nullptr) {
// return type is a scalar, but we still need a pointer to it. Use the async fn frame.
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, "");
} else {
// Use the call instruction's result location.
ret_ptr = result_loc;
}
// Store a zero in the awaiter's result ptr to indicate we do not need a copy made.
- LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 1, "");
- LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr)));
+ LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 1, "");
+ LLVMValueRef zero_ptr = LLVMConstNull(ZigLLVMGetGEPResultElementType(awaiter_ret_ptr));
LLVMBuildStore(g->builder, zero_ptr, awaiter_ret_ptr);
}
if (prefix_arg_err_ret_stack) {
- LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
frame_index_trace_arg(g, src_return_type) + 1, "");
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope,
@@ -5074,19 +5166,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
assert(frame_result_loc != nullptr);
- LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_fn_ptr_index, "");
+ LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_fn_ptr_index, "");
LLVMValueRef bitcasted_fn_val = LLVMBuildBitCast(g->builder, fn_val,
- LLVMGetElementType(LLVMTypeOf(fn_ptr_ptr)), "");
+ LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), "");
LLVMBuildStore(g->builder, bitcasted_fn_val, fn_ptr_ptr);
- LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_resume_index, "");
+ LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_resume_index, "");
LLVMBuildStore(g->builder, zero, resume_index_ptr);
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, "");
LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr);
if (ret_has_bits) {
- LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, "");
+ LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, "");
LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr);
}
} else if (instruction->modifier == CallModifierAsync) {
@@ -5095,14 +5187,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
zig_panic("TODO @asyncCall of non-async function");
}
frame_result_loc = result_loc;
+ if (result_loc != nullptr) {
+ ir_assert(instruction->result_loc->value->type->id == ZigTypeIdPointer, &instruction->base);
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->result_loc->value->type->data.pointer.child_type);
+ } else {
+ frame_struct_llvm_ty = nullptr;
+ }
awaiter_init_val = LLVMConstAllOnes(usize_type_ref);
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, "");
LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr);
if (ret_has_bits) {
- ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
- LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, "");
+ ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, "");
+ LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, "");
LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr);
if (first_arg_ret) {
@@ -5113,11 +5211,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
// Then we have to wire up the StackTrace pointers.
// Await is responsible for merging error return traces.
uint32_t trace_field_index_start = frame_index_trace_arg(g, src_return_type);
- LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start, "");
- LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start + 2, "");
- LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
+ LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc,
trace_field_index_start + 3, "");
LLVMBuildStore(g->builder, trace_field_ptr, callee_trace_ptr_ptr);
@@ -5178,6 +5276,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
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
@@ -5189,8 +5288,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
size_t field_count = arg_calc.field_index;
LLVMTypeRef *field_types = heap::c_allocator.allocate_nonzero<LLVMTypeRef>(field_count);
- LLVMGetStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc)), field_types);
- assert(LLVMCountStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc))) == arg_calc_start.field_index);
+ LLVMGetStructElementTypes(frame_struct_llvm_ty, field_types);
+ assert(LLVMCountStructElementTypes(frame_struct_llvm_ty) == arg_calc_start.field_index);
arg_calc = arg_calc_start;
for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
@@ -5211,32 +5310,34 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
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 = LLVMBuildStructGEP(g->builder, casted_frame, 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));
}
gen_param_types.deinit();
if (instruction->modifier == CallModifierAsync) {
- gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
if (instruction->new_stack != nullptr) {
return LLVMBuildBitCast(g->builder, frame_result_loc,
get_llvm_type(g, instruction->base.value->type), "");
}
return nullptr;
} else if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
- gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
if (ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc,
- frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_awaiter_index, "");
LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref);
LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr,
all_ones, LLVMAtomicOrderingRelease);
@@ -5255,14 +5356,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
ZigType *result_type = instruction->base.value->type;
ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true);
- return gen_await_early_return(g, &instruction->base, frame_result_loc,
+ return gen_await_early_return(g, &instruction->base,
+ frame_struct_llvm_ty, frame_result_loc,
result_type, ptr_result_type, result_loc, true);
} else {
ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true);
LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume");
- LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
+ LLVMValueRef call_inst = gen_resume(g, fn_llvm_ty, fn_val, frame_result_loc, ResumeIdCall);
set_tail_call_if_appropriate(g, call_inst);
LLVMBuildRetVoid(g->builder);
@@ -5284,44 +5386,52 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI
if (need_frame_ptr_ptr_spill) {
LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack);
- LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
- frame_result_loc_uncasted = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
+ LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, instruction->new_stack->value->type),
+ frame_slice_ptr, slice_ptr_index, "");
+ frame_result_loc_uncasted = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(frame_ptr_ptr), frame_ptr_ptr, "");
}
if (frame_result_loc_uncasted != nullptr) {
if (instruction->fn_entry != nullptr) {
+ frame_struct_llvm_ty = get_llvm_type(g, instruction->fn_entry->frame_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
- LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), "");
+ LLVMPointerType(frame_struct_llvm_ty, 0), "");
} else {
frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted,
get_llvm_type(g, anyframe_type), "");
+ frame_struct_llvm_ty = anyframe_type->data.any_frame.struct_llvm_ty;
}
}
- LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
- return LLVMBuildLoad(g->builder, result_ptr, "");
+ LLVMValueRef result_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty,
+ frame_result_loc, frame_ret_start + 2, "");
+ return LLVMBuildLoad2(g->builder, get_llvm_type(g, src_return_type), result_ptr, "");
}
} else {
gen_param_types.deinit();
}
if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) {
- result = ZigLLVMBuildCall(g->builder, 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");
} else {
- LLVMValueRef new_stack_addr = get_new_stack_addr(g, ir_llvm_value(g, instruction->new_stack));
+ LLVMValueRef new_stack_addr = get_new_stack_addr(g,
+ get_llvm_type(g, instruction->new_stack->value->type),
+ ir_llvm_value(g, instruction->new_stack));
LLVMValueRef old_stack_ref;
if (src_return_type->id != ZigTypeIdUnreachable) {
LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g);
- old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, "");
+ 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, 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);
- LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(stackrestore_fn_val), stackrestore_fn_val, &old_stack_ref, 1, "");
}
}
@@ -5387,7 +5497,8 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable
codegen_report_errors_and_exit(g);
ir_assert(field->gen_index != SIZE_MAX, &instruction->base);
- LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
+ LLVMValueRef field_ptr_val = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, struct_type), struct_ptr, (unsigned)field->gen_index, "");
ZigType *res_type = instruction->base.value->type;
ir_assert(res_type->id == ZigTypeIdPointer, &instruction->base);
if (res_type->data.pointer.host_int_bytes != 0) {
@@ -5432,8 +5543,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMPointerType(tag_type_ref, 0), "");
} else {
assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
- tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
- union_type->data.unionation.gen_tag_index, "");
+ tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
}
LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref,
@@ -5448,19 +5560,25 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);
if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 0, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type), union_ptr, 0, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
return bitcasted_union_field_ptr;
}
if (instruction->initializing) {
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
&field->enum_field->value);
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
} else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
- LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_tag_index, "");
+ LLVMValueRef tag_value = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(tag_field_ptr),
+ tag_field_ptr, 0, false, "");
LLVMValueRef expected_tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
@@ -5476,8 +5594,8 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
- union_type->data.unionation.gen_union_index, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type),
+ union_ptr, union_type->data.unionation.gen_union_index, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
return bitcasted_union_field_ptr;
}
@@ -5555,7 +5673,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
size_t param_index = 0;
LLVMTypeRef *param_types = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count);
LLVMValueRef *param_values = heap::c_allocator.allocate<LLVMValueRef>(input_and_output_count);
- bool *param_needs_attr = heap::c_allocator.allocate<bool>(input_and_output_count);
+ LLVMTypeRef *param_needs_attr = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count);
for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) {
AsmOutput *asm_output = asm_expr->output_list.at(i);
bool is_return = (asm_output->return_type != nullptr);
@@ -5571,7 +5689,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1);
} else {
buf_appendf(&constraint_buf, "=*%s", buf_ptr(asm_output->constraint) + 1);
- param_needs_attr[param_index] = true;
+ ZigVar *variable = instruction->output_vars[i];
+ param_needs_attr[param_index] = get_llvm_type(g, variable->var_type);
}
if (total_index + 1 < total_constraint_count) {
buf_append_char(&constraint_buf, ',');
@@ -5597,6 +5716,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
ZigType *const type = ir_input->value->type;
LLVMTypeRef type_ref = get_llvm_type(g, type);
LLVMValueRef value_ref = ir_llvm_value(g, ir_input);
+ LLVMTypeRef elem_type_ref = nullptr;
// Handle integers of non pot bitsize by widening them.
if (type->id == ZigTypeIdInt) {
const size_t bitsize = type->data.integral.bit_count;
@@ -5608,6 +5728,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
value_ref = gen_widen_or_shorten(g, false, type, wider_type, value_ref);
}
} else if (handle_is_ptr(g, type)) {
+ elem_type_ref = type_ref;
ZigType *gen_type = get_pointer_to_type(g, type, true);
type_ref = get_llvm_type(g, gen_type);
}
@@ -5615,7 +5736,10 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
param_types[param_index] = type_ref;
param_values[param_index] = value_ref;
// In the case of indirect inputs, LLVM requires the callsite to have an elementtype(<ty>) attribute.
- param_needs_attr[param_index] = buf_ptr(asm_input->constraint)[0] == '*';
+ if (buf_ptr(asm_input->constraint)[0] == '*') {
+ 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) {
Buf *clobber_buf = asm_expr->clobber_list.at(i);
@@ -5660,11 +5784,12 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A
LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template),
buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT, false);
- LLVMValueRef built_call = LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, "");
+ LLVMValueRef built_call = LLVMBuildCall2(g->builder, function_type,
+ asm_fn, param_values, (unsigned)input_and_output_count, "");
for (size_t i = 0; i < input_and_output_count; i += 1) {
- if (param_needs_attr[i]) {
- LLVMTypeRef elem_ty = LLVMGetElementType(param_types[i]);
+ if (param_needs_attr[i] != nullptr) {
+ LLVMTypeRef elem_ty = param_needs_attr[i];
ZigLLVMSetCallElemTypeAttr(built_call, i, elem_ty);
}
}
@@ -5689,8 +5814,9 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
if (is_scalar)
return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
- LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
- return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
+ LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), maybe_handle, maybe_null_index, "");
+ return gen_load_untyped(g, ZigLLVMGetGEPResultElementType(maybe_field_ptr), maybe_field_ptr, 0, false, "");
}
static LLVMValueRef ir_render_test_non_null(CodeGen *g, Stage1Air *executable,
@@ -5736,12 +5862,13 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, Stage1Air *executa
} else {
LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type);
if (instruction->initializing) {
- LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref,
- maybe_null_index, "");
+ LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), optional_struct_ref, maybe_null_index, "");
LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false);
}
- return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, "");
+ return LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, maybe_type), optional_struct_ref, maybe_child_index, "");
}
}
}
@@ -5818,7 +5945,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, Stage1Air *executable, Stage1AirIn
operand,
LLVMConstNull(LLVMInt1Type()),
};
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5830,7 +5957,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, Stage1Air *executable, Stage1AirIn
operand,
LLVMConstNull(LLVMInt1Type()),
};
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5887,7 +6014,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, Stage1Air *executable, Stage
ZigType *int_type = instruction->op->value->type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
LLVMValueRef operand = ir_llvm_value(g, instruction->op);
- LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
+ LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &operand, 1, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
}
@@ -5978,7 +6105,9 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
err_val,
};
- return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, "");
+ return LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGlobalGetValueType(g->err_name_table),
+ g->err_name_table, indices, 2, "");
}
static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
@@ -6050,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[] = {
- LLVMConstGEP(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);
@@ -6099,7 +6228,8 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, Stage1Air *executable,
LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type);
LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
- return ZigLLVMBuildCall(g->builder, enum_name_function, &enum_tag_value, 1,
+ return ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(enum_name_function), enum_name_function,
+ &enum_tag_value, 1,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
@@ -6166,8 +6296,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, Stag
align_bytes = get_ptr_align(g, slice_ptr_type);
size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, "");
- ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, "");
+ LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder,
+ 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 {
zig_unreachable();
}
@@ -6319,12 +6451,16 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, Stage1Air *executable, Stage1A
if (actual_abi_type != nullptr) {
payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), "");
}
- LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
+ LLVMTypeRef result_loc_struct_llvm_ty = get_llvm_type(g,
+ instruction->result_loc->value->type->data.pointer.child_type);
+ LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder,
+ result_loc_struct_llvm_ty, result_loc, maybe_child_index, "");
gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");
- LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
+ LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_loc_struct_llvm_ty, result_loc,
+ maybe_null_index, "");
gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
return result_loc;
}
@@ -6469,7 +6605,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, Stage1Air *executable, Stage1Ai
static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, Stage1Air *executable, Stage1AirInstWasmMemorySize *instruction) {
// TODO adjust for wasm64
LLVMValueRef param = ir_llvm_value(g, instruction->index);
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_wasm_memory_size(g)), gen_wasm_memory_size(g), &param, 1, "");
return val;
}
@@ -6479,7 +6615,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, Stage1Air *executable
ir_llvm_value(g, instruction->index),
ir_llvm_value(g, instruction->delta),
};
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_wasm_memory_grow(g)), gen_wasm_memory_grow(g), params, 2, "");
return val;
}
@@ -6525,7 +6661,7 @@ static LLVMValueRef ir_render_prefetch(CodeGen *g, Stage1Air *executable, Stage1
LLVMConstInt(LLVMInt32Type(), instruction->locality, false),
LLVMConstInt(LLVMInt32Type(), instruction->cache, false),
};
- LLVMValueRef val = LLVMBuildCall(g->builder, gen_prefetch(g), params, 4, "");
+ LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(gen_prefetch(g)), gen_prefetch(g), params, 4, "");
return val;
}
@@ -6591,12 +6727,14 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (value_has_bits) {
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
if (want_runtime_safety && sentinel != nullptr) {
LLVMValueRef indices[] = {
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
end_val,
};
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ array_llvm_ty, array_ptr, indices, 2, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
@@ -6604,7 +6742,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
start_val,
};
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, array_ptr, indices, 2, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
@@ -6623,27 +6761,30 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (value_has_bits) {
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type);
if (want_runtime_safety && sentinel != nullptr) {
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &end_val, 1, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty,
+ array_ptr, &end_val, 1, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr,
+ &start_val, 1, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
} else if (array_type->id == ZigTypeIdStruct) {
assert(array_type->data.structure.special == StructSpecialSlice);
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind);
- assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
const size_t gen_len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
assert(gen_len_index != SIZE_MAX);
LLVMValueRef prev_end = nullptr;
if (!instruction->end || want_runtime_safety) {
- LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_len_index, "");
- prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
+ LLVMValueRef src_len_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, array_type), array_ptr, gen_len_index, "");
+ prev_end = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(src_len_ptr), src_len_ptr, 0, false, "");
}
LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
@@ -6682,18 +6823,22 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
codegen_report_errors_and_exit(g);
if (ptr_has_bits) {
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_field_type->data.pointer.child_type);
const size_t gen_ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
assert(gen_ptr_index != SIZE_MAX);
- LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_ptr_index, "");
- LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
+ LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, array_type), array_ptr, gen_ptr_index, "");
+ LLVMValueRef src_ptr = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(src_ptr_ptr),
+ src_ptr_ptr, 0, false, "");
if (sentinel != nullptr) {
- LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &end_val, 1, "");
+ LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty,
+ src_ptr, &end_val, 1, "");
add_sentinel_check(g, sentinel_elem_ptr, sentinel);
}
- slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, "");
+ slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, src_ptr, &start_val, 1, "");
}
len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, "");
@@ -6735,7 +6880,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
// The slice may not have a pointer at all if it points to a zero-sized type
const size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index;
if (gen_ptr_index != SIZE_MAX) {
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, result_type), tmp_struct_ptr, gen_ptr_index, "");
if (slice_start_ptr != nullptr) {
gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
} else if (want_runtime_safety) {
@@ -6748,7 +6894,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air
const size_t gen_len_index = result_type->data.structure.fields[slice_len_index]->gen_index;
assert(gen_len_index != SIZE_MAX);
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, result_type), tmp_struct_ptr, gen_len_index, "");
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
@@ -6767,7 +6914,7 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {
static LLVMValueRef ir_render_breakpoint(CodeGen *g, Stage1Air *executable, Stage1AirInstBreakpoint *instruction) {
- LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
+ LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_trap_fn_val(g)), get_trap_fn_val(g), nullptr, 0, "");
return nullptr;
}
@@ -6781,7 +6928,7 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
}
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
- LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, "");
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
@@ -6793,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;
@@ -6803,7 +6950,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, Stage1Air *executable,
Stage1AirInstFrameAddress *instruction)
{
LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
- LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, "");
+ LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(get_frame_address_fn_val(g)), get_frame_address_fn_val(g), &zero, 1, "");
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
}
@@ -6866,7 +7013,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, Stage1Air *executable, Sta
op2,
};
- LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
gen_store(g, result, ptr_result, instruction->result_ptr->value->type);
@@ -6881,8 +7028,9 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, Stage1Air *executable, Stage1
LLVMValueRef err_val;
if (type_has_bits(g, payload_type)) {
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
- err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, err_union_type), err_union_handle, err_union_err_index, "");
+ err_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(err_val_ptr), err_val_ptr, 0, false, "");
} else {
err_val = err_union_handle;
}
@@ -6907,7 +7055,8 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, Stage1Air *executable,
} else {
// TODO assign undef to the payload
LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
- return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
+ return LLVMBuildStructGEP2(g->builder, get_llvm_type(g, err_union_type), err_union_handle,
+ err_union_err_index, "");
}
}
@@ -6946,11 +7095,14 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab
return err_union_handle;
}
+ LLVMTypeRef err_union_llvm_ty = get_llvm_type(g, err_union_type);
+
if (want_safety) {
LLVMValueRef err_val;
if (type_has_bits(g, payload_type)) {
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
- err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty,
+ err_union_handle, err_union_err_index, "");
+ err_val = gen_load_untyped(g, ZigLLVMGetGEPResultElementType(err_val_ptr), err_val_ptr, 0, false, "");
} else {
err_val = err_union_handle;
}
@@ -6967,11 +7119,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab
if (type_has_bits(g, payload_type)) {
if (instruction->initializing) {
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty,
+ err_union_handle, err_union_err_index, "");
LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
}
- return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
+ return LLVMBuildStructGEP2(g->builder, err_union_llvm_ty, err_union_handle,
+ err_union_payload_index, "");
} else {
if (instruction->initializing) {
gen_store_untyped(g, zero, err_union_ptr, 0, false);
@@ -7006,11 +7160,14 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, Stage1Air *executable, S
}
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
+ LLVMTypeRef result_llvm_struct_ty = get_llvm_type(g, wanted_type);
- LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
+ LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc,
+ maybe_child_index, "");
// child_type and instruction->value->value->type may differ by constness
gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
- LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
+ LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc,
+ maybe_null_index, "");
gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);
return result_loc;
@@ -7028,7 +7185,8 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, Stage1Air *executable, S
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, wanted_type),
+ result_loc, err_union_err_index, "");
gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
// TODO store undef to the payload
@@ -7057,11 +7215,14 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, Stage1Air *executable
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
+ LLVMTypeRef result_struct_llvm_ty = get_llvm_type(g, wanted_type);
- LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
+ LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc,
+ err_union_err_index, "");
gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
- LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
+ LLVMValueRef payload_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc,
+ err_union_payload_index, "");
gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
return result_loc;
@@ -7079,7 +7240,8 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, Stage1Air *executable, Stage
return union_val;
assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val,
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, union_type), union_val,
union_type->data.unionation.gen_tag_index, "");
ZigType *ptr_type = get_pointer_to_type(g, tag_type, false);
return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
@@ -7154,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), "");
}
@@ -7221,14 +7384,12 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St
LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
- LLVMValueRef result;
if (vector_len == 0) {
LLVMValueRef params[3] = { op1, op2, op3 };
- result = LLVMBuildCall(g->builder, func_ref, params, 3, "");
- } else {
- result = build_alloca(g, instruction->op1->value->type, "", 0);
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, 3, "");
}
+ LLVMValueRef result = LLVMGetUndef(get_llvm_type(g, instruction->op1->value->type));
LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type;
for (uint32_t i = 0; i < vector_len; i++) {
LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false);
@@ -7238,12 +7399,8 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St
LLVMBuildExtractElement(g->builder, op2, index_value, ""),
LLVMBuildExtractElement(g->builder, op3, index_value, ""),
};
- LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, 3, "");
- LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""),
- call_result, index_value, "");
- }
- if (vector_len != 0) {
- result = LLVMBuildLoad(g->builder, result, "");
+ LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(func_ref), func_ref, params, 3, "");
+ result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, "");
}
return result;
}
@@ -7262,7 +7419,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, Stage1Air *executable, Stage1A
instruction->base.value->type->id == ZigTypeIdVector);
LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFMA, BuiltinFnIdMulAdd);
LLVMValueRef args[3] = { op1, op2, op3 };
- return LLVMBuildCall(g->builder, fn_val, args, 3, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, args, 3, "");
}
static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1AirInstBswap *instruction) {
@@ -7273,7 +7430,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air
assert(int_type->id == ZigTypeIdInt);
if (int_type->data.integral.bit_count % 16 == 0) {
LLVMValueRef fn_val = get_int_builtin_fn(g, expr_type, BuiltinFnIdBswap);
- return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &op, 1, "");
}
// Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate
ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed,
@@ -7292,7 +7449,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), "");
// 00aabbcc
LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap);
- LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, "");
+ LLVMValueRef swapped = LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &extended, 1, "");
// ccbbaa00
LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, shift_amt, "");
// 00ccbbaa
@@ -7328,7 +7485,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, Stage1Air *executable, Sta
ZigType *int_type = instruction->base.value->type;
assert(int_type->id == ZigTypeIdInt);
LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value->type, BuiltinFnIdBitReverse);
- return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
+ return LLVMBuildCall2(g->builder, LLVMGlobalGetValueType(fn_val), fn_val, &op, 1, "");
}
static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
@@ -7353,11 +7510,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMTypeRef u32_type_ref = LLVMInt32Type();
LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false);
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
for (uintptr_t i = 0; i < instruction->vector->value->type->data.vector.len; i++) {
LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false);
LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false);
LLVMValueRef indexes[] = { zero, index_usize };
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, result_loc, indexes, 2, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, result_loc, indexes, 2, "");
LLVMValueRef elem = LLVMBuildExtractElement(g->builder, vector, index_u32, "");
LLVMBuildStore(g->builder, elem, elem_ptr);
}
@@ -7376,13 +7534,13 @@ 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;
+ ZigType *array_type = instruction->array->value->type;
+ ir_assert(array_type->id == ZigTypeIdArray, &instruction->base);
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, casted_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.
@@ -7390,12 +7548,15 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable,
LLVMTypeRef u32_type_ref = LLVMInt32Type();
LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false);
LLVMValueRef vector = LLVMGetUndef(vector_type_ref);
+ LLVMTypeRef array_llvm_ty = get_llvm_type(g, array_type);
+ LLVMTypeRef elem_llvm_ty = get_llvm_type(g, elem_type);
for (uintptr_t i = 0; i < instruction->base.value->type->data.vector.len; i++) {
LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false);
LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false);
LLVMValueRef indexes[] = { zero, index_usize };
- LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, "");
- LLVMValueRef elem = LLVMBuildLoad(g->builder, elem_ptr, "");
+ LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, array_llvm_ty, array_ptr,
+ indexes, 2, "");
+ LLVMValueRef elem = LLVMBuildLoad2(g->builder, elem_llvm_ty, elem_ptr, "");
vector = LLVMBuildInsertElement(g->builder, vector, elem, index_u32, "");
}
return vector;
@@ -7461,14 +7622,16 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable,
}
static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr,
- LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
- LLVMValueRef result_loc, bool non_async)
+ LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr,
+ ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async)
{
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef their_result_ptr = nullptr;
if (type_has_bits(g, result_type) && (non_async || result_loc != nullptr)) {
- LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, "");
- their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, "");
+ LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ target_frame_struct_llvm_ty, target_frame_ptr, frame_ret_start, "");
+ their_result_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(their_result_ptr_ptr), their_result_ptr_ptr, "");
if (result_loc != nullptr) {
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, result_loc, ptr_u8, "");
@@ -7482,13 +7645,16 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_ins
}
}
if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) {
- LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
+ LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ target_frame_struct_llvm_ty, target_frame_ptr,
frame_index_trace_arg(g, result_type), "");
- LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, "");
+ LLVMValueRef src_trace_ptr = LLVMBuildLoad2(g->builder,
+ ZigLLVMGetGEPResultElementType(their_trace_ptr_ptr), their_trace_ptr_ptr, "");
bool is_llvm_alloca;
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->scope, &is_llvm_alloca);
LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
- ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
+ ZigLLVMBuildCall(g->builder, LLVMGlobalGetValueType(get_merge_err_ret_traces_fn_val(g)),
+ get_merge_err_ret_traces_fn_val(g), args, 2,
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
}
if (non_async && type_has_bits(g, result_type)) {
@@ -7503,6 +7669,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
+ ir_assert(instruction->frame->value->type->id == ZigTypeIdAnyFrame, &instruction->base);
+ LLVMTypeRef target_frame_llvm_ty = instruction->frame->value->type->data.any_frame.struct_llvm_ty;
ZigType *result_type = instruction->base.value->type;
ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true);
@@ -7512,8 +7680,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
if (instruction->is_nosuspend ||
(instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
{
- return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
- ptr_result_type, result_loc, true);
+ return gen_await_early_return(g, &instruction->base, target_frame_llvm_ty,
+ target_frame_ptr, result_type, ptr_result_type, result_loc, true);
}
// Prepare to be suspended
@@ -7525,10 +7693,11 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
// supply the awaiter return pointer
if (type_has_bits(g, result_type)) {
- LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, "");
+ LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_ret_start + 1, "");
if (result_loc == nullptr) {
// no copy needed
- LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr_ptr))),
+ LLVMBuildStore(g->builder, LLVMConstNull(ZigLLVMGetGEPResultElementType(awaiter_ret_ptr_ptr)),
awaiter_ret_ptr_ptr);
} else {
LLVMBuildStore(g->builder, result_loc, awaiter_ret_ptr_ptr);
@@ -7540,14 +7709,15 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
bool is_llvm_alloca;
LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca);
assert(my_err_ret_trace_val != nullptr);
- LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr,
- frame_index_trace_arg(g, result_type) + 1, "");
+ LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_index_trace_arg(g, result_type) + 1, "");
LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr);
}
// caller's own frame pointer
LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, "");
- LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, "");
+ LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty,
+ target_frame_ptr, frame_awaiter_index, "");
LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val,
LLVMAtomicOrderingRelease);
@@ -7572,8 +7742,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air
// Early return: The async function has already completed. We must copy the result and
// the error return trace if applicable.
LLVMPositionBuilderAtEnd(g->builder, early_return_block);
- gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, ptr_result_type,
- result_loc, false);
+ gen_await_early_return(g, &instruction->base, target_frame_llvm_ty, target_frame_ptr,
+ result_type, ptr_result_type, result_loc, false);
LLVMBuildBr(g->builder, end_bb);
LLVMPositionBuilderAtEnd(g->builder, resume_bb);
@@ -7591,7 +7761,7 @@ static LLVMValueRef ir_render_resume(CodeGen *g, Stage1Air *executable, Stage1Ai
ZigType *frame_type = instruction->frame->value->type;
assert(frame_type->id == ZigTypeIdAnyFrame);
- gen_resume(g, nullptr, frame, ResumeIdManual);
+ gen_resume(g, g->anyframe_fn_type, nullptr, frame, ResumeIdManual);
return nullptr;
}
@@ -7631,7 +7801,8 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, Stage1Air *executable, Stage
zig_unreachable();
case SpillIdRetErrCode: {
LLVMValueRef ptr = ir_llvm_value(g, g->cur_fn->err_code_spill);
- return LLVMBuildLoad(g->builder, ptr, "");
+ LLVMTypeRef llvm_ty = g->builtin_types.entry_global_error_set->llvm_type;
+ return LLVMBuildLoad2(g->builder, llvm_ty, ptr, "");
}
}
@@ -7923,43 +8094,33 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co
ConstParent *parent = &array_const_val->parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
- LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
- if (el_type == LLVMArrayTypeKind) {
- ZigType *usize = g->builtin_types.entry_usize;
- LLVMValueRef indices[] = {
- LLVMConstNull(usize->llvm_type),
- LLVMConstInt(usize->llvm_type, index, false),
- };
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
- } else if (el_type == LLVMStructTypeKind) {
- ZigType *u32 = g->builtin_types.entry_u32;
- LLVMValueRef indices[] = {
- LLVMConstNull(get_llvm_type(g, u32)),
- LLVMConstInt(get_llvm_type(g, u32), index, false),
- };
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
- } else {
- return base_ptr;
- }
+ 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(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));
- LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr,
- LLVMPointerType(get_llvm_type(g, struct_const_val->type), 0));
- return LLVMConstInBoundsGEP(casted_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) {
@@ -7971,7 +8132,7 @@ static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), err_union_err_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigValue *err_union_const_val) {
@@ -7983,7 +8144,7 @@ static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigVal
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), err_union_payload_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValue *optional_const_val) {
@@ -7995,7 +8156,7 @@ static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValu
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), maybe_child_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, 2);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, optional_const_val->type), base_ptr, indices, 2);
}
static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_const_val) {
@@ -8012,7 +8173,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_co
LLVMConstNull(get_llvm_type(g, u32)),
LLVMConstInt(get_llvm_type(g, u32), union_payload_index, false),
};
- return LLVMConstInBoundsGEP(base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1);
+ return LLVMConstInBoundsGEP2(get_llvm_type(g, union_const_val->type), base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1);
}
static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ZigValue *const_val) {
@@ -9206,28 +9367,38 @@ static void do_code_gen(CodeGen *g) {
}
}
+ LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
+
// finishing error return trace setup. we have to do this after all the allocas.
if (have_err_ret_trace_stack) {
ZigType *usize = g->builtin_types.entry_usize;
size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
- LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
+ LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false);
size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
- LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
+ LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, g->stack_trace_type),
+ g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
- LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
+ LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)ptr_field_index, "");
LLVMValueRef zero = LLVMConstNull(usize->llvm_type);
LLVMValueRef indices[] = {zero, zero};
- LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val,
- indices, 2, "");
+ LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP2(g->builder,
+ LLVMGetAllocatedType(err_ret_array_val), err_ret_array_val, indices, 2, "");
ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false);
gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type);
size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
- LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
+ LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder,
+ ZigLLVMGetGEPResultElementType(addresses_field_ptr),
+ addresses_field_ptr, (unsigned)len_field_index, "");
gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
}
@@ -9235,7 +9406,6 @@ static void do_code_gen(CodeGen *g) {
(void)get_llvm_type(g, fn_table_entry->frame_type);
g->cur_resume_block_count = 0;
- LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
if (g->need_frame_size_prefix_data) {
ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val);
@@ -9254,22 +9424,31 @@ static void do_code_gen(CodeGen *g) {
LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block);
render_async_spills(g);
- g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_awaiter_index, "");
- LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, "");
+ g->cur_async_awaiter_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_awaiter_index, "");
+ LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr, frame_resume_index, "");
g->cur_async_resume_index_ptr = resume_index_ptr;
if (type_has_bits(g, fn_type_id->return_type)) {
- LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, "");
- g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, "");
+ LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ 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,
+ 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)) {
trace_field_index_stack = frame_index_trace_stack(g, fn_table_entry);
- g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack, "");
}
- LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
+ LLVMValueRef resume_index = LLVMBuildLoad2(g->builder, usize_type_ref, resume_index_ptr, "");
LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4);
g->cur_async_switch_instr = switch_instr;
@@ -9293,15 +9472,21 @@ static void do_code_gen(CodeGen *g) {
LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr);
if (trace_field_index_stack != UINT32_MAX) {
if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) {
- LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
frame_index_trace_arg(g, fn_type_id->return_type), "");
- LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(trace_ptr_ptr)));
+ LLVMValueRef zero_ptr = LLVMConstNull(ZigLLVMGetGEPResultElementType(trace_ptr_ptr));
LLVMBuildStore(g->builder, zero_ptr, trace_ptr_ptr);
}
- LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack, "");
- LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr,
+ LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder,
+ get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)),
+ g->cur_frame_ptr,
trace_field_index_stack + 1, "");
gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr);