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

Compiler creates invalid code with -fp_speculation=safe

djunglas
New Contributor I
233 Views

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 == 'B' ||
              type == 'I'   ) {
            if ( doscale )  xval = x / scale;
            else            xval = x;
            xfrac = xval - floor (xval + thresh);

            if ( xfrac > thresh ) {
               if ( type == 'I' && xfrac <= RELMINTHRESH (xval)  )
                  continue;

               xiinf = (xfrac > 0.5) ? 1.0 - xfrac : xfrac;

               if ( ignore ) {
                  b1j = b1;
                  b2j = b2;

                  if ( doscale ) {
                     b1j /= scale;
                     b2j /= scale;
                  }
                  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 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

0 Kudos
1 Solution
Tom_T_
Novice
233 Views

icc12.1 was very bad at -fp-speculation=safe, as were early versions of icc 13.

icc 13.1.0.146 Build 20130121 or newer (e.g. icc14) do much better.  I hope you are able to upgrade.

View solution in original post

0 Kudos
2 Replies
Tom_T_
Novice
234 Views

icc12.1 was very bad at -fp-speculation=safe, as were early versions of icc 13.

icc 13.1.0.146 Build 20130121 or newer (e.g. icc14) do much better.  I hope you are able to upgrade.

0 Kudos
djunglas
New Contributor I
233 Views

Thank you for the tip. I tried version 'icc (ICC) 13.1.3 20130607' and with that the problem no longer occurs.

Since the "select media" function seems to work now, I have attached my minimal failing example for sake of completeness. Just run 'make' to reproduce the issue.

0 Kudos
Reply