Commit 3f5dd08ca8

Andrew Kelley <superjoe30@gmail.com>
2017-08-30 10:14:53
codegen: all stores specify align value
See #37
1 parent 849f653
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);