This pragma is introduced by forthcoming C2x standard and can be used to
set particular rounding mode without need to call 'fesetmode' or accessing
control mode registers directly. Previously this pragma was implemented in
clang partially, only for the purpose of using in constant expressions and
making tests.
This change implements the pragma according to the standard draft. It sets
up dynamic rounding mode in the compound statement where the pragma acts.
This is inevitable for targets that set rounding mode by changing some
control register. Some targets however allow specifying rounding mode as a
field in instructions, in this case setting dynamic rounding mode is not
mandatory. However the standard draft requests that invocations of
functions shall be evaluated using dynamic rounding mode. So the dynamic
rounding mode is set even if actually later it is unused. Removal of
unneeded manipulation on dynamic rounding mode can be made by a separate
IR optimization.
The implementation uses intrinsic functions 'flt_rounds' and
'set_rounding' to save/restore dynamic rounding mode. It is not the best
way, because these functions need to extract rounding mode from the
content of some control register or pack into it. More efficient
implementation could save/restore entire value of the control register. It
requires functions 'fegetmode' and 'fesetmode' to be implemented as LLVM
intrinsic functions. When these functions will be implemented, the same
mechanism could be used in implementation of other similar fp pragmas.
I was imagining that if the new rounding mode is dynamic, we still need to reset the rounding mode back to what it was when the thread was created or to the previous rounding mode set by a library call, but now I'm not certain. I commented on one of the test cases about what I was thinking.