[llvm-dev] (When) Do function calls read/latch/freeze their parameters?

Nicolai Hähnle via llvm-dev llvm-dev at lists.llvm.org
Mon Jul 13 12:57:40 PDT 2020


Hi,

We're looking at what may be a real-life bug encountered by our
compiler related to `undef` values and function calls.

The input program effectively contains the expression

    clamp(v, x, x)

expecting that the result will be equal to `x`, even when `v` is read
from uninitialized memory. In the input language, `clamp` is a
built-in, so this expectation is somewhat reasonable.

In our compiler, the clamp gets replaced by the logically equivalent
corresponding sequence of icmp/select instructions, which leads to
multiple reads from v, which changes the result when v is undef.

We should be able to fix this in our compiler by inserting a freeze
instruction, but to me this raises a more complicated point around
function inlining that is illustrated by this example:
https://alive2.llvm.org/ce/z/wcYxCB (I don't know if the output of
Alive2 is meaningful here or if there are limitations around function
calls).

Function inlining in LLVM currently does *not* introduce freezes.
However, calls to intrinsics such as llvm.minimum.* etc. are
presumably expected to introduce freezes. So if we think of intrinsics
as being implemented by library functions (as is de facto the case
with the `clamp` example above), should those library functions be
treated differently by inlining? Should such functions be written with
explicit `freeze`s in the beginning? Does this mean it would make
sense to expose `freeze` as an intrinsic accessible from C/C++ in
Clang, so that such library functions can be written in a high-level
language?

As you can see, I unfortunately have more questions than answers right now ;)

Cheers,
Nicolai
-- 
Lerne, wie die Welt wirklich ist,
aber vergiss niemals, wie sie sein sollte.


More information about the llvm-dev mailing list