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

            Bug ID: 128629
           Summary: [14/15/16/17 Regression] wrong code at -O1: match.pd
                    -((-a)/b) -> a/b and -(a*-b) -> a*b applied to
                    _Complex double (sign of zero)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: needs-bisection, 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 a = 1;
int main(void) {
  _Complex double t = -a;
  _Complex double x = -(t / a);
  printf("%g\n", __imag__ x);
}

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

Expected: -0. t = -a = -1-0i and t/a = -1+0i, so -(t/a) = 1-0i: the imaginary
part is -0. The fold gives a/a = 1+0i (+0). Second test (mult rule):
BUG-042/reduced-min-mul.c, a = 1+1i, x = -(a * -a): -O0 prints -0 for the real
part, -O1 prints 0.

Suspected cause: match.pd negate rules "-(a * -b) -> a * b" and "-((-a) / b) ->
a / b" have no guard for complex types with signed zeros.

Avoided by: -fno-tree-forwprop (at -O1).

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

Known to work: 8.5.0, 10.5.0, 11.4.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