| ... | @@ -1097,7 +1097,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1097,7 +1097,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1097 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); | 1097 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1098 | | 1098 | |
| 1099 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, ""); | 1099 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, ""); |
| 1100 | LLVMValueRef len_value = LLVMBuildSub(g->builder, end_val, start_val, ""); | 1100 | LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); |
| 1101 | LLVMBuildStore(g->builder, len_value, len_field_ptr); | 1101 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1102 | | 1102 | |
| 1103 | return tmp_struct_ptr; | 1103 | return tmp_struct_ptr; |
| ... | @@ -1115,7 +1115,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1115,7 +1115,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1115 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); | 1115 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1116 | | 1116 | |
| 1117 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, ""); | 1117 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, ""); |
| 1118 | LLVMValueRef len_value = LLVMBuildSub(g->builder, end_val, start_val, ""); | 1118 | LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); |
| 1119 | LLVMBuildStore(g->builder, len_value, len_field_ptr); | 1119 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1120 | | 1120 | |
| 1121 | return tmp_struct_ptr; | 1121 | return tmp_struct_ptr; |
| ... | @@ -1160,7 +1160,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1160,7 +1160,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1160 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); | 1160 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1161 | | 1161 | |
| 1162 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, len_index, ""); | 1162 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, len_index, ""); |
| 1163 | LLVMValueRef len_value = LLVMBuildSub(g->builder, end_val, start_val, ""); | 1163 | LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); |
| 1164 | LLVMBuildStore(g->builder, len_value, len_field_ptr); | 1164 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1165 | | 1165 | |
| 1166 | return tmp_struct_ptr; | 1166 | return tmp_struct_ptr; |
| ... | @@ -1287,6 +1287,28 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, | ... | @@ -1287,6 +1287,28 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, |
| 1287 | return target_ref; | 1287 | return target_ref; |
| 1288 | } | 1288 | } |
| 1289 | | 1289 | |
| | 1290 | static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddSubMul op, |
| | 1291 | LLVMValueRef val1, LLVMValueRef val2) |
| | 1292 | { |
| | 1293 | LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op); |
| | 1294 | LLVMValueRef params[] = { |
| | 1295 | val1, |
| | 1296 | val2, |
| | 1297 | }; |
| | 1298 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| | 1299 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| | 1300 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| | 1301 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail"); |
| | 1302 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk"); |
| | 1303 | LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block); |
| | 1304 | |
| | 1305 | LLVMPositionBuilderAtEnd(g->builder, fail_block); |
| | 1306 | gen_debug_safety_crash(g); |
| | 1307 | |
| | 1308 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 1309 | return result; |
| | 1310 | } |
| | 1311 | |
| 1290 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | 1312 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1291 | assert(node->type == NodeTypePrefixOpExpr); | 1313 | assert(node->type == NodeTypePrefixOpExpr); |
| 1292 | assert(node->data.prefix_op_expr.primary_expr); | 1314 | assert(node->data.prefix_op_expr.primary_expr); |
| ... | @@ -1300,12 +1322,20 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1300,12 +1322,20 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1300 | case PrefixOpNegation: | 1322 | case PrefixOpNegation: |
| 1301 | { | 1323 | { |
| 1302 | LLVMValueRef expr = gen_expr(g, expr_node); | 1324 | LLVMValueRef expr = gen_expr(g, expr_node); |
| 1303 | if (expr_type->id == TypeTableEntryIdInt) { | 1325 | set_debug_source_node(g, node); |
| 1304 | set_debug_source_node(g, node); | 1326 | if (expr_type->id == TypeTableEntryIdFloat) { |
| 1305 | return LLVMBuildNeg(g->builder, expr, ""); | | |
| 1306 | } else if (expr_type->id == TypeTableEntryIdFloat) { | | |
| 1307 | set_debug_source_node(g, node); | | |
| 1308 | return LLVMBuildFNeg(g->builder, expr, ""); | 1327 | return LLVMBuildFNeg(g->builder, expr, ""); |
| | 1328 | } else if (expr_type->id == TypeTableEntryIdInt) { |
| | 1329 | if (expr_type->data.integral.is_wrapping) { |
| | 1330 | return LLVMBuildNeg(g->builder, expr, ""); |
| | 1331 | } else if (want_debug_safety(g, expr_node)) { |
| | 1332 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr)); |
| | 1333 | return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr); |
| | 1334 | } else if (expr_type->data.integral.is_signed) { |
| | 1335 | return LLVMBuildNSWNeg(g->builder, expr, ""); |
| | 1336 | } else { |
| | 1337 | return LLVMBuildNUWNeg(g->builder, expr, ""); |
| | 1338 | } |
| 1309 | } else { | 1339 | } else { |
| 1310 | zig_unreachable(); | 1340 | zig_unreachable(); |
| 1311 | } | 1341 | } |
| ... | @@ -1431,28 +1461,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1431,28 +1461,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1431 | zig_unreachable(); | 1461 | zig_unreachable(); |
| 1432 | } | 1462 | } |
| 1433 | | 1463 | |
| 1434 | static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddSubMul op, | | |
| 1435 | LLVMValueRef val1, LLVMValueRef val2) | | |
| 1436 | { | | |
| 1437 | LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op); | | |
| 1438 | LLVMValueRef params[] = { | | |
| 1439 | val1, | | |
| 1440 | val2, | | |
| 1441 | }; | | |
| 1442 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); | | |
| 1443 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); | | |
| 1444 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); | | |
| 1445 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail"); | | |
| 1446 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk"); | | |
| 1447 | LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block); | | |
| 1448 | | | |
| 1449 | LLVMPositionBuilderAtEnd(g->builder, fail_block); | | |
| 1450 | gen_debug_safety_crash(g); | | |
| 1451 | | | |
| 1452 | LLVMPositionBuilderAtEnd(g->builder, ok_block); | | |
| 1453 | return result; | | |
| 1454 | } | | |
| 1455 | | | |
| 1456 | static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | 1464 | static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1457 | LLVMValueRef val1, LLVMValueRef val2, | 1465 | LLVMValueRef val1, LLVMValueRef val2, |
| 1458 | TypeTableEntry *op1_type, TypeTableEntry *op2_type, | 1466 | TypeTableEntry *op1_type, TypeTableEntry *op2_type, |
| ... | @@ -2727,7 +2735,7 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { | ... | @@ -2727,7 +2735,7 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 2727 | | 2735 | |
| 2728 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | 2736 | LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 2729 | set_debug_source_node(g, node); | 2737 | set_debug_source_node(g, node); |
| 2730 | LLVMValueRef new_index_val = LLVMBuildAdd(g->builder, index_val, one_const, ""); | 2738 | LLVMValueRef new_index_val = LLVMBuildNSWAdd(g->builder, index_val, one_const, ""); |
| 2731 | LLVMBuildStore(g->builder, new_index_val, index_ptr); | 2739 | LLVMBuildStore(g->builder, new_index_val, index_ptr); |
| 2732 | LLVMBuildBr(g->builder, cond_block); | 2740 | LLVMBuildBr(g->builder, cond_block); |
| 2733 | | 2741 | |