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