Skip to content

Cranelift: Correctly handle abi calculation for multi-part arguments #9509

Open
@bjorn3

Description

@bjorn3

Feature

When lowering a C or Rust type in a clif ir function signature, sometimes it is necessary to split it into multiple clif ir level parameters. For example #[repr(C)] struct F32Array { field0: [f32; 4] } would be split into f32, f32, f32, f32 on arm64. According to the ABI document for pretty much every architecture if at least one of these parts doesn't fit into an argument register anymore, the entire value has to be passed on the stack. Currently there is no way to tell Cranelift to handle this behavior.

Benefit

Required for rust-lang/rustc_codegen_cranelift#1525.

Implementation

@cfallin suggested a couple of options of which the option they preferred is:

put an abstraction in CLIF for "these values are allocated as a unit"; kind of a lightweight aggregate type, only in the signature and only used by the ABI code, so e.g. the group wouldn't otherwise be a first-class value

I also think this is the best option.

Alternatives

The alternatives @cfallin suggested are:

  • make aggregate types part of CLIF, and update Cranelift's ABI code to understand the platform-specific rules for them, like LLVM does
  • "pre-lower" into the needed form one level up. This is pretty ugly and implies knowledge of target platform in CLIF (beyond just datatype sizes as today) but could in principle be hacked together I think...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions