https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127405
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords|needs-reduction |wrong-code
Priority|P3 |P2
Known to work| |13.5.0
Summary|[14/15/16 Regression] wrong |[14/15/16/17 Regression]
|code at -O3 with a reverse |wrong code at -O3 with a
|loop over |reverse loop over
|std::vector<struct-of-2-dou |std::vector<struct-of-2-dou
|bles> |bles>
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Testcase that also fails on trunk. One mitigation might be to restrict
unrolling of NE/EQ_EXPR exits in unsigned type.
/* { dg-do run } */
/* { dg-options "-O3" } */
#include <stdlib.h>
extern void abort (void);
void __attribute__((noinline, noclone, noipa)) test(unsigned long n, int *a,
int *b) {
for (unsigned long i = n - 2; i + 2 != 0; --i) {
a[i+2] = b[i+2] - a[i+3] - a[i+5] + (int)(i + 2);
}
}
int main(int argc, char **argv) {
/* Use argc to make n a pure runtime variable (n = 6) that the compiler
cannot propagate. */
unsigned long n = argc + 5;
int *a = (int *) malloc (12 * sizeof(int));
int *b = (int *) malloc (12 * sizeof(int));
for (int i = 0; i < 12; i++) {
a[i] = 0;
b[i] = i + 1;
}
test(n, a, b);
if (a[6] != 13 || a[5] != -2 || a[4] != 11 || a[3] != -17 || a[2] != 24 ||
a[1] != -32) {
abort ();
}
free (a);
free (b);
return 0;
}