Hi there,
I have run into something that looks like a bug in the compiler. I compile this code with '-O -fp_speculation=safe':
double *x = v2->data2->x; for (j = 0; j < len2; j++) { if ( type[j] == 'B' || type[j] == 'I' ) { if ( doscale ) xval = x[j] / scale[j]; else xval = x[j]; xfrac = xval - floor (xval + thresh); if ( xfrac > thresh ) { if ( type[j] == 'I'&& xfrac <= RELMINTHRESH (xval) ) continue; xiinf = (xfrac > 0.5) ? 1.0 - xfrac : xfrac; if ( ignore ) { b1j = b1[j]; b2j = b2[j]; if ( doscale ) { b1j /= scale[j]; b2j /= scale[j]; } if ( xval < b1j || xval > b2j ) { continue; } } if ( ilist ) { ilist[xn] = j; dlist[xn] = xfrac; } xs += xiinf; xn++; } } }
Running the compiled code produces a segmentation fault. Compiling without -fp_speculation=safe or without optimization at all, things work as expected. Even shuffeling around some code makes the problem go away. From gdb I get this:
Program received signal SIGSEGV, Segmentation fault. 0x0000000000400dbf in function1 () (gdb) disassemble Dump of assembler code for function function1: ... 0x0000000000400d8f <+959>: punpcklbw %xmm1,%xmm1 0x0000000000400d93 <+963>: punpcklbw %xmm2,%xmm2 0x0000000000400d97 <+967>: punpcklwd %xmm1,%xmm1 0x0000000000400d9b <+971>: punpcklwd %xmm2,%xmm2 0x0000000000400d9f <+975>: punpckldq %xmm1,%xmm1 0x0000000000400da3 <+979>: punpckldq %xmm2,%xmm2 0x0000000000400da7 <+983>: movdqa %xmm1,%xmm5 0x0000000000400dab <+987>: movsd 0x0(%r13,%r12,8),%xmm7 0x0000000000400db2 <+994>: andps %xmm2,%xmm5 0x0000000000400db5 <+997>: movhpd 0x8(%r13,%r12,8),%xmm7 0x0000000000400dbc <+1004>: movaps %xmm5,%xmm6 => 0x0000000000400dbf <+1007>: movaps (%r14,%r12,8),%xmm3 0x0000000000400dc4 <+1012>: movaps %xmm5,%xmm4 0x0000000000400dc7 <+1015>: andnps 0x5672(%rip),%xmm4 # 0x406440 0x0000000000400dce <+1022>: andps %xmm7,%xmm6 0x0000000000400dd1 <+1025>: movaps %xmm3,0x110(%rsp) 0x0000000000400dd9 <+1033>: andps %xmm5,%xmm3 0x0000000000400ddc <+1036>: orps %xmm4,%xmm6 0x0000000000400ddf <+1039>: orps %xmm4,%xmm3 0x0000000000400de2 <+1042>: divpd %xmm3,%xmm6 ... (gdb) info registers rax 0x0 0 rbx 0x7ffffffe7c00 140737488256000 rcx 0x7fffffff2860 140737488300128 rdx 0x7fffffffd4c0 140737488344256 rsi 0xac4 2756 rdi 0x4242 16962 rbp 0xac4 0xac4 rsp 0x7ffffffe7a80 0x7ffffffe7a80 r8 0x3 3 r9 0xffffffffffffffff -1 r10 0x7ffffffed230 140737488278064 r11 0x7fffffffdfc0 140737488347072 r12 0xe 14 r13 0x7fffffff2860 140737488300128 r14 0x0 0 r15 0x7ffffffed230 140737488278064 rip 0x400dbf 0x400dbf <function1+1007> eflags 0x10206 [ PF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0
As you can see, the code attempts to access element 14 (R12) in a NULL array (R14). I have looked at the offending assembler code and as far as I can tell the following happens: icc eliminates almost all 'if' statements in the code above and replaces this with branch-free code. This code always and unconditionally accesses scale[j] in each iteration. However, if 'doscale' is false then 'scale' is NULL, so unconditionally accessing scale will result in an segmentation fault. I am pretty sure that my source code is correct since it works well with gcc and when compiling without -fp_speculation=safe. In these cases I do not get any warnings from valgrind either.
I have a minimal example to reproduce the issue but right now the upload/attachment feature does not seem to work.
icc (ICC) 12.1.5 20120612
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
On this OS (uname -a):
Linux <hostname> 3.0.80-0.7-default #1 SMP Tue Jun 25 18:32:49 UTC 2013 (25740f8) x86_64 x86_64 x86_64 GNU/Linux
Is this a known issue? Is there a known way to work around the problem (I don't want to drop -fp_speculation=safe and I am not happy with shuffeling around my code until the issue magically disappears)?
Thanks a lot,
Daniel