Code generation bug in ICC 13 and 14

Code generation bug in ICC 13 and 14

I've been trying to find somewhere on the Intel site to file a bug report but it seems virtually impossible to do this, so I thought I'd try posting it here. If anyone has a link to a proper bug reporting page then I'd be happy to file it there too.

Here's a self-contained example which illustrates a serious code gen bug in ICC 13 and 14 which shows up at -O2 and above. ICC 11 is fine. There is also a workaround included:

#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

void ReverseData(
    const int n,        // IN: data height and width (it must be square)
    uint16_t data[]     // IN: data to be mirrored.  Must not be NULL.
                        // OUT: data image with columns reversed.
)
{
    uint16_t *pRowStart = &data[0];     // point to row 0 column 0
    uint16_t *pRowEnd   = &data[n-1];   // point to row 0 column n-1
    int r;
    for (r = 0; r < n; ++r)
    {
        int c;
        for (c = 0; c < n/2; ++c)
        {
            uint16_t *pLeft  = pRowStart + c;
            uint16_t *pRight = pRowEnd   - c;
            uint16_t dLeft  = *pLeft;
            uint16_t dRight = *pRight;
#ifdef WORKAROUND
            // NB: these asserts are a workaround for an apparent code generation bug in ICC versions 13
            //     and 14 - without these asserts we get memory corruption beyond the end of the data.
            //     Note: this bug does not appear to be present in ICC 11.
            assert(pLeft >= &data[0] && pLeft < &data[n*n]);
            assert(pRight >= &data[0] && pRight < &data[n*n]);
#endif
            *pLeft  = dRight;
            *pRight = dLeft;
        }
        pRowStart += n;
        pRowEnd += n;
    }
} // end: ReverseData()

int main()
{
    const int n = 32;
    const int size = n * n + n;     // data is nxn but add an additional row for test purposes -
    uint16_t *data = NULL;          // this additional guard row should not get over-written
    int r, c;                       // unless we have a code generation bug
    int errors = 0;

    data = calloc(size, sizeof(data[0]));
                                    // allocate and init all data to zero

    for (r = 0; r < n; ++r)         // init nxn data to distinct values, leaving additionl guard row set to zero
    {
        for (c = 0; c < n; ++c)
        {
            data[r * n + c] = r * n + c;
       }
    }

    printf("Call ReverseData(%d, %p)...\n", n, data);

    ReverseData(n, data);           // call our function to reverse nxn data

    for (c = 0; c < n; ++c)         // check to see whether anything has been written to our guard row
    {
        if (data[r * n + c] != 0)
        {
            printf("Error at index %d, data should be 0 but is actually %u !\n", r * n + c, data[r * n + c]);
            errors++;
        }
    }

    printf("%s\n", errors == 0 ? "PASS" : "FAIL");

    free(data);

    return 0;
}

 

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

For support there is "Intel Premier Support", but these Forums are monitored too

Thanks for the test case, I can reproduce the test failure; with gcc at O2 it passes

I created DPD200357874 in our internal bugs database

Many thanks for filing the bug report Melanie - I guess I need to set up an "Intel Premier Support" account if I want to track this ?

Leave a Comment

Please sign in to add a comment. Not a member? Join today