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;
}

Reply via email to