Compiler creates invalid code with -fp_speculation=safe

Compiler creates invalid code with -fp_speculation=safe

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

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Best Reply

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.

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.

Attachments: 

AttachmentSize
Download bug_0.zip368.95 KB

Leave a Comment

Please sign in to add a comment. Not a member? Join today