Commit 3f5dd08ca8
Changed files (5)
std
special
src/codegen.cpp
@@ -603,6 +603,24 @@ static LLVMValueRef get_floor_ceil_fn(CodeGen *g, TypeTableEntry *type_entry, Zi
return fn_val;
}
+static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr,
+ uint32_t alignment, bool is_volatile)
+{
+ LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr);
+ if (is_volatile) LLVMSetVolatile(instruction, true);
+ if (alignment == 0) {
+ LLVMSetAlignment(instruction, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(value)));
+ } else {
+ LLVMSetAlignment(instruction, alignment);
+ }
+ return instruction;
+}
+
+static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, TypeTableEntry *ptr_type) {
+ assert(ptr_type->id == TypeTableEntryIdPointer);
+ return gen_store_untyped(g, value, ptr, ptr_type->data.pointer.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)
{
@@ -617,6 +635,7 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alig
}
static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type, const char *name) {
+ assert(ptr_type->id == TypeTableEntryIdPointer);
return gen_load_untyped(g, ptr, ptr_type->data.pointer.alignment, ptr_type->data.pointer.is_volatile, name);
}
@@ -789,6 +808,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
for (; i < err_buf_len; i += 1) {
err_buf_vals[i] = LLVMGetUndef(LLVMInt8Type());
}
+ uint32_t u8_align_bytes = get_abi_alignment(g, g->builtin_types.entry_u8);
LLVMValueRef init_value = LLVMConstArray(LLVMInt8Type(), err_buf_vals, err_buf_len);
Buf *global_name = get_mangled_name(g, buf_create_from_str("__zig_panic_buf"), false);
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_value), buf_ptr(global_name));
@@ -796,7 +816,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
LLVMSetLinkage(global_value, LLVMInternalLinkage);
LLVMSetGlobalConstant(global_value, false);
LLVMSetUnnamedAddr(global_value, true);
- LLVMSetAlignment(global_value, get_abi_alignment(g, g->builtin_types.entry_u8));
+ LLVMSetAlignment(global_value, u8_align_bytes);
TypeTableEntry *usize = g->builtin_types.entry_usize;
LLVMValueRef full_buf_ptr_indices[] = {
@@ -851,7 +871,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
offset_buf_ptr, // dest pointer
err_name_ptr, // source pointer
err_name_len, // size bytes
- LLVMConstInt(LLVMInt32Type(), 1, false), // align bytes
+ LLVMConstInt(LLVMInt32Type(), u8_align_bytes, false), // align bytes
LLVMConstNull(LLVMInt1Type()), // is volatile
};
@@ -1089,9 +1109,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry
uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;
if (unaligned_bit_count == 0) {
- LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr);
- LLVMSetAlignment(llvm_instruction, ptr_type->data.pointer.alignment);
- LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile);
+ gen_store(g, value, ptr, ptr_type);
return nullptr;
}
@@ -1112,9 +1130,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry
LLVMValueRef shifted_value = LLVMBuildShl(g->builder, extended_value, shift_amt_val, "");
LLVMValueRef ored_value = LLVMBuildOr(g->builder, shifted_value, anded_containing_int, "");
- LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, ored_value, ptr);
- LLVMSetAlignment(llvm_instruction, ptr_type->data.pointer.alignment);
- LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile);
+ gen_store(g, ored_value, ptr, ptr_type);
return nullptr;
}
@@ -1673,7 +1689,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
wanted_type->data.structure.fields[0].type_entry->type_ref, "");
LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
(unsigned)wanted_ptr_index, "");
- LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
+ gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
@@ -1706,7 +1722,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
(unsigned)wanted_len_index, "");
- LLVMBuildStore(g->builder, new_len, dest_len_ptr);
+ gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
return cast_instruction->tmp_ptr;
@@ -1726,14 +1742,14 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
(unsigned)wanted_ptr_index, "");
LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, "");
- LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr);
+ gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index;
LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
(unsigned)wanted_len_index, "");
LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
actual_type->data.array.len / type_size(g, wanted_child_type), false);
- LLVMBuildStore(g->builder, len_val, len_ptr);
+ gen_store_untyped(g, len_val, len_ptr, 0, false);
return cast_instruction->tmp_ptr;
}
@@ -2542,7 +2558,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru
return value;
} else {
assert(instruction->tmp_ptr);
- LLVMBuildStore(g->builder, value, instruction->tmp_ptr);
+ gen_store_untyped(g, value, instruction->tmp_ptr, 0, false);
return instruction->tmp_ptr;
}
}
@@ -2828,11 +2844,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
start_val,
};
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, "");
- LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr);
+ gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
- LLVMBuildStore(g->builder, len_value, len_field_ptr);
+ gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
} else if (array_type->id == TypeTableEntryIdPointer) {
@@ -2845,11 +2861,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
- LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr);
+ gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
- LLVMBuildStore(g->builder, len_value, len_field_ptr);
+ gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
} else if (array_type->id == TypeTableEntryIdStruct) {
@@ -2888,11 +2904,11 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)ptr_index, "");
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, (unsigned)len_index, "");
- LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr);
+ gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)len_index, "");
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
- LLVMBuildStore(g->builder, len_value, len_field_ptr);
+ gen_store_untyped(g, len_value, len_field_ptr, 0, false);
return tmp_struct_ptr;
} else {
@@ -2979,7 +2995,7 @@ static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp
}
LLVMValueRef overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, op1, orig_val, "");
- LLVMBuildStore(g->builder, result, ptr_result);
+ gen_store(g, result, ptr_result, instruction->result_ptr->value.type);
return overflow_bit;
}
@@ -3017,7 +3033,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
- LLVMBuildStore(g->builder, result, ptr_result);
+ gen_store(g, result, ptr_result, instruction->result_ptr->value.type);
return overflow_bit;
}
@@ -3114,7 +3130,7 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
// 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, instruction->tmp_ptr, maybe_null_index, "");
- LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
+ gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);
return instruction->tmp_ptr;
}
@@ -3133,7 +3149,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
assert(instruction->tmp_ptr);
LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
- LLVMBuildStore(g->builder, err_val, err_tag_ptr);
+ gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
return instruction->tmp_ptr;
}
@@ -3155,7 +3171,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);
LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
- LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr);
+ gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, child_type, false), payload_val);
@@ -3190,7 +3206,7 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir
LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_tag_index, "");
- LLVMBuildStore(g->builder, tag_value, tag_field_ptr);
+ gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
TypeTableEntry *union_val_type = instruction->field->type_entry;
if (type_has_bits(union_val_type)) {
@@ -4318,7 +4334,8 @@ static void do_code_gen(CodeGen *g) {
if (!handle_is_ptr(variable->value->type)) {
clear_debug_source_node(g);
- LLVMBuildStore(g->builder, LLVMGetParam(fn, (unsigned)variable->gen_arg_index), variable->value_ref);
+ gen_store_untyped(g, LLVMGetParam(fn, (unsigned)variable->gen_arg_index), variable->value_ref,
+ variable->align_bytes, false);
}
if (variable->decl_node) {
src/ir.cpp
@@ -14175,7 +14175,15 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst
if (type_is_invalid(result_ptr->value.type))
return ira->codegen->builtin_types.entry_invalid;
- TypeTableEntry *expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false);
+ TypeTableEntry *expected_ptr_type;
+ if (result_ptr->value.type->id == TypeTableEntryIdPointer) {
+ expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type,
+ false, result_ptr->value.type->data.pointer.is_volatile,
+ result_ptr->value.type->data.pointer.alignment, 0, 0);
+ } else {
+ expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false);
+ }
+
IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type);
if (type_is_invalid(casted_result_ptr->value.type))
return ira->codegen->builtin_types.entry_invalid;
src/zig_llvm.cpp
@@ -541,17 +541,6 @@ void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder) {
reinterpret_cast<DIBuilder*>(dibuilder)->finalize();
}
-ZigLLVMInsertionPoint *ZigLLVMSaveInsertPoint(LLVMBuilderRef builder_wrapped) {
- IRBuilderBase::InsertPoint *ip = new IRBuilderBase::InsertPoint();
- *ip = unwrap(builder_wrapped)->saveIP();
- return reinterpret_cast<ZigLLVMInsertionPoint*>(ip);
-}
-
-void ZigLLVMRestoreInsertPoint(LLVMBuilderRef builder, ZigLLVMInsertionPoint *ip_wrapped) {
- IRBuilderBase::InsertPoint *ip = reinterpret_cast<IRBuilderBase::InsertPoint*>(ip_wrapped);
- unwrap(builder)->restoreIP(*ip);
-}
-
LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref)
{
src/zig_llvm.hpp
@@ -153,9 +153,6 @@ void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram);
void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder);
-ZigLLVMInsertionPoint *ZigLLVMSaveInsertPoint(LLVMBuilderRef builder);
-void ZigLLVMRestoreInsertPoint(LLVMBuilderRef builder, ZigLLVMInsertionPoint *point);
-
LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref);
LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
std/special/builtin.zig
@@ -39,6 +39,8 @@ export fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }
// and have the math stuff use the intrinsic. same as @mod and @rem
export fn floorf(x: f32) -> f32 { math.floor(x) }
export fn ceilf(x: f32) -> f32 { math.ceil(x) }
+export fn floor(x: f64) -> f64 { math.floor(x) }
+export fn ceil(x: f64) -> f64 { math.ceil(x) }
fn generic_fmod(comptime T: type, x: T, y: T) -> T {
@setDebugSafety(this, false);