https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128464
Bug ID: 128464
Summary: wrong code at -O1: complex lowering drops part of a
_Complex unsigned multiply with an abnormal SSA name
since r11-5156
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
Target: x86_64-pc-linux-gnu
int printf(const char *, ...);
unsigned f(unsigned x, unsigned y)
{
{
__label__ l1;
void g1(void) { goto l1; }
l1:;
}
_Complex unsigned z = 0, w;
__imag__ z = x;
__real__ w = 1;
__imag__ w = y;
z = ~(z * w);
{
__label__ l2;
void g2(void) { goto l2; }
g2();
l2:;
}
return __real__ z;
}
int main(void)
{
printf("%u\n", f(1, 1));
return 0;
}
$ gcc -O0 t.c && ./a.out
4294967295
$ gcc -O1 t.c && ./a.out
0
-O1, -O2, -O3 all fail.
Expected: 4294967295. z = 0 + 1i and w = 1 + 1i, so z * w = -1 + 1i. ~ on a
complex value is the conjugate, -1 - 1i, so the real part is 4294967295. Both
parts of w are written before w is read.
The non-local goto makes z and w abnormal SSA names.
complex_propagate::visit_stmt and visit_phi return SSA_PROP_VARYING for such an
lhs before they set its lattice value, and the stale value makes the multiply
lowering assume a zero imaginary part. Setting the lattice to VARYING there
fixes it. Some forms of this are wrong at -O0 as well, because complex lowering
runs there too.
Bisected to r11-5156-g0d8290959ec (also r10-9405-g9272936ac5f on the gcc-10
branch).
Correct on 8.5.0.
Wrong on 10.5.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, trunk.
-O0 -fsanitize=undefined,address is clean.
gcc version 17.0.0 20261029 (experimental), r17-5747-g85867b0c935,
x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release