https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126491
Bug ID: 126491
Summary: [13/14/15/16/17 Regression] Wrong code with
address_compare
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: ktkachov at gcc dot gnu.org
Target Milestone: ---
/* Wrong code: address_compare () (gcc/fold-const.cc:16483) computes
equal == 2 ("cannot decide") for these pairs at fold-const.cc:16614-16631,
then throws that verdict away at fold-const.cc:16672-16676
if (!INTEGRAL_TYPE_P (type))
return 0;
and reports "known unequal" for every pointer-typed comparison.
match.pd:8393-8396 folds the == to constant false, yet the very same two
addresses compare equal at run time in the same program.
Free of undefined behaviour: forming and comparing a one-past-the-end
pointer is allowed, == between pointers to distinct objects is a defined
comparison, and no object is dereferenced. */
char e0[0];
char e1[0];
struct E { };
struct E es1, es2;
char g1[16];
char g2[16];
/* Run-time reference: a single comparison the optimiser cannot fold. */
__attribute__((noipa)) int rt (void *a, void *b) { return a == b; }
__attribute__((noipa)) void chk (int folded, int runtime)
{
if (folded != runtime)
__builtin_abort ();
}
int main (void)
{
/* Zero-sized objects are placed at one and the same address, so both of
these compare equal at run time. The fold says "unequal". */
chk (&e0[0] == &e1[0], rt (&e0[0], &e1[0]));
chk ((char *) &es1 == (char *) &es2, rt ((char *) &es1, (char *) &es2));
/* C11 6.5.9p6: a one-past-the-end pointer compares equal to a pointer to
the start of an object that immediately follows it in the address space.
Whichever of g1/g2 the compiler lays out first, one of the two lines
below is such a pair at run time. Both fold to constant false. */
chk (&g1[16] == &g2[0], rt (&g1[16], &g2[0]));
chk (&g2[16] == &g1[0], rt (&g2[16], &g1[0]));
return 0;
}
aborts at -O2 since GCC 10 on aarch64