https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128631

            Bug ID: 128631
           Summary: wrong code at -O1: x / 1.0 folded to x for _Complex
                    double, wrong sign of zero in real part
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jeffchen006 at gmail dot com
  Target Milestone: ---

int printf(const char *, ...);
_Complex double x = -0.0;
int main(void) {
  _Complex double one = 1;
  printf("%g\n", __real__ (x / one));
}

$ gcc -O0 t.c && ./a.out
0
$ gcc -O1 t.c && ./a.out
-0

Expected: 0. x = -0+0i, one = 1+0i. Real part of x/one = (-0*1 + 0*0)/1 = +0
(libgcc __divdc3 and Clang give 0). -O1 folds x/one to x and prints -0. x / -1
has the same problem.

Suspected cause: match.pd rdiv rules with real_onep / real_minus_onep (x / 1 ->
x, x / -1 -> -x) have no guard for complex signed zeros. The mult twins have
the guard.

Known to fail: 8.5.0, 10.5.0, 11.4.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0,
17.0.

-O0 -fsanitize=undefined,address is clean.

gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release

Reply via email to