optimization in presence of floating point

an interesting problem occurs if you do interval arithmetic.

void foo() {
float XL, XU, Y, Z;

....
call_change_rounding_mode(lower);
XL = Y + Z; // lower bound
call_change_rounding_mode(upper);
XU = Y + Z;

}

Two issues here:
1) will the compiler mistakenly treat Y+Z as a common subexpression.
2) might it move the call_change_rounding_mode after the assignment to XU since it seens no dependency.

This is actually to my previous mips16 ir post but is a question of more wide interest.

From: "reed kotler" <rkotler@mips.com>
To: LLVMdev@cs.uiuc.edu
Sent: Wednesday, April 17, 2013 8:32:23 PM
Subject: [LLVMdev] optimization in presence of floating point

an interesting problem occurs if you do interval arithmetic.

void foo() {
float XL, XU, Y, Z;

....
call_change_rounding_mode(lower);
XL = Y + Z; // lower bound
call_change_rounding_mode(upper);
XU = Y + Z;

}

Two issues here:
1) will the compiler mistakenly treat Y+Z as a common subexpression.
2) might it move the call_change_rounding_mode after the assignment
to
XU since it seens no dependency.

I have come across these issues myself as well. To be fair, Clang does not support the FENV_ACCESS pragma, and as I recall, the standard allows an implementation-defined default value (which, in our case, cannot be changed). Moreover, LLVM internally does not have an option to enable the correct conservative side-effect model to make all of this really work correctly.

-Hal

Note that there are also some constant optimizations which assume the floating point rounding mode in order to be correct, so that they may misapply if the rounding mode is different. Duncan Sands has suggested that the correct “fix” is to add metadata to each floating point operation describing the rounding mode and then change processing to be aware of this. This seems like a good plan, but it’s also a very big feature to implement with appropriate confidence that it’s right, so it’s not something I’m planning to dive into any time soon.

For reordering issues, it would be useful for llvm ir to provide various ways to control reordering.

for example, a wrapper that indicates that other operations cannot be moved inside the wrapper.

or a wrapper that indicates that the IR in it must be processed canonically.

I think GCC may already have some of this but I'm not sure.

For reordering issues, it would be useful for llvm ir to provide various
ways to control reordering.

for example, a wrapper that indicates that other operations cannot be
moved inside the wrapper.

This sounds like a membarrier.

or a wrapper that indicates that the IR in it must be processed
canonically.

Or, maybe a volatile-like flag that only exists within a certain scope.

-Cameron