From b3bce10699d43c4bb11bd31734d0a630b4ab533f Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 3 Nov 2025 02:43:01 +0100 Subject: [PATCH] Remove division-by-zero checks for floating point in safe mode #2556. --- releasenotes.md | 1 + src/compiler/llvm_codegen_expr.c | 4 ++-- test/test_suite/floats/div_by_zero.c3t | 27 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/floats/div_by_zero.c3t diff --git a/releasenotes.md b/releasenotes.md index bad198367..434947084 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -8,6 +8,7 @@ ### Fixes - `Foo.is_eq` would return false if the type was a `typedef` and had an overload, but the underlying type was not comparable. +- Remove division-by-zero checks for floating point in safe mode #2556. ### Stdlib changes diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index c7a926783..5ab3aaf96 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4238,23 +4238,23 @@ void llvm_emit_binary(GenContext *c, BEValue *be_value, Expr *expr, BEValue *lhs val = llvm_emit_add_int(c, lhs_type, lhs_value, rhs_value, expr->span); break; case BINARYOP_DIV: - llvm_emit_trap_zero(c, rhs_type, rhs_value, "Division by zero.", expr->span); if (is_float) { val = LLVMBuildFDiv(c->builder, lhs_value, rhs_value, "fdiv"); break; } + llvm_emit_trap_zero(c, rhs_type, rhs_value, "Division by zero.", expr->span); val = type_is_unsigned(lhs_type) ? LLVMBuildUDiv(c->builder, lhs_value, rhs_value, "udiv") : LLVMBuildSDiv(c->builder, lhs_value, rhs_value, "sdiv"); break; case BINARYOP_MOD: - llvm_emit_trap_zero(c, rhs_type, rhs_value, "% by zero.", expr->span); if (type_is_float(lhs_type)) { val = LLVMBuildFRem(c->builder, lhs_value, rhs_value, "fmod"); break; } + llvm_emit_trap_zero(c, rhs_type, rhs_value, "% by zero.", expr->span); val = type_is_unsigned(lhs_type) ? LLVMBuildURem(c->builder, lhs_value, rhs_value, "umod") : LLVMBuildSRem(c->builder, lhs_value, rhs_value, "smod"); diff --git a/test/test_suite/floats/div_by_zero.c3t b/test/test_suite/floats/div_by_zero.c3t new file mode 100644 index 000000000..17f6d6419 --- /dev/null +++ b/test/test_suite/floats/div_by_zero.c3t @@ -0,0 +1,27 @@ +// #target: macos-x64 +// #safe: yes +module test; + +fn void test() +{ + float x, y; + x = x / y; + x = x % y; +} + +/* #expect: test.ll + +entry: + %x = alloca float, align 4 + %y = alloca float, align 4 + store float 0.000000e+00, ptr %x, align 4 + store float 0.000000e+00, ptr %y, align 4 + %0 = load float, ptr %x, align 4 + %1 = load float, ptr %y, align 4 + %fdiv = fdiv float %0, %1 + store float %fdiv, ptr %x, align 4 + %2 = load float, ptr %x, align 4 + %3 = load float, ptr %y, align 4 + %fmod = frem float %2, %3 + store float %fmod, ptr %x, align 4 + ret void