| ... | ... | @@ -1097,7 +1097,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1097 | 1097 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1098 | 1098 | |
| 1099 | 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 | 1101 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1102 | 1102 | |
| 1103 | 1103 | return tmp_struct_ptr; |
| ... | ... | @@ -1115,7 +1115,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1115 | 1115 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1116 | 1116 | |
| 1117 | 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 | 1119 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1120 | 1120 | |
| 1121 | 1121 | return tmp_struct_ptr; |
| ... | ... | @@ -1160,7 +1160,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1160 | 1160 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| 1161 | 1161 | |
| 1162 | 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 | 1164 | LLVMBuildStore(g->builder, len_value, len_field_ptr); |
| 1165 | 1165 | |
| 1166 | 1166 | return tmp_struct_ptr; |
| ... | ... | @@ -1287,6 +1287,28 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, |
| 1287 | 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 | 1312 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1291 | 1313 | assert(node->type == NodeTypePrefixOpExpr); |
| 1292 | 1314 | assert(node->data.prefix_op_expr.primary_expr); |
| ... | ... | @@ -1300,12 +1322,20 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1300 | 1322 | case PrefixOpNegation: |
| 1301 | 1323 | { |
| 1302 | 1324 | LLVMValueRef expr = gen_expr(g, expr_node); |
| 1303 | | if (expr_type->id == TypeTableEntryIdInt) { |
| 1304 | | set_debug_source_node(g, node); |
| 1305 | | return LLVMBuildNeg(g->builder, expr, ""); |
| 1306 | | } else if (expr_type->id == TypeTableEntryIdFloat) { |
| 1307 | | set_debug_source_node(g, node); |
| 1325 | set_debug_source_node(g, node); |
| 1326 | if (expr_type->id == TypeTableEntryIdFloat) { |
| 1308 | 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 | 1339 | } else { |
| 1310 | 1340 | zig_unreachable(); |
| 1311 | 1341 | } |
| ... | ... | @@ -1431,28 +1461,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1431 | 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 | 1464 | static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1457 | 1465 | LLVMValueRef val1, LLVMValueRef val2, |
| 1458 | 1466 | TypeTableEntry *op1_type, TypeTableEntry *op2_type, |
| ... | ... | @@ -2727,7 +2735,7 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) { |
| 2727 | 2735 | |
| 2728 | 2736 | LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 2729 | 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 | 2739 | LLVMBuildStore(g->builder, new_index_val, index_ptr); |
| 2732 | 2740 | LLVMBuildBr(g->builder, cond_block); |
| 2733 | 2741 | |