John Reagan via llvm-dev
2018-Jan-12 16:41 UTC
[llvm-dev] [cfe-dev] Why is #pragma STDC FENV_ACCESS not supported?
I'll give some data points from our OpenVMS Itanium (and Alpha) platforms where we support multiple IEEE modes and dynamic rounding in our C and Fortran compilers (we don't have actual FENV_ACCESS in our C product but you can come close). On the command line, you get to pick IEEE modes with: /IEEE_MODE /IEEE_MODE=option /IEEE_MODE=DENORM_RESULTS (D) Selects the IEEE floating-point mode to be used. Options: FAST During program execution, only finite values (no infinities, NaNs, or denorms) are created. Exceptional conditions, such as floating point overflow and divide by zero, are fatal. UNDERFLOW_TO_ZERO Generate infinities and NaNs. Flush denormalized results and underflow to zero without exceptions. DENORM_RESULTS Same as UNDERFLOW_TO_ZERO, except that denorms are generated. This is the default for I64 systems. INEXACT Same as DENORM_RESULTS, except that inexact values are trapped. This is the slowest mode. and rounding modes /ROUNDING_MODE /ROUNDING_MODE=option /ROUNDING_MODE=NEAREST (D) For /FLOAT=IEEE_MODE, the /ROUNDING_MODE qualifier lets you select one of the following IEEE rounding modes: o NEAREST (default) o DYNAMIC o MINUS_INFINITY o CHOPPED And "strict" modes /ASSUME /ASSUME=(option[,...]) Controls compiler assumptions. You may select the following options: [NO]ACCURACY_SENSITIVE Specifies whether certain code transformations that affect floating-point operations are allowed. These changes may or may not affect the accuracy of the program's results. If you specify NOACCURACY_SENSITIVE, the compiler is free to reorder floating-point operations, based on algebraic identities (inverses, associativity, and distribution). This allows the compiler to move divide operations outside of loops, improving performance. The default, ACCURACY_SENSITIVE, directs the compiler to use only certain scalar rules for calculations. This setting can prevent some optimization. if you pick DYNAMIC, you can then use a system call (SYS$IEEE_SET_ROUNDING_MODE) to change the value. We warn in our manuals that /ROUNDING=DYNAMIC may have a significant performance impact. The idea is that you set the mode [the routine returns the prior mode], do you work, put the old mode back. You would collect such code into its own module and compile with with DYNAMIC but compile the majority of your code with the defaults. We've had our default be "strict" with /ASSUME=ACCURACY_SENSITIVE for years and let people specify NOACCURACY if desired. We don't tie it to any optimization level. It is a separate knob.