about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/abi.rs
AgeCommit message (Collapse)AuthorLines
2024-05-09Make builtin_deref just return a TyMichael Goulet-1/+1
2024-04-25Auto merge of #121298 - nikic:writable, r=cuviperbors-0/+13
Set writable and dead_on_unwind attributes for sret arguments Set the `writable` and `dead_on_unwind` attributes for `sret` arguments. This allows call slot optimization to remove more memcpy's. See https://llvm.org/docs/LangRef.html#parameter-attributes for the specification of these attributes. In short, the statement we're making here is that: * The return slot is writable. * The return slot will not be read if the function unwinds. Fixes https://github.com/rust-lang/rust/issues/90595.
2024-04-25Set writable and dead_on_unwind attributes for sret argumentsNikita Popov-0/+13
2024-04-24Auto merge of #122053 - erikdesjardins:alloca, r=nikicbors-1/+1
Stop using LLVM struct types for alloca The alloca type has no semantic meaning, only the size (and alignment, but we specify it explicitly) matter. Using `[N x i8]` is a more direct way to specify that we want `N` bytes, and avoids relying on LLVM's struct layout. It is likely that a future LLVM version will change to an untyped alloca representation. Split out from #121577. r? `@ghost`
2024-04-11use [N x i8] for alloca typesErik Desjardins-1/+1
2024-04-11Put `PlaceValue` into `OperandValue::Ref`, rather than 3 tuple fieldsScott McMurray-3/+8
2024-04-11Make `PlaceRef` hold a `PlaceValue` for the non-layout fields (like ↵Scott McMurray-1/+1
`OperandRef` does)
2024-04-08force_array -> is_consecutiveNikita Popov-1/+4
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).
2024-04-08Fix argument ABI for overaligned structs on ppc64leNikita Popov-1/+1
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 https://github.com/rust-lang/rust/issues/122767.
2024-03-17make PassMode::Cast consistently copy between Rust/ABI representationErik Desjardins-41/+27
Previously, we did this slightly incorrectly for return values, and didn't do it at all for arguments.
2024-03-17make CastTarget::size and CastTarget::llvm_type consistent, removeErik Desjardins-28/+24
special case that's not present in Clang Making the methods consistent doesn't require much justification. It's required for us to generate correct code. The special case was present near the end of `CastTarget::llvm_type`, and resulted in the final integer component of the ABI type being shrunk to the smallest integer that fits. You can see this in action here (https://godbolt.org/z/Pe73cr91d), where, for a struct with 5 u16 elements, rustc generates `{ i64, i16 }`, while Clang generates `[2 x i64]`. This special case was added a long time ago, when the function was originally written [1]. That commit consolidated logic from many backends, and in some of the code it deleted, sparc64 [2] and powerpc64 [3] had similar special cases. However, looking at Clang today, it doesn't have this special case for sparc64 (https://godbolt.org/z/YaafvYWdf) or powerpc64 (https://godbolt.org/z/5c3YePTje), so this change just removes it. [1]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-183c4dadf10704bd1f521b71f71d89bf755c9603a93f894d66c03bb1effc6021R231 [2]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-2d8f87ea6db6d7f0a6fbeb1d5549adc07e93331278d951a1e051a40f92914436L163-L166 [3]: https://github.com/rust-lang/rust/commit/f0636b61c7f84962a609e831760db9d77f4f5e14#diff-88af4a9df9ead503a5c7774a0455d270dea3ba60e9b0ec1ce550b4c53d3bce3bL172-L175
2024-03-11copy byval argument to alloca if alignment is insufficientErik Desjardins-49/+55
2024-03-05use [N x i8] for byval/sret typesErik Desjardins-4/+16
This avoids depending on LLVM's struct types to determine the size of the byval/sret slot.
2024-01-30Remove the `abi_amdgpu_kernel` featureclubby789-1/+0
2023-12-15Separate immediate and in-memory ScalarPair representationNikita Popov-2/+2
Currently, we assume that ScalarPair is always represented using a two-element struct, both as an immediate value and when stored in memory. This currently works fairly well, but runs into problems with https://github.com/rust-lang/rust/pull/116672, where a ScalarPair involving an i128 type can no longer be represented as a two-element struct in memory. For example, the tuple `(i32, i128)` needs to be represented in-memory as `{ i32, [3 x i32], i128 }` to satisfy alignment requirement. Using `{ i32, i128 }` instead will result in the second element being stored at the wrong offset (prior to LLVM 18). Resolve this issue by no longer requiring that the immediate and in-memory type for ScalarPair are the same. The in-memory type will now look the same as for normal struct types (and will include padding filler and similar), while the immediate type stays a simple two-element struct type. This also means that booleans in immediate ScalarPair are now represented as i1 rather than i8, just like we do everywhere else. The core change here is to llvm_type (which now treats ScalarPair as a normal struct) and immediate_llvm_type (which returns the two-element struct that llvm_type used to produce). The rest is fixing things up to no longer assume these are the same. In particular, this switches places that try to get pointers to the ScalarPair elements to use byte-geps instead of struct-geps.
2023-12-10remove redundant importssurechen-1/+0
detects redundant imports that can be eliminated. for #117772 : In order to facilitate review and modification, split the checking code and removing redundant imports code into two PR.
2023-11-21Fix `clippy::needless_borrow` in the compilerNilstrieb-1/+1
`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`. Then I had to remove a few unnecessary parens and muts that were exposed now.
2023-11-03move ABI sanity check from LLVM codegen backend to ABI computation logicRalf Jung-40/+3
2023-10-27Link to correct issue in PassMode::Direct ptx-kernel exceptionKjetil Kjeka-1/+1
2023-10-27Documentation and error message improvements related to PassMode::Direct assertKjetil Kjeka-2/+2
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
2023-10-26NVPTX: Allow PassMode::Direct for ptx kernels for nowKjetil Kjeka-1/+6
2023-09-15cannot have Direct for unsized typesRalf Jung-0/+5
2023-09-15clarify PassMode::Indirect as wellRalf Jung-15/+20
2023-09-15explain PassMode::CastRalf Jung-8/+10
2023-09-08the wasm ABI behavior is a bugRalf Jung-9/+6
2023-09-07extend comments around PassMode::DirectRalf Jung-1/+41
2023-08-26Use `preserve_mostcc` for `extern "rust-cold"`Scott McMurray-1/+3
As experimentation in 115242 has shown looks better than `coldcc`. And *don't* use a different convention for cold on Windows, because that actually ends up making things worse. cc tracking issue 97544
2023-08-08feat: `riscv-interrupt-{m,s}` calling conventionsSeth Pellegrino-2/+7
Similar to prior support added for the mips430, avr, and x86 targets this change implements the rough equivalent of clang's [`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling e.g. ```rust static mut CNT: usize = 0; pub extern "riscv-interrupt-m" fn isr_m() { unsafe { CNT += 1; } } ``` to produce highly effective assembly like: ```asm pub extern "riscv-interrupt-m" fn isr_m() { 420003a0: 1141 addi sp,sp,-16 unsafe { CNT += 1; 420003a2: c62a sw a0,12(sp) 420003a4: c42e sw a1,8(sp) 420003a6: 3fc80537 lui a0,0x3fc80 420003aa: 63c52583 lw a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0> 420003ae: 0585 addi a1,a1,1 420003b0: 62b52e23 sw a1,1596(a0) } } 420003b4: 4532 lw a0,12(sp) 420003b6: 45a2 lw a1,8(sp) 420003b8: 0141 addi sp,sp,16 420003ba: 30200073 mret ``` (disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`) This outcome is superior to hand-coded interrupt routines which, lacking visibility into any non-assembly body of the interrupt handler, have to be very conservative and save the [entire CPU state to the stack frame][full-frame-save]. By instead asking LLVM to only save the registers that it uses, we defer the decision to the tool with the best context: it can more accurately account for the cost of spills if it knows that every additional register used is already at the cost of an implicit spill. At the LLVM level, this is apparently [implemented by] marking every register as "[callee-save]," matching the semantics of an interrupt handler nicely (it has to leave the CPU state just as it found it after its `{m|s}ret`). This approach is not suitable for every interrupt handler, as it makes no attempt to e.g. save the state in a user-accessible stack frame. For a full discussion of those challenges and tradeoffs, please refer to [the interrupt calling conventions RFC][rfc]. Inside rustc, this implementation differs from prior art because LLVM does not expose the "all-saved" function flavor as a calling convention directly, instead preferring to use an attribute that allows for differentiating between "machine-mode" and "superivsor-mode" interrupts. Finally, some effort has been made to guide those who may not yet be aware of the differences between machine-mode and supervisor-mode interrupts as to why no `riscv-interrupt` calling convention is exposed through rustc, and similarly for why `riscv-interrupt-u` makes no appearance (as it would complicate future LLVM upgrades). [clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v [full-frame-save]: https://github.com/esp-rs/esp-riscv-rt/blob/9281af2ecffe13e40992917316f36920c26acaf3/src/lib.rs#L440-L469 [implemented by]: https://github.com/llvm/llvm-project/blob/b7fb2a3fec7c187d58a6d338ab512d9173bca987/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp#L61-L67 [callee-save]: https://github.com/llvm/llvm-project/blob/973f1fe7a8591c7af148e573491ab68cc15b6ecf/llvm/lib/Target/RISCV/RISCVCallingConv.td#L30-L37 [rfc]: https://github.com/rust-lang/rfcs/pull/3246
2023-07-29cg_llvm: remove pointee types and pointercast/bitcast-of-ptrErik Desjardins-13/+4
2023-07-05Move `TyCtxt::mk_x` to `Ty::new_x` where applicableBoxy-1/+1
2023-01-17Remove double spaces after dots in commentsMaybe Waffle-1/+1
2023-01-04cleanup: handle -Zmutable-noalias like -Zbox-noaliasErik Desjardins-10/+0
2022-11-11Improve generating Custom entry functionAyush Singh-17/+23
This commit is aimed at making compiler generated entry functions (Basically just C `main` right now) more generic so other targets can do similar things for custom entry. This was initially implemented as part of https://github.com/rust-lang/rust/pull/100316. Currently, this moves the entry function name and Call convention to the target spec. Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
2022-10-01Merge apply_attrs_callsite into call and invokebjorn3-4/+0
Some codegen backends are not able to apply callsite attrs after the fact.
2022-09-09Rollup merge of #99207 - 5225225:msan-eager-checks, r=jackh726Matthias Krüger-0/+8
Enable eager checks for memory sanitizer Fixes #99179
2022-08-26Move `ArgAbi::pad_i32` into `PassMode::Cast`.Nicholas Nethercote-19/+20
Because it's only needed for that variant. This shrinks the types and clarifies the logic.
2022-08-26Turn `ArgAbi::pad` into a `bool`.Nicholas Nethercote-4/+4
Because it's only ever set to `None` or `Some(Reg::i32())`.
2022-08-26Simplify arg capacity calculations.Nicholas Nethercote-5/+2
Currently they try to be very precise. But they are wrong, i.e. they don't match what's happening in the loop below. This code isn't hot enough for it to matter that much.
2022-08-26Change `FnAbi::args` to a boxed slice.Nicholas Nethercote-2/+2
2022-08-26Change `FnAbi::fixed_count` to a `u32`.Nicholas Nethercote-1/+2
2022-08-26Box `CastTarget` within `PassMode`.Nicholas Nethercote-25/+21
Because `PassMode::Cast` is by far the largest variant, but is relatively rare. This requires making `PassMode` not impl `Copy`, and `Clone` is no longer necessary. This causes lots of sigil adjusting, but nothing very notable.
2022-08-14Emit noundef even for unoptimised code if msan is on5225225-0/+8
2022-07-27Add elementtype attributes for llvm.arm.ldrex/strex intrinsicsNikita Popov-0/+16
These intrinsics (and a few more, but there are the only ones exposed by stdarch) require an elementtype attribute in LLVM 15.
2022-07-13Rename `debugging_opts` to `unstable_opts`Joshua Nelson-1/+1
This is no longer used only for debugging options (e.g. `-Zoutput-width`, `-Zallow-features`). Rename it to be more clear.
2022-05-30Add support for emitting functions with `coldcc` in LLVMScott McMurray-0/+1
The eventual goal is to try using this for things like the internal panicking stuff, to see whether it helps.
2022-04-05Mark scalar layout unions so that backends that do not support partially ↵Oli Scherer-2/+2
initialized scalars can special case them.
2022-03-03Pass LLVM string attributes as string slicesTomasz Miąsko-2/+1
2022-02-26just put smallvec lengths in the signatureErik Desjardins-5/+2
2022-02-26Add LLVM attributes in batches instead of individuallyErik Desjardins-129/+85
This should improve performance.
2022-02-26Auto merge of #94127 - erikdesjardins:debugattr, r=nikicbors-49/+60
At opt-level=0, apply only ABI-affecting attributes to functions This should provide a small perf improvement for debug builds, and should more than cancel out the perf regression from adding noundef (https://github.com/rust-lang/rust/pull/93670#issuecomment-1038347581, #94106). r? `@nikic`