On Fri, 5 Jun 2026, Robin Dapp wrote:

> >>> Please give an overview of what APEX is and why LTO currently
> >>> cannot handle it.
> >>>
> >>> Richard.
> >
> >> Luis, is the problem just that we need consistent builtin numbering (which
> >> requires special care with dynamically enabled builtins but should still be
> >> possible) or is there more to it?
> >
> >> --
> >> Regards
> >>  Robin
> >
> > Hi Richard, Robin,
> >
> > APEX (ARC Processor EXtension) is a mechanism for integrating custom
> > instructions into GCC without requiring users to have detailed knowledge of
> > compiler internals.  It allows users to define custom instructions via C 
> > pragmas
> > and assembler directives.
> >
> > A function prototype is used to represent a custom instruction, and a pragma
> > binds it to instruction metadata (e.g., mnemonic, opcode), effectively 
> > making it
> > behave like a builtin:
> >
> > ```c
> > int foo_func (int, int);
> > #pragma intrinsic (foo_func, "foo", 7, XD)
> >
> > int main (void)
> > {
> >   return foo_func (1, 2);
> > }
> > ```
> >
> > which generate:
> > ```asm
> > .extInstruction foo,7,XD
> > main:
> >   li    a5,2
> >   li    a0,1
> >   foo   a0,a0,a5    # APEX instruction
> >   ret
> > ```
> >
> > The issue with LTO is that APEX intrinsics are registered dynamically during
> > front-end processing via pragmas. This registration state is not preserved
> > through LTO.
> >
> > By the time LTO reads the serialized GIMPLE back in, the original pragma
> > processing phase has already completed, so the backend no longer has any 
> > record
> > of the intrinsic definition (mnemonic, opcode, operand constraints).  As a
> > result, the call cannot be resolved against any known intrinsic entry, 
> > leading
> > to an ICE during validation.
> >
> > In response to Robin’s question: it is a bit more than just builtin 
> > numbering.
> >
> > It is not only about having a stable identifier across LTO, but also about
> > preserving and restoring the intrinsic registration itself.  Even with 
> > consistent
> > numbering, the backend still lacks the metadata required to reconstruct the
> > intrinsic after LTO.
> 
> But we do know all possible intrinsics, statically?

I don't read it this way.

> Can't we (dummy) "initialize" them so there are placeholders to fall back to?
> 
> I haven't looked in detail (sorry) and just saw the "trick GCC into" which 
> might already indicate something like that?

The GCC canonical way of doing what APEX does would be

extern inline __attribute__((gnu_inline))
int foo_func (int a, int b)
{
  int res;
  __asm__ (".byte 7, XD" : "=r" (res) : "r" (a), "r" (b));
  return res;
}

and I'd implement "fancy" (producing the appropriate register operand
mnemonic piece) via output templates and assembler extensions.

No need for #pragma or anything, it's just GCC extended asm and
function-as-a-macro extension.  This should all work with LTO
already.

Richard.

Reply via email to