cfe-dev Digest, Vol 139, Issue 16

Hi JF,

A few options:

  1. Make them a builtin, have libc implementations forward to the builtin.
  2. Teach clang / LLVM about these function’s semantics (i.e. if conditions met, same as memset).

I think 1. is the best approach.

Could you expand on why 1 looks better than 2?

There’s a lot of code that can be handled via clang builtin or via pattern matching IR pass. All of libm for example. Some functions have both styles, some even get converted from clang builtin to libm call to llvm intrinsic.

I’m in favour of recognising function calls and translating them to IR intrinsics. This simplifies testing (via opt). It moves an optimisation out of clang and into an IR pass which feels right. It also means &sin works, though I know this to be forbidden.

As such I’m interested in your preference for doing this in clang, and whether it generalises to other magic library functions.



I think libc keeping the initial checks and using a builtin for the special memset (which can’t otherwise be expressed in straight C) is better because it’s not opaque. There’s only compiler magic where there needs to be, and no special recognition of semantics otherwise (which can be error-prone).

libm, in comparison, isn’t straightforward to understand when it e.g. uses a lookup table. In that case, teaching clang / LLVM about things like “sin creates a number in this range” seems good, because there’s no way we’d figure it out otherwise.