Skip to content

std.math ieeeFlags cannot be reliably tested #888

@smolt

Description

@smolt

The compiler can unexpectedly rearrange floating point operations and access to the floating point status flags when optimizing. This means std.math ieeeFlags cannot be reliably checked in optimized code. Consider:

void main()
{
    import std.math;
    static real zero = 0.0;
    real x = 3.5;

    resetIeeeFlags();
    assert(!ieeeFlags.invalid);

    x /= zero;
    x *= zero;
    assert(ieeeFlags.invalid);  // optimizer may moves this before div and mult
    assert(isNaN(x));
}

Here, optimizer moves function call ieeeFlags() before math ops, and invalid is not set as expected.
This has been observed with LLVM 3.6 targeting arm and x86-64, and other combinations may be affected to. Right now it is cause a new 2.067 unittest in std.math to fail.

C99 invented "#pragma STDC FENV_ACCESS ON" to prevent optimizer from reordering instructions that affect float environment. See note [2] here: http://en.wikipedia.org/wiki/C99#Example

clang does not support this pragma and LLVM IR has no way of expressing:
https://llvm.org/bugs/show_bug.cgi?id=10409

This also could be an issue for gdc as this reference says gcc doesn't support pragma FENV_ACCESS:
http://wiki.musl-libc.org/wiki/Mathematical_Library#Fenv_and_error_handling

Work around in C is to use volatile vars to force ordering and libm.h has a FORCE_EVAL macro to do that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions