Inconsistent program behavior on Red Hat Enterprise Linux* 7.4 if compiled with Intel compilers

Reference Number : CMPLRS-41993, CMPLRS-45873, CMPLRS-4605

Version : Intel® C++ and Fortran Compilers 17.0, 18.0 for Intel 64 only, older versions affected as well

Operating System : Red Hat Enterprise Linux* 7.4, Centos* 7.4, Fedora* 25

Problem Description :  There is an issue with calls via Procedure Linkage Table (PLT) to functions with custom calling conventions on Red Hat Enterprise Linux* 7.4.  Such functions are widely used in Intel compiler libraries, such as LIBIRC, LIBSVML, etc. The Intel compiler generates usual call sequence for such functions, and they may be called via PLT in the final executable. During the resolution of the PLT relocation the runtime may overwrite registers that do not need to be preserved according to the ABI. The code enclosing such a call can not assume that the call follows the defined custom calling convention anymore.  The issue may cause inconsistent program behavior, such as floating-point exceptions (e.g. unexpected NaN generation) or crashes (SIGSEGVs).

Note that the problem may be observed on any system containing glibc version 2.24-9 and newer (as well as the particular version of glibc 2.17 that comes with RHEL 7.4 and Centos 7.4).

Following test case (Fortran and C version) may be used to reproduce the problem and check if the system is affected.

Fortran:

program test_glibc_except
  use, intrinsic :: ieee_arithmetic
  real, dimension(3) :: x, y

  call ieee_set_halting_mode(ieee_invalid, .true.)
  do i = 1,3
     x(i) = 0.
     y(i) = exp(x(i))
  end do

  print *,'y= ',y
end program test_glibc_except

$ ifort -shared-intel test_glibc_except.f90; ./a.out
forrtl: error (65): floating invalid
...
libsvml.so   00007F4820628441  __svml_expf4_l9    Unknown  Unknown

C:

#include <stdio.h>
#include <math.h>
int main()
{
  float x[3], y[3];

        for (int i=0; i<3; i++)  {
            x[i] = 0.;
            y[i] = exp(x[i]);
        }

  printf("y[2]= %f \n",y[2]);
  return 0;
}

$ icc -std=c99 -shared-intel -fp-trap=invalid test_exp.c; ./a.out
Floating point exception (core dumped)

Note that if invalid exceptions are masked then the last element printed is a NaN.

Resolution Status : One workaround is to do all required relocations at startup of a binary by setting the environment variable LD_BIND_NOW=1.  The 17.0 Update 4 and Update 5 compilers and also the initial 18.0 release have a workaround implemented in the compiler that will avoid PLT relocations for the problem calls if -fPIC is specified.

This issue has been resolved: in the 17.0 Update 6 or 18.0 Update 1 compiler   (no need to specify -fPIC)

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.