Skip to content

Conversation

@luismgsilva
Copy link
Member

@luismgsilva luismgsilva commented Oct 27, 2025

This patch creates a new lto section that serializes all the APEX intrinsics information
registered during GCC run-time. Once lto1 is invoked, this section is read and the
APEX intrinsics are re-registered.

A simple approach could be as follow:

  1. Before looking into the GIMPLE representation tree, we store the intrinsic information
    in the backend and generate a dummy function declaration.
  2. When lto1 is checking in the backend for the availability of the intrinsic
    (using the function code) it would find the dummy declaration.
  3. Only after this validation GCC creates the actual fndecl from the GIMPLE representation
    to be used for the expand.

This approach works for single compilation unit. If we have multiple compilation units,
each with different APEX intrinsics (or same ones, but different registered order) the
fncode of each fndecl will overlap.

Example:

  • Imagine that we have a foo in file1.c and bar in file2.c. In each fndecl the
    fncode would be 0.
  • When these files are used in lto1 and we register a dummy intrinsic for each, the
    intrinsic validation would use the same fndecl to validate both - we are not able to
    distinguish which one is which from the fncode.

This patch's approach:

  • We have to trick GCC to think that the intrinsic is available before its actually registered.
  • It will then create the fndecl from the GIMPLE representation.
  • The intrinsic registration is only handled after the GIMPLE representation and only after
    all fndecl have been restored.
  • This way, we can safely search for the fndecl of the given APEX intrinsic and change its
    fncode to match what we are storing in the backend.

Each APEX intrinsic fncode (which is used as index in the arcv_apex_builtins[]) will have
the correct corresponding fndecl associated with it.

Other comments:
The read and write routines were initially in gcc/ folder among other ipa-* files.
Since this implementation is riscv specific, I've decided to move it to the backend files.

Testing:
We are currently using a single .exp file to run both regular tests and lto tests. This can
be sperated in two .exp files (e.g., apex.exp and apex-lto.exp) if we decide so.
Validating lto error messages does not work as expected. Patch removed from this PR. - Fixed.

@luismgsilva luismgsilva self-assigned this Oct 27, 2025
@luismgsilva luismgsilva force-pushed the luis/apex-lto branch 8 times, most recently from d3468a6 to 5f0ea4b Compare October 29, 2025 18:37
@luismgsilva luismgsilva marked this pull request as ready for review October 29, 2025 19:22
@luismgsilva luismgsilva changed the title tmp: arcv: apex: lto fix. arcv: apex: Fix LTO Oct 30, 2025
@luismgsilva luismgsilva force-pushed the luis/apex-lto branch 3 times, most recently from e9d1183 to 8a27ac6 Compare October 30, 2025 16:15
@luismgsilva luismgsilva changed the title arcv: apex: Fix LTO arcv: apex: Add LTO support for APEX intrinsics. Oct 30, 2025
Comment on lines +376 to +381

case RISCV_BUILTIN_APEX:
/* Trick GCC to think that the function is defined.
The actual fndecl used is created after this
validation from the GIMPLE representation in LTO. */
return integer_zero_node;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't let this prevent you from merging it now. But this is probably not a good long-term solution. Should we ask the community what a better solution could be?

Copy link
Member Author

@luismgsilva luismgsilva Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I also don't like this approach, and I doubt it would be accepted upstream. Although, I don't see a proper solution to identify the correct intrinsic by only the function code. Because with multiple compilation units, these fncodes might overlap.

APEX (ARC Processor Extension) intrinsics are registered dynamically
via #pragma intrinsic directives rather than being statically defined.
This creates a challenge for LTO where intrinsic definitions from
different translation units must be preserved and made available during
link-time optimization.

This patch implements LTO serialization for APEX intrinsics by:

1. Creating a dedicated .gnu.lto_riscv_apex section to store APEX
   intrinsic metadata (name, mnemonic, opcode, instruction formats)
2. Writing all registered APEX intrinsics during the compilation phase
3. Reading and re-registering all APEX intrinsics during the LTO phase
4. Integrating with the LTO streamer infrastructure

Without this support, LTO would lose APEX intrinsic definitions,
causing "unavailable intrinsics" errors during link-time optimization.

Signed-off-by: Luis Silva <luiss@synopsys.com>
This patch adds new DejaGnu test directives to scan assembly output
from LTRANS units during LTO compilation.  These procedures enable
testing of code generation in the LTRANS phase, which is essential
for verifying that target-specific features are correctly preserved
through the LTO pipeline.

The new directives scan .ltrans*.s files produced during LTO
compilation:

- scan-ltrans-assembler: Checks if a pattern exists in any LTRANS
  assembly file for the current test
- scan-ltrans-assembler-times: Verifies a pattern appears exactly
  N times across all LTRANS assembly files

Signed-off-by: Luis Silva <luiss@synopsys.com>
The LTO test framework lacked support for testing expected link-time
errors.  Tests could use dg-lto-warning and dg-lto-message for
diagnostics emitted during compilation, but there was no way to verify
that certain code patterns correctly fail at link time under LTO.

This patch adds dg-lto-error directive support, allowing tests to:

1. Mark expected link failures with dg-lto-error directives
2. Pass when the link fails as expected (no executable created or
   linker errors present)
3. Fail when the link succeeds but should have failed
4. Skip execution tests when link failure is expected

The implementation tracks dg-lto-error presence via a global flag and
performs custom link result checking when link failure is expected,
rather than using the standard check_compile reporting.

Signed-off-by: Luis Silva <luiss@synopsys.com>
This patch adds tests for LTO support of APEX intrinsics,
including both positive and negative test cases.

The testsuite validates that APEX intrinsics declared via #pragma
intrinsic directives in different translation units are correctly
serialized, merged, and made available during link-time optimization.

Test coverage includes:

1. Conflict Detection Tests (arcv-apex-lto-err*):
   - Opcode mismatch detection across compilation units
   - Instruction name mismatch detection
   - Instruction format mismatch detection
   - Multiple simultaneous conflicts

2. Successful LTO Tests (arcv-apex-lto-test*):
   - Multiple instruction formats (XD, XS, XI, XC) across files
   - Partial overlap of intrinsics between translation units
   - Different pragma declaration orders

All tests verify that:
- APEX intrinsic calls survive LTO optimization
- Correct .extInstruction directives are emitted
- Proper assembly instructions are generated
- Conflicting definitions produce appropriate diagnostics

Signed-off-by: Luis Silva <luiss@synopsys.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants