Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7942 Discussions

Code generation bug in ICC 13 and 14

Paul_Russell
Beginner
275 Views

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

 

0 Kudos
2 Replies
Melanie_B_Intel
Employee
275 Views

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

0 Kudos
Paul_Russell
Beginner
275 Views

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 ?

0 Kudos
Reply