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