authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 16:00:12-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 16:00:12-05:00
log025051885be8c99bfccc7d3746ac138f7d5546e1
tree20cbf34b93811f6b1a3d8c409d2a6bddc2eb3ea4
parentd151c58788098778c07f764d2256955cb36a832f

fix volatile not respected for loads


2 files changed, 26 insertions(+), 20 deletions(-)

src/codegen.cpp+25-19
...@@ -415,12 +415,14 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,...@@ -415,12 +415,14 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry,
415 return *fn;415 return *fn;
416}416}
417417
418static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type) {418static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type, bool is_volatile) {
419 if (type_has_bits(type)) {419 if (type_has_bits(type)) {
420 if (handle_is_ptr(type)) {420 if (handle_is_ptr(type)) {
421 return ptr;421 return ptr;
422 } else {422 } else {
423 return LLVMBuildLoad(g->builder, ptr, "");423 LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, "");
424 LLVMSetVolatile(result, is_volatile);
425 return result;
424 }426 }
425 } else {427 } else {
426 return nullptr;428 return nullptr;
...@@ -1191,6 +1193,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1191,6 +1193,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1191 case IrUnOpInvalid:1193 case IrUnOpInvalid:
1192 case IrUnOpError:1194 case IrUnOpError:
1193 case IrUnOpMaybe:1195 case IrUnOpMaybe:
1196 case IrUnOpDereference:
1194 zig_unreachable();1197 zig_unreachable();
1195 case IrUnOpNegation:1198 case IrUnOpNegation:
1196 case IrUnOpNegationWrap:1199 case IrUnOpNegationWrap:
...@@ -1214,16 +1217,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1214,16 +1217,6 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1214 }1217 }
1215 case IrUnOpBinNot:1218 case IrUnOpBinNot:
1216 return LLVMBuildNot(g->builder, expr, "");1219 return LLVMBuildNot(g->builder, expr, "");
1217 case IrUnOpDereference:
1218 {
1219 assert(expr_type->id == TypeTableEntryIdPointer);
1220 if (!type_has_bits(expr_type)) {
1221 return nullptr;
1222 } else {
1223 TypeTableEntry *child_type = expr_type->data.pointer.child_type;
1224 return get_handle_value(g, expr, child_type);
1225 }
1226 }
1227 }1220 }
12281221
1229 zig_unreachable();1222 zig_unreachable();
...@@ -1289,8 +1282,15 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -1289,8 +1282,15 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1289}1282}
12901283
1291static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) {1284static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) {
1285 TypeTableEntry *child_type = instruction->base.value.type;
1286 if (!type_has_bits(child_type)) {
1287 return nullptr;
1288 }
1292 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);1289 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
1293 return get_handle_value(g, ptr, instruction->base.value.type);1290 TypeTableEntry *ptr_type = instruction->ptr->value.type;
1291 assert(ptr_type->id == TypeTableEntryIdPointer);
1292 bool is_volatile = ptr_type->data.pointer.is_volatile;
1293 return get_handle_value(g, ptr, child_type, is_volatile);
1294}1294}
12951295
1296static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {1296static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
...@@ -1329,8 +1329,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -1329,8 +1329,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
1329 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);1329 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
1330 TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type;1330 TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type;
1331 assert(array_ptr_type->id == TypeTableEntryIdPointer);1331 assert(array_ptr_type->id == TypeTableEntryIdPointer);
1332 bool is_volatile = array_ptr_type->data.pointer.is_volatile;
1332 TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type;1333 TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type;
1333 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type);1334 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, is_volatile);
1334 LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index);1335 LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index);
1335 assert(subscript_value);1336 assert(subscript_value);
13361337
...@@ -1607,12 +1608,13 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,...@@ -1607,12 +1608,13 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
1607{1608{
1608 TypeTableEntry *ptr_type = instruction->value->value.type;1609 TypeTableEntry *ptr_type = instruction->value->value.type;
1609 assert(ptr_type->id == TypeTableEntryIdPointer);1610 assert(ptr_type->id == TypeTableEntryIdPointer);
1611 bool is_volatile = ptr_type->data.pointer.is_volatile;
1610 TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type;1612 TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type;
1611 assert(maybe_type->id == TypeTableEntryIdMaybe);1613 assert(maybe_type->id == TypeTableEntryIdMaybe);
1612 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;1614 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
1613 bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn);1615 bool maybe_is_ptr = (child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn);
1614 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);1616 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
1615 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type);1617 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, is_volatile);
1616 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {1618 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
1617 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);1619 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
1618 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");1620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
...@@ -1627,7 +1629,7 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,...@@ -1627,7 +1629,7 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
1627 if (maybe_is_ptr) {1629 if (maybe_is_ptr) {
1628 return maybe_ptr;1630 return maybe_ptr;
1629 } else {1631 } else {
1630 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type);1632 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, is_volatile);
1631 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");1633 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");
1632 }1634 }
1633}1635}
...@@ -2066,10 +2068,12 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI...@@ -2066,10 +2068,12 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
20662068
2067static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) {2069static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) {
2068 TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);2070 TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);
2071 assert(ptr_type->id == TypeTableEntryIdPointer);
2072 bool is_volatile = ptr_type->data.pointer.is_volatile;
2069 TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);2073 TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);
2070 TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);2074 TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);
2071 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);2075 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
2072 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type);2076 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile);
20732077
2074 if (type_has_bits(child_type)) {2078 if (type_has_bits(child_type)) {
2075 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");2079 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
...@@ -2081,10 +2085,12 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab...@@ -2081,10 +2085,12 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
20812085
2082static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) {2086static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) {
2083 TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);2087 TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type);
2088 assert(ptr_type->id == TypeTableEntryIdPointer);
2089 bool is_volatile = ptr_type->data.pointer.is_volatile;
2084 TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);2090 TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type);
2085 TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);2091 TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type);
2086 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);2092 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
2087 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type);2093 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile);
20882094
2089 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {2095 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
2090 LLVMValueRef err_val;2096 LLVMValueRef err_val;
...@@ -2193,7 +2199,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI...@@ -2193,7 +2199,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI
2193 return enum_val;2199 return enum_val;
21942200
2195 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, "");2201 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, "");
2196 return get_handle_value(g, tag_field_ptr, tag_type);2202 return get_handle_value(g, tag_field_ptr, tag_type, false);
2197}2203}
21982204
2199static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, IrInstructionInitEnum *instruction) {2205static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, IrInstructionInitEnum *instruction) {
src/ir.cpp+1-1
...@@ -8367,7 +8367,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp...@@ -8367,7 +8367,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
8367 return child_type;8367 return child_type;
8368 }8368 }
83698369
8370 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, IrUnOpDereference, value);8370 ir_build_load_ptr_from(&ira->new_irb, &un_op_instruction->base, value);
8371 return child_type;8371 return child_type;
8372}8372}
83738373