[llvm-dev] [IR] GlobalIFunc with declaration as resolver

Itay Bookstein via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 12 08:39:51 PST 2021


Hi all,

We've had a lengthy discussion in [1] regarding GlobalIFunc whose
resolver is a declaration, and I wanted to get wider feedback for the
IR-level semantics.

The ELF object file semantics require the resolver to be defined in
the same TU as the ifunc [2] and Clang and GCC require the same when
using 'plain' attribute((ifunc("..."))), diagnosing that it must be a
defined function [3]. The same applies for aliases and their aliasees.
The LLVM Verifier requires that aliasees not be declarations [4], but
the same currently does not hold for GlobalIFunc (Verifier code for
GlobalIFunc was added in [1], defined-check was reverted due to
breaking CFE attribute cpu_specific).

The implementation of attributes cpu_dispatch and cpu_specific in CFE
currently depends on GlobalIFunc with a declaration for a resolver, in
the case when cpu_specific is specified in a TU and cpu_dispatch is
not. Trunk currently has broken codegen for references against such
ifuncs in the same TU [5], but there's reference to a downstream
(codegen-level?) patch which could fix it [6]. I don't know what
semantics the patch implements, but two options come to mind:
* Replace uses of GlobalIFunc with result of call to resolver; this
can work only in code, not in gvar initializers, and it nullifies
benefit of using an ifunc.
* 'downgrade' GlobalIFunc to a function declaration, dropping
'connection' to resolver (valid only when it has odr linkage? didn't
think this through). This creates a small representational redundancy
(ifunc with undefined resolver ~== func decl).

A different approach is to declare GlobalIFunc with undefined resolver
to be invalid IR, and thus bring it in line with the very similar
construct of GlobalAlias. This would necessitate a change to the
implementation of cpu_specific/cpu_dispatch to avoid breaking support
for defining them in separate TUs. A problem with that is that it
creates an issue similar to [7], where CFE would sometimes need to
emit a function declaration and later 'upgrade' it to a GlobalIFunc
upon encountering cpu_dispatch. CFE devs wish to avoid introducing
additional RAUW module mutations in this way. My understanding is that
this is because it harms incremental compilation scenarios, but I
don't know the full technical aspects of this.

~ Itay

[1] https://reviews.llvm.org/D112349
[2] https://sourceware.org/glibc/wiki/GNU_IFUNC
[3] https://github.com/llvm/llvm-project/blob/99d5cbbd7e33b620f5f4725ffa04ce15d2794a14/clang/lib/CodeGen/CodeGenModule.cpp#L345
[4] https://github.com/llvm/llvm-project/blob/99d5cbbd7e33b620f5f4725ffa04ce15d2794a14/llvm/lib/IR/Verifier.cpp#L785
[5] https://reviews.llvm.org/D112349#3109211
[6] https://reviews.llvm.org/D112349#3116519
[7] https://github.com/llvm/llvm-project/blob/05f34ffa216975f132fa1bd4cbf8424053a19147/clang/lib/CodeGen/CodeGenModule.cpp#L4971-L4982

-- 
This e-mail message and any attachments thereto are intended only for the 
person or entity to which it is addressed and may contain confidential 
and/or privileged material. Any retransmission, dissemination, copying or 
other use of, or taking of any action in reliance upon this information is 
prohibited. If you are not the intended addressee, please contact the 
sender immediately and delete the materials and information from your 
device and system and confirm the deletion by reply e-mail.


More information about the llvm-dev mailing list