Issue 135911
Summary Unevaluated parts of conditional operator are sometimes evaluated
Labels new issue
Assignees
Reporter Evenedric
    The following code fragment

    double Foo(double Q, double A) {
      return (A == 0) ? 0.0 : Q / A;
 }

Compiled with `g++ -c -O2 foo.cc` on the arm64-apple target, generates the following assembly:

    00000000   fdiv  d0, d0, d1
    00000004 fcmp  d1, #0.0
    00000008   movi  d1, #0000000000000000
    0000000c fcsel d0, d1, d0, eq
    00000010   ret

Which is (usually) correct. Note that the `fdiv` instruction runs regardless of whether `A == 0` or not, but since the subexpression `Q / A` is side effect free this is normally not a problem. In my case I create side effects by installing a floating point error handler that traps division by zero. The function `Foo(Q,0)` would be expected to avoid such a trap, but with the above assembly code it does not.

I believe that in the conditional _expression_ `A?B:C`, only one of `B` or `C` should be evaluated with side effects. But maybe the compiler is justified in evaluating both if it believes them to be side effect free? (The fact that I created side effects by calls to fesetenv() and sigaction() is certainly not known to the compiler). I haven't found a clear policy on this sort of thing - at the very least, it seems like a grey area.

Other details:

  > g++ -v
  Apple clang version 16.0.0 (clang-1600.0.26.4)
 Target: arm64-apple-darwin24.3.0
  Thread model: posix
  InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to