The LLVM projects page says this:

"We need some way to reason about errno. Consider a loop like this:
     for ()
       x += sqrt(loopinvariant);"


"The hard part of this project is figuring out how to describe errno in the optimizer"

The important property here is the idempotence of sqrt(): it is potentially side-effecting, but that side effect is independent of the number of times it is called (with the same argument).

Thus the solution to the errno problem seems to be an idempotence analysis pass, an idempotent function attribute, and a handful of passes (LICM, maybe more) that exploit this attribute.

Putting on my volatile testing hat for a second, I feel compelled to mention that no function that potentially touches a volatile object is idempotent :).

John Regehr