Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix argument ABI for overaligned structs on ppc64le #122781

Merged
merged 2 commits into from
Apr 8, 2024

Commits on Apr 8, 2024

  1. Fix argument ABI for overaligned structs on ppc64le

    When passing a 16 (or higher) aligned struct by value on ppc64le,
    it needs to be passed as an array of `i128` rather than an array
    of `i64`. This will force the use of an even starting register.
    
    For the case of a 16 byte struct with alignment 16 it is important
    that `[1 x i128]` is used instead of `i128` -- apparently, the
    latter will get treated similarly to `[2 x i64]`, not exhibiting
    the correct ABI. Add a `force_array` flag to `Uniform` to support
    this.
    
    The relevant clang code can be found here:
    https://github.com/llvm/llvm-project/blob/fe2119a7b08b6e468b2a67768904ea85b1bf0a45/clang/lib/CodeGen/Targets/PPC.cpp#L878-L884
    https://github.com/llvm/llvm-project/blob/fe2119a7b08b6e468b2a67768904ea85b1bf0a45/clang/lib/CodeGen/Targets/PPC.cpp#L780-L784
    
    I think the corresponding psABI wording is this:
    
    > Fixed size aggregates and unions passed by value are mapped to as
    > many doublewords of the parameter save area as the value uses in
    > memory. Aggregrates and unions are aligned according to their
    > alignment requirements. This may result in doublewords being
    > skipped for alignment.
    
    In particular the last sentence.
    
    Fixes rust-lang#122767.
    nikic committed Apr 8, 2024
    Configuration menu
    Copy the full SHA
    009280c View commit details
    Browse the repository at this point in the history
  2. force_array -> is_consecutive

    The actual ABI implication here is that in some cases the values
    are required to be "consecutive", i.e. must either all be passed
    in registers or all on stack (without padding).
    
    Adjust the code to either use Uniform::new() or Uniform::consecutive()
    depending on which behavior is needed.
    
    Then, when lowering this in LLVM, skip the [1 x i128] to i128
    simplification if is_consecutive is set. i128 is the only case
    I'm aware of where this is problematic right now. If we find
    other cases, we can extend this (either based on target information
    or possibly just by not simplifying for is_consecutive entirely).
    nikic committed Apr 8, 2024
    Configuration menu
    Copy the full SHA
    1b7342b View commit details
    Browse the repository at this point in the history