1137 Commits

Author SHA1 Message Date
Adwin White 6279106e72 fix all errors 2026-04-20 00:18:28 +08:00
teor dafb6bb801 Refactor FnDecl and FnSig flags into packed structs 2026-04-16 07:08:08 +10:00
Daniel Scherzer bd712bd224 CValue::zst() - add missing "ZST" in docs 2026-04-14 13:22:50 -07:00
Jacob Pratt 803a7227fb Rollup merge of #155005 - folkertdev:simd-element-type-llvm, r=nnethercote
preserve SIMD element type information

Preserve the SIMD element type and provide it to LLVM for better optimization.

This is relevant for AArch64 types like `int16x4x2_t`, see also https://github.com/llvm/llvm-project/issues/181514. Such types are defined like so:

```rust
#[repr(simd)]
struct int16x4_t([i16; 4]);

#[repr(C)]
struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
```

Previously this would be translated to the opaque `[2 x <8 x i8>]`, with this PR it is instead `[2 x <4 x i16>]`. That change is not relevant for the ABI, but using the correct type prevents bitcasts that can (indeed, do) confuse the LLVM pattern matcher.

This change will make it possible to implement the deinterleaving loads on AArch64 in a portable way (without neon-specific intrinsics), which means that e.g. Miri or the cranelift backend can run them without additional support.

discussion at [#t-compiler > loss of vector element type information](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/loss.20of.20vector.20element.20type.20information/with/584483611)
2026-04-14 00:37:24 -04:00
bors 338dff3e3a Auto merge of #136006 - oli-obk:push-tzonluoyuwkq, r=wesleywiser
Start using pattern types in libcore



cc rust-lang/rust#135996

Replaces the innards of `NonNull` with `*const T is !null`.

This does affect LLVM's optimizations, as now reading the field preserves the metadata that the field is not null, and transmuting to another type (e.g. just a raw pointer), will also preserve that information for optimizations. This can cause LLVM opts to do more work, but it's not guaranteed to produce better machine code.

Once we also remove all uses of rustc_layout_scalar_range_start from rustc itself, we can remove the support for that attribute entirely and handle all such needs via pattern types
2026-04-13 21:54:46 +00:00
Oli Scherer 834137afd7 Use !null pattern type in libcore 2026-04-13 17:23:03 +02:00
Jonathan Brouwer 2f607ee662 Rollup merge of #153997 - nnethercote:closure-consistency, r=petrochenkov
Use closures more consistently in `dep_graph.rs`.

This file has several methods that take a `FnOnce() -> R` closure:
- `DepGraph::with_ignore`
- `DepGraph::with_query_deserialization`
- `DepGraph::with_anon_task`
- `DepGraphData::with_anon_task_inner`

It also has two methods that take a faux closure via an `A` argument and a `fn(TyCtxt<'tcx>, A) -> R` argument:
- DepGraph::with_task
- DepGraphData::with_task

The rationale is that the faux closure exercises tight control over what state they have access to. This seems silly when (a) they are passed a `TyCtxt`, and (b) when similar nearby functions take real closures. And they are more awkward to use, e.g. requiring multiple arguments to be gathered into a tuple. This commit changes the faux closures to real closures.

r? @Zalathar
2026-04-13 14:02:35 +02:00
Folkert de Vries 6f428df8df preseve SIMD element type information
and provide it to LLVM for better optimization
2026-04-13 13:26:50 +02:00
Nicholas Nethercote 3ff4201fd1 Move rustc_middle::mir::mono to rustc_middle::mono
Because the things in this module aren't MIR and don't use anything
from `rustc_middle::mir`. Also, modules that use `mono` often don't use
anything else from `rustc_middle::mir`.
2026-04-07 08:33:54 +10:00
Nicholas Nethercote deb901c896 Use closures more consistently in dep_graph.rs.
This file has several methods that take a `FnOnce() -> R` closure:
- `DepGraph::with_ignore`
- `DepGraph::with_query_deserialization`
- `DepGraph::with_anon_task`
- `DepGraphData::with_anon_task_inner`

It also has two methods that take a faux closure via an `A` argument and
a `fn(TyCtxt<'tcx>, A) -> R` argument:
- DepGraph::with_task
- DepGraphData::with_task

The rationale is that the faux closure exercises tight control over what
state they have access to. This seems silly when (a) they are passed a
`TyCtxt`, and (b) when similar nearby functions take real closures. And
they are more awkward to use, e.g. requiring multiple arguments to be
gathered into a tuple. This commit changes the faux closures to real
closures.
2026-03-31 20:21:05 +11:00
Nicholas Nethercote ccc3c01162 Use Hcx/hcx consistently for StableHashingContext.
The `HashStable` and `ToStableHashKey` traits both have a type parameter
that is sometimes called `CTX` and sometimes called `HCX`. (In practice
this type parameter is always instantiated as `StableHashingContext`.)
Similarly, variables with these types are sometimes called `ctx` and
sometimes called `hcx`. This inconsistency has bugged me for some time.

The `HCX`/`hcx` form is more informative (the `H`/`h` indicates what
type of context it is) and it matches other cases like `tcx`, `dcx`,
`icx`.

Also, RFC 430 says that type parameters should have names that are
"concise UpperCamelCase, usually single uppercase letter: T". In this
case `H` feels insufficient, and `Hcx` feels better.

Therefore, this commit changes the code to use `Hcx`/`hcx` everywhere.
2026-03-31 20:16:57 +11:00
Guillaume Gomez 67ab3ac423 Rollup merge of #154043 - RalfJung:simd-min-max, r=Amanieu,calebzulawski,antoyo
simd_fmin/fmax: make semantics and name consistent with scalar intrinsics

This is the SIMD version of https://github.com/rust-lang/rust/pull/153343: change the documented semantics of the SIMD float min/max intrinsics to that of the scalar intrinsics, and also make the name consistent. The overall semantic change this amounts to is that we restrict the non-determinism: the old semantics effectively mean "when one input is an SNaN, the result non-deterministically is a NaN or the other input"; the new semantics say that in this case the other input must be returned. For all other cases, old and new semantics are equivalent. This means all users of these intrinsics that were correct with the old semantics are still correct: the overall set of possible behaviors has become smaller, no new possible behaviors are being added.

In terms of providers of this API:
- Miri, GCC, and cranelift already implement the new semantics, so no changes are needed.
- LLVM is adjusted to use `minimumnum nsz` instead of `minnum`, thus giving us the new semantics.

In terms of consumers of this API:
- Portable SIMD almost certainly wants to match the scalar behavior, so this is strictly a bugfix here.
- Stdarch mostly stopped using the intrinsic, except on nvptx, where arguably the new semantics are closer to what we actually want than the old semantics (https://github.com/rust-lang/stdarch/issues/2056).

Q: Should there be an `f` in the intrinsic name to indicate that it is for floats? E.g., `simd_fminimum_number_nsz`?

Also see https://github.com/rust-lang/rust/issues/153395.
2026-03-29 00:06:50 +01:00
Guillaume Gomez e6f17e4bbb Rollup merge of #153834 - N1ark:generic-float-intrinsics, r=tgross35,RalfJung
Merge `fabsf16/32/64/128` into `fabs::<F>`

Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.

Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!
2026-03-29 00:06:50 +01:00
bjorn3 a6e0f6a137 Merge commit '493d427c7d3423f085f05179e36a35b4943b1379' into sync_cg_clif-2026-03-25 2026-03-25 11:43:04 +01:00
Jonathan Brouwer fad2a35ebf Rollup merge of #154133 - bjorn3:va_list_drop_defer_codegen, r=nnethercote
Defer codegen for the VaList Drop impl to actual uses

This allows compiling libcore with codegen backends that don't actually implement VaList like cg_clif.
2026-03-24 10:54:04 +01:00
Jonathan Brouwer 6e6e266520 Rollup merge of #153857 - RalfJung:cfg-abi, r=Mark-Simulacrum
Rename `target.abi` to `target.cfg_abi` and enum-ify llvm_abiname

See [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/De-spaghettifying.20ABI.20controls/with/578893542) for more context. Discussed a bit in https://github.com/rust-lang/rust/pull/153769#discussion_r2934399038 too.

This renames `target.abi` to `target.cfg_abi` to make it less likely that someone will use it to determine things about the actual ccABI, i.e. the calling convention used on the target. `target.abi` does not control that calling convention, it just *sometimes* informs the user about that calling convention (and also about other aspects of the ABI).

Also turn llvm_abiname into an enum to make it more natural to match on.
Cc @workingjubilee @madsmtm
2026-03-23 12:14:54 +01:00
Ralf Jung 40ebcc031d target specs: rename abi to cfg_abi 2026-03-22 10:34:32 +01:00
bjorn3 0b69ff5074 Defer codegen for the VaList Drop impl to actual uses
This allows compiling libcore with codegen backends that don't actually
implement VaList like cg_clif.
2026-03-20 11:48:36 +01:00
Trevor Gross 16f89853f7 coretests: Expand ieee754 parsing and printing tests to f16
Use `float_test!` to cover all types, with a note about f128 missing the
traits.
2026-03-19 17:04:17 +00:00
Ralf Jung 986a280644 simd_fmin/fmax: make semantics and name consistent with scalar intrinsics 2026-03-18 15:17:56 +01:00
N1ark abb5228ec1 Merge fabsfN into fabs::<F>
Add `bounds::FloatPrimitive`

Exhaustive float pattern match

Fix GCC

use span bugs
2026-03-16 21:49:04 +00:00
bors 1e2183119f Auto merge of #153166 - reddevilmidzy:codegen-tidy, r=lcnr
Tidy: disallow TODO in other in-tree projects

Fixes: https://github.com/rust-lang/rust/issues/152280
MCP: https://github.com/rust-lang/compiler-team/issues/963

TODO

* [x] Add ci check to `cg_clif`: https://github.com/rust-lang/rustc_codegen_cranelift/pull/1632
* [x] Add ci check to `cg_gcc`: https://github.com/rust-lang/rustc_codegen_gcc/pull/861

r? lcnr
2026-03-15 20:38:45 +00:00
Ralf Jung c7220f423b rename min/maxnum intrinsics to min/maximum_number and fix their LLVM lowering 2026-03-15 14:53:00 +01:00
Nicholas Nethercote c12ab08c14 Move Spanned.
It's defined in `rustc_span::source_map` which doesn't make any sense
because it has nothing to do with source maps. This commit moves it to
the crate root, a more sensible spot for something this basic.
2026-03-11 06:25:23 +11:00
Redddy 50db919f5d Change TODO in compiler to FIXME 2026-03-07 12:12:33 +00:00
Ralf Jung 0fd3ac4c97 libcore float tests: replace macro shadowing by const-compatible macro 2026-03-06 12:07:25 +01:00
bors 64b72a1fa5 Auto merge of #150447 - WaffleLapkin:maybe-dangling-semantics, r=RalfJung
Implement `MaybeDangling` compiler support



Tracking issue: https://github.com/rust-lang/rust/issues/118166



cc @RalfJung
2026-03-05 12:21:27 +00:00
Waffle Lapkin 312055fad5 refactor PointeeInfo
Make `size`/`align` always correct rather than conditionally on the
`safe` field. This makes it less error prone and easier to work with for
`MaybeDangling` / potential future pointer kinds like `Aligned<_>`.
2026-03-05 11:53:38 +01:00
bjorn3 5aa980e6dc Replace CodegenResults with CompiledModules
This is already CodegenResults without CrateInfo. The driver can
calculate the CrateInfo and pass it by-ref to the backend. Using
CompiledModules makes it a bit easier to move some other things out of
the backend as will be necessary for moving LTO to the link phase.
2026-03-02 16:39:41 +00:00
bjorn3 a192c617ec Use CompiledModules inside CodegenResults
In preparation for fully replacing CodegenResults with CompiledModules.
2026-03-02 16:39:13 +00:00
Folkert de Vries 14d29f9ae2 Stabilize cfg_select 2026-02-22 19:59:25 +01:00
Jonathan Brouwer 90ac20f430 Rollup merge of #152799 - bjorn3:sync_cg_clif-2026-02-18, r=bjorn3
Subtree sync for rustc_codegen_cranelift

The highlight this time is a Cranelift update.

r? @ghost

@rustbot label +A-codegen +A-cranelift +T-compiler
2026-02-18 22:19:45 +01:00
bjorn3 14b7c8216e Format jit-helper.py 2026-02-18 15:22:36 +00:00
bjorn3 fb63550549 Fix broken merge 2026-02-18 15:10:37 +00:00
bjorn3 87ba622af7 Merge commit 'abdb98ad4b47117ee3be17b1e43fab34f18f5805' into sync_cg_clif-2026-02-18 2026-02-18 15:02:27 +00:00
Camille Gillot 6d4b1b38e7 Remove ShallowInitBox. 2026-02-17 11:25:50 +00:00
Stuart Cook 331a785f81 Rollup merge of #152512 - okaneco:exact_integer, r=tgross35
core: Implement feature `float_exact_integer_constants`

Accepted ACP - https://github.com/rust-lang/libs-team/issues/713#issuecomment-3880122239
Tracking issue - https://github.com/rust-lang/rust/issues/152466

Implement accepted ACP for `MAX_EXACT_INTEGER` and `MIN_EXACT_INTEGER` on `f16`, `f32`, `f64`, and `f128`
Add tests to `coretests/tests/floats/mod.rs`
2026-02-17 13:02:22 +11:00
okaneco 7be024fc06 [cg_clif]: Fix codegen of f128 to i128 casts
Correct name for intrinsic that converts f128 to u128
Use `to_signed` instead of `from_signed` to ensure proper intrinsic
selected for u128/i128
2026-02-16 16:29:36 -05:00
bors 3c9faa0d03 Auto merge of #148190 - RalfJung:box_new, r=RalfJung
replace box_new with lower-level intrinsics

The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).

This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.

To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)

See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.

This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.

I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.

### `vec!` FAQ

- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
2026-02-16 18:46:10 +00:00
Ralf Jung 5e65109f21 add write_box_via_move intrinsic and use it for vec!
This allows us to get rid of box_new entirely
2026-02-16 17:27:40 +01:00
Trevor Gross 83794755b7 clif: Only set has_reliable_f128_math with glibc
New float tests in core are failing on clif with issues like the
following:

    Undefined symbols for architecture arm64:
        "_coshf128", referenced from:
            __RNvMNtCshY0fR2o0hOA_3std4f128C4f1284coshCs5TKtJxXQNGL_9coretests in coretests-e38519c0cc90db54.coretests.44b6247a565e10d1-cgu.10.rcgu.o
                "_exp2f128", referenced from:
            __RNvMNtCshY0fR2o0hOA_3std4f128C4f1284exp2Cs5TKtJxXQNGL_9coretests in coretests-e38519c0cc90db54.coretests.44b6247a565e10d1-cgu.10.rcgu.o
        ...

Disable f128 math unless the symbols are known to be available, which
for now is only glibc targets. This matches the LLVM backend.
2026-02-15 18:00:54 +00:00
xonx 2c1d605f21 unify and deduplicate floats 2026-02-15 18:00:41 +00:00
Jacob Pratt 202f102914 Rollup merge of #152573 - usamoi:escape-2, r=bjorn3
move `escape_symbol_name` to `cg_ssa`

followup of rust-lang/rust#151955

r? @bjorn3
2026-02-13 22:26:33 -05:00
Jonathan Brouwer 65d982abd8 Rollup merge of #152469 - mu001999-contrib:cleanup/unused-features, r=nadrieril,jdonszelmann
Remove unused features

Detected by https://github.com/rust-lang/rust/pull/152164.

~~Only allow `unused_features` if there are complex platform-specific features enabled.~~
2026-02-13 13:34:58 +01:00
usamoi 4796ff1bf5 move escape_symbol_name to cg_ssa 2026-02-13 20:31:18 +08:00
mu001999 a07f837491 Remove unused features in compiler 2026-02-13 09:25:39 +08:00
bjorn3 1106018af0 Use cg_ssa's produce_final_output_artifacts in cg_clif 2026-02-11 12:36:19 +00:00
bjorn3 d2a0557afb Convert to inline diagnostics in all codegen backends 2026-02-04 13:12:49 +00:00
bors 75963ce795 Auto merge of #151065 - nagisa:add-preserve-none-abi, r=petrochenkov
abi: add a rust-preserve-none calling convention

This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature.

For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:

    foo:
        push r12
        ; do things
        pop r12
        jmp next_step

This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.

I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)
2026-01-25 02:49:32 +00:00
Matthias Krüger 3a69035338 Rollup merge of #151346 - folkertdev:simd-splat, r=workingjubilee
add `simd_splat` intrinsic

Add `simd_splat` which lowers to the LLVM canonical splat sequence.

```llvm
insertelement <N x elem> poison, elem %x, i32 0
shufflevector <N x elem> v0, <N x elem> poison, <N x i32> zeroinitializer
```

Right now we try to fake it using one of

```rust
fn splat(x: u32) -> u32x8 {
    u32x8::from_array([x; 8])
}
```

or (in `stdarch`)

```rust
fn splat(value: $elem_type) -> $name {
    #[derive(Copy, Clone)]
    #[repr(simd)]
    struct JustOne([$elem_type; 1]);
    let one = JustOne([value]);
    // SAFETY: 0 is always in-bounds because we're shuffling
    // a simd type with exactly one element.
    unsafe { simd_shuffle!(one, one, [0; $len]) }
}
```

Both of these can confuse the LLVM optimizer, producing sub-par code. Some examples:

- https://github.com/rust-lang/rust/issues/60637
- https://github.com/rust-lang/rust/issues/137407
- https://github.com/rust-lang/rust/issues/122623
- https://github.com/rust-lang/rust/issues/97804

---

As far as I can tell there is no way to provide a fallback implementation for this intrinsic, because there is no `const` way of evaluating the number of elements (there might be issues beyond that, too). So, I added implementations for all 4 backends.

Both GCC and const-eval appear to have some issues with simd vectors containing pointers. I have a workaround for GCC, but haven't yet been able to make const-eval work. See the comments below.

Currently this just adds the intrinsic, it does not actually use it anywhere yet.
2026-01-24 21:04:15 +01:00