/************************************************************************* This is a minimal code to isolate a suspected bug of icc. Expected behaviour: The main function initializes and prints the input struct before calling function "trouble". The result after the call should have the value 1.0 in element c2.x (and all other elements zero). In addition, the global variables "dbx1" and "dbx2" are assigned in function "trouble" to the intermediate value of (*u).c1.x and (*u).c2.x (which also should be 1.0). Observed behaviour of the function "trouble" with icc versions 12.1.1, 12.1.6, 13.1.3, or 14.0.1: When compiled with option "-O1" the result after the call is incorrect, while with "-O0" or "-O2" it is correct. With other, non-minimal versions of this function, the incorrect behaviour can also be observed with option "-O2". Remark: The function "trouble" is extracted from project_su3hyp_dble (which projects HYP-smeard gauge matrices back into the SU(3) group). This minimal version of that function is still supposed to be a valid code, but of course is not very sensible any more, because most of the original functionality has been removed. Author: Felix Bahr and Hubert Simma 17.2.2014 *************************************************************************/ #include #include double dbx1, dbx2; typedef struct { double x, y; } pair_t; typedef struct { pair_t c1, c2; } trouble_t; /* The incorrect behaviour disappears, if trouble_t is defined as follows (and ".x" and ".y" are replaced by "x" and "y" everywhere): typedef struct { double c1x, c1y, c2x, c2y; } trouble_t; */ /* "trouble" must NOT be static */ void trouble( trouble_t *u) { double norm; norm = 0.25 * (*u).c2.x; (*u).c1.x = norm * (*u).c1.x; (*u).c1.y = norm * (*u).c1.y; (*u).c2.x = norm * (*u).c2.x; (*u).c2.y = norm * (*u).c2.y; /* The following 2 lines are optional and only serve to demonstrate that the compiler has missed the changed value of (*u).c2.x */ dbx1 = (*u).c1.x; dbx2 = (*u).c2.x; /* If the following line is removed, dbx2 still has an incorrect value, but after the function call *u has correct values */ (*u).c2.x = (*u).c2.x * (*u).c2.x; } int main(int argc, char * argv[]) { trouble_t m; m.c1.x=2.0; m.c1.y=0; m.c2.x=2.0; m.c2.y=0; printf("Before trouble: %f %f %f %f (expect: 2.0 0.0 2.0 0.0)\n", m.c1.x, m.c1.y, m.c2.x, m.c2.y); trouble(&m); printf("In trouble 1: %f (expect: 1.0)\n", dbx1); printf("In trouble 2: %f (expect: 1.0)\n", dbx2); printf("After trouble: %f (expect: 1.0)\n", m.c2.x); return 0; }