MichaelChirico / r-bugs

A ⚠️read-only⚠️mirror of https://bugs.r-project.org/
20 stars 0 forks source link

[BUGZILLA #15384] GCC 4.8.1 (4.7.2) -O3 compiled R 3.0.1 exhibits problem with NaN constants in Byte-Code #4972

Closed MichaelChirico closed 4 years ago

MichaelChirico commented 4 years ago

the grDevice check (test code) for convertColor() failed continuosly ... so I tried to track the problem down ...

I guess there is a problem with the way the byte-code compiler package works when compiled with gcc 4.8.1 (gcc 4.7.2 fails to create a properly working compiler, too)

### R 3.0.1 compiled with ### gcc 4.8.1 ### options: ### CFLAGS: -O3 -funroll-loops -ffast-math -march=corei7 ### configure flags: ### --enable-threads=posix --with-lapack --enable-memory-profiling --enable-R-shlib \ ### --enable-R-profiling \ ### --enable-shared --with-tcltk \ ### --with-system-pcre --with-system-zlib \ ### --with-system-bzlib --with-libpng --with-x

### -> "default" compiler package: 3.0.1

t2 <- function(vv) { vv[vv < 0] <- NaN; return(vv);}
print(t2(c(1,-2,3)))

[1] 1 NaN 3

library(compiler)
t2cgcc <- cmpfun(t2)
load(file="bytecode-t2-fun.bin")
disassemble(t2cgcc)

list(.Code, list(7L, LDCONST.OP, 1L, STARTASSIGN.OP, 2L, STARTSUBASSIGN.OP, 3L, 16L, GETVAR.OP, 2L, LDCONST.OP, 1L, LT.OP, 4L, PUSHARG.OP, DFLTSUBASSIGN.OP, ENDASSIGN.OP, 2L, POP.OP, GETVAR.OP, 2L, RETURN.OP), list({ vv[vv < 0] <- NaN return(vv) }, NaN, vv, [<-(*tmp*, vv < 0, value = NaN), vv < 0)) ^ ^ ^ | some '0' is missing here

### R 3.0.1 compiled with icc 11+ ### CFLAGS: -O3 -ipo -axSSE4.1 -msse4.1 -parallel ### compile flags: ### --prefix=/apps/R-3.0.1 \ ### --enable-R-shlib \ ### --with-blas="-lmkl_gf_lp64 -lmkl_blas95_lp64 \ ### -lmkl_lapack95_lp64 -lmkl" --with-lapack \

disassemble(t2c)

list(.Code, list(7L, LDCONST.OP, 1L, STARTASSIGN.OP, 2L, STARTSUBASSIGN.OP, 3L, 16L, GETVAR.OP, 2L, LDCONST.OP, 4L, LT.OP, 5L, PUSHARG.OP, DFLTSUBASSIGN.OP, ENDASSIGN.OP, 2L, POP.OP, GETVAR.OP, 2L, RETURN.OP), list({ vv[vv < 0] <- NaN return(vv) }, NaN, vv, [<-(*tmp*, vv < 0, value = NaN), 0, vv < 0))

print(t2(c(1,-2,3)))

[1] 1 NaN 3

print(t2c(c(1,-2,3)))

[1] 1 NaN 3

print(t2cgcc(c(1,-2,3)))

[1] 1 -2 3 ^^ ERROR ... should read NaN

# --------------------------------

If we compile R-3.0.1 using gcc 4.8.1 with CFLAGS = "-O0 -g " the the "grDevice" tests/check get passed; and the minimal 'NaN' test runs fine:

t2 <- function(vv) { vv[vv < 0] <- NaN; return(vv);}
print(t2(c(1,-2,3)))

[1] 1 NaN 3

library(compiler)
t2cgccO0 <- cmpfun(t2)
t2cgccO0(c(1,-2,3))

[1] 1 NaN 3

disassemble(t2cgccO0)

list(.Code, list(7L, LDCONST.OP, 1L, STARTASSIGN.OP, 2L, STARTSUBASSIGN.OP, 3L, 16L, GETVAR.OP, 2L, LDCONST.OP, 4L, LT.OP, 5L, PUSHARG.OP, DFLTSUBASSIGN.OP, ENDASSIGN.OP, 2L, POP.OP, GETVAR.OP, 2L, RETURN.OP), list({ vv[vv < 0] <- NaN return(vv) }, NaN, vv, [<-(*tmp*, vv < 0, value = NaN), 0, vv < 0))


METADATA

MichaelChirico commented 4 years ago

Thanks for the example.

I have gcc 4.7.2 on Fedora 18. With -O3 the build segfaults all over the place but I can get it far enough to reproduce this when I add -ffast-math. It isn't really a compiler issue: the compiler calls the C code implementing identical() to check whether a value is already in the constant pool, and with "-O3 -ffast-math" identical() does this:

identical(0, NaN)

[1] TRUE

I do not know if this is an issue in R_compute_identical or in gcc.

luke


METADATA

MichaelChirico commented 4 years ago

This is the docmented behaviour of gcc:

   -ffast-math
       Sets -fno-math-errno, -funsafe-math-optimizations,
       -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and
       -fcx-limited-range.

       This option causes the preprocessor macro "__FAST_MATH__" to be
       defined.

       This option is not turned on by any -O option besides -Ofast since
       it can result in incorrect output for programs that depend on an
       exact implementation of IEEE or ISO rules/specifications for math
       functions. It may, however, yield faster code for programs that do
       not require the guarantees of these specifications.

As R's documentation says

Floating Point Arithmetic: R requires arithmetic compliant with IEC 60559, also known as IEEE 754.

and more in §C.8 or the 'R Installation and Administration Manual'.


METADATA