[libvirt PATCH] meson: stop CLang doing inter-procedural analysis

Peter Krempa pkrempa at redhat.com
Fri Mar 17 15:01:05 UTC 2023


On Thu, Mar 16, 2023 at 13:05:43 +0000, Daniel P. Berrangé wrote:
> The virNumaNodeIsAvailable function is stubbed out when building
> without libnuma, such that it just returns a constant value. When
> CLang is optimizing, it does inter-procedural analysis across
> function calls. When it sees that the call to virNumaNodeIsAvailable
> returns a fixed constant, it elides the conditional check for errors
> in the callers such as virNumaNodesetIsAvailable.
> 
> This is a valid optimization as the C standard declares that there
> must only be one implementation of each function in a binary. This
> is normally the case, but ELF allows for function overrides when
> linking or at runtime with LD_PRELOAD, which is technically outside
> the mandated C language behaviour.
> 
> So while CLang's optimization works fine at runtime, it breaks in our
> test suite which aims to mock the virNumaNodeIsAvailable function so
> that it has specific semantics regardless of whether libnuma is built
> or not. The return value check optimization though means our mock
> override won't have the right effect. The mock will be invoked, but
> its return value is not used.
> 
> Potentially the same problem could be exhibited with GCC if certain
> combinations of optimizations are enabled, though thus far we've
> not seen it.
> 
> To be robust on both CLang and GCC we need to make it more explicit
> that we want to be able to replace functions and thus optimization
> of calls must be limited. Currently we rely on 'noinline' which
> does succesfully prevent inlining of the function, but it cannot
> stop the eliding of checks based on the constant return value.
> Thus we need a bigger hammer.
> 
> There are a couple of options to disable this optimization:
> 
>  * Annotate a symbol as 'weak'. This is tells the compiler
>    that the symbol is intended to be overridable at linktime
>    or runtime, and thus it will avoid doing inter-procedural
>    analysis for optimizations. This was tried previously but
>    have to be reverted as it had unintended consequences
>    when linking .a files into our final .so, resulting in all
>    the weak symbol impls being lost. See commit
>    407a281a8e2b6c5078ba1148535663ea64fd9314
> 
>  * Annotate a symbol with 'noipa'. This tells the compiler
>    to avoid inter-procedural analysis for calls to just this
>    function. This wold be ideal match for our scenario, but
>    unfortunately it is only implemented for GCC currently:
> 
>      https://reviews.llvm.org/D101011
> 
>  * The '-fsemantic-interposition' argument tells the optimizer
>    that any functions may be replaced with alternative
>    implementations that have different semantics. It thus
>    blocks any optimizations across function calls. This is
>    quite a harsh block on the optimizer, but it appears to be
>    the only one that is viable with CLang.
> 
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>  meson.build | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)

Repeating approval from the MR.

Reviewed-by: Peter Krempa <pkrempa at redhat.com>


More information about the libvir-list mailing list