Issue 136695
Summary [Optimization Request] Improve code generation for explicit division-by-zero checks
Labels new issue
Assignees
Reporter 399833783
    Related to: [#136679 Clang silently eliminates division-by-zero error detection when optimizations are enabled, with inconsistent behavior between optimization levels](https://github.com/llvm/llvm-project/issues/136679)

Thank you for your response. While I understand that this is undefined behavior according to the standard, this optimization poses several practical issues in real-world development:

**1. Debugging challenges:** The same code behaves differently between `-O0` and `-O2`, making it difficult for developers to track down problems.
**2. Security traps:** Many defensive programming techniques rely on division-by-zero errors as a last line of defense.
**3. Portability:** Different compilers handle this situation differently, increasing porting difficulty.

I'd also like to highlight a significant optimization inconsistency: When developers properly handle division-by-zero with explicit checks (e.g., "`if (b == 0) return false`"), the compiled code contains unnecessary jumps compared to the "unsafe" version without checks. This seems counterintuitive - code that correctly handles edge cases should be optimized at least as well as code that invokes undefined behavior.

Consider this practical scenario: A function calculates A/B and returns the result, but the developer assumes the caller will check `B != 0`. In debug mode (`-O0`), everything works as expected because division by zero triggers an error. However, in release mode (`-O2`), unexpected behavior might occur.

>From a mathematical standpoint, transforming "`a > (~0ULL) / b`" into a multiplication-based check is not valid when b could be zero. The compiler is applying an algebraic transformation that assumes constraints ($b ≠ 0$) not enforced in the code. Rather than silently substituting semantically different operations, wouldn't it be more appropriate to preserve the division instruction and let the CPU raise the expected exception?

The fact that Clang preserves division-by-zero checks in `-O0` but removes them in `-O2` creates an inconsistency. Even for undefined behavior, isn't behavioral consistency across optimization levels a reasonable expectation?

Perhaps these improvement options could be considered:
1. Add compiler warnings when division by zero might be optimized away.
2. Don't apply this optimization in case A1 (no condition check, with `-O2`), maintaining consistency with case A3 (no condition check, without `-O2`).
3. Improve optimization for code that properly checks for division by zero (case A2), ensuring it's at least as efficient as the unchecked version (case A1).

These changes would help developers better understand their code's actual behavior and reduce unexpected surprises.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to