aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-12-01 13:11:32 +0000
committergingerBill <gingerBill@users.noreply.github.com>2025-12-01 13:11:32 +0000
commit0f0c40b96dc5d5b6e585c935186b342180747d06 (patch)
tree5ea7b828f4f697ac3f1b759d7b076d442882938d /src
parent493220eb323c1e6dd2d1784c2d779a506b2dc3f3 (diff)
Fix `-integer-division-by-zero` modes and document `all-bits`
Diffstat (limited to 'src')
-rw-r--r--src/llvm_backend_expr.cpp19
-rw-r--r--src/llvm_backend_proc.cpp2
-rw-r--r--src/main.cpp6
3 files changed, 15 insertions, 12 deletions
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index d5658b9d5..9b8df5a37 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -1161,8 +1161,7 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
case IntegerDivisionByZero_Zero:
return zero;
case IntegerDivisionByZero_AllBits:
- // return all_bits;
- break;
+ return all_bits;
}
} else {
if (!is_signed && lb_sizeof(type) <= 8) {
@@ -1198,7 +1197,6 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
lb_start_block(p, edge_case_block);
-
switch (behaviour) {
case IntegerDivisionByZero_Trap:
lb_call_intrinsic(p, "llvm.trap", nullptr, 0, nullptr, 0);
@@ -1214,17 +1212,17 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
incoming_values[1] = all_bits;
break;
}
+ LLVMValueRef res = nullptr;
lb_emit_jump(p, done_block);
lb_start_block(p, done_block);
- LLVMValueRef res = incoming_values[0];
switch (behaviour) {
case IntegerDivisionByZero_Trap:
- case IntegerDivisionByZero_Self:
res = incoming_values[0];
break;
+ case IntegerDivisionByZero_Self:
case IntegerDivisionByZero_Zero:
case IntegerDivisionByZero_AllBits:
res = LLVMBuildPhi(p->builder, type, "");
@@ -1233,6 +1231,9 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
incoming_blocks[0] = p->curr_block->preds[0]->block;
incoming_blocks[1] = p->curr_block->preds[1]->block;
+ GB_ASSERT(incoming_blocks[0] == safe_block->block);
+ GB_ASSERT(incoming_blocks[1] == edge_case_block->block);
+
LLVMAddIncoming(res, incoming_values, incoming_blocks, 2);
break;
}
@@ -1240,7 +1241,7 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
return res;
}
-gb_internal LLVMValueRef lb_integer_division_intrinsics(lbProcedure *p, LLVMValueRef lhs, LLVMValueRef rhs, LLVMValueRef scale, Type *platform_type, char const *name) {
+gb_internal LLVMValueRef lb_integer_division_fixed_point_intrinsics(lbProcedure *p, LLVMValueRef lhs, LLVMValueRef rhs, LLVMValueRef scale, Type *platform_type, char const *name) {
LLVMTypeRef type = LLVMTypeOf(rhs);
GB_ASSERT(LLVMTypeOf(lhs) == type);
@@ -1310,13 +1311,13 @@ gb_internal LLVMValueRef lb_integer_division_intrinsics(lbProcedure *p, LLVMValu
lb_emit_jump(p, done_block);
lb_start_block(p, done_block);
- LLVMValueRef res = incoming_values[0];
+ LLVMValueRef res = nullptr;
switch (behaviour) {
case IntegerDivisionByZero_Trap:
- case IntegerDivisionByZero_Self:
res = incoming_values[0];
break;
+ case IntegerDivisionByZero_Self:
case IntegerDivisionByZero_Zero:
case IntegerDivisionByZero_AllBits:
res = LLVMBuildPhi(p->builder, type, "");
@@ -1423,9 +1424,9 @@ gb_internal LLVMValueRef lb_integer_modulo(lbProcedure *p, LLVMValueRef lhs, LLV
switch (behaviour) {
case IntegerDivisionByZero_Trap:
- case IntegerDivisionByZero_Self:
res = incoming_values[0];
break;
+ case IntegerDivisionByZero_Self:
case IntegerDivisionByZero_Zero:
case IntegerDivisionByZero_AllBits:
res = LLVMBuildPhi(p->builder, type, "");
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 10e10564e..27167aefd 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -3305,7 +3305,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
if (id == BuiltinProc_fixed_point_div ||
id == BuiltinProc_fixed_point_div_sat) {
- res.value = lb_integer_division_intrinsics(p, x.value, y.value, scale.value, platform_type, name);
+ res.value = lb_integer_division_fixed_point_intrinsics(p, x.value, y.value, scale.value, platform_type, name);
} else {
LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
diff --git a/src/main.cpp b/src/main.cpp
index 544cd54bb..ca05bb177 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1570,8 +1570,10 @@ gb_internal bool parse_build_flags(Array<String> args) {
build_context.integer_division_by_zero_behaviour = IntegerDivisionByZero_Zero;
} else if (str_eq_ignore_case(value.value_string, "self")) {
build_context.integer_division_by_zero_behaviour = IntegerDivisionByZero_Self;
- }else {
- gb_printf_err("-integer-division-by-zero options are 'trap', 'zero', and 'self'.\n");
+ } else if (str_eq_ignore_case(value.value_string, "all-bits")) {
+ build_context.integer_division_by_zero_behaviour = IntegerDivisionByZero_AllBits;
+ } else {
+ gb_printf_err("-integer-division-by-zero options are 'trap', 'zero', 'self', and 'all-bits'.\n");
bad_flags = true;
}
break;