171 Commits

Author SHA1 Message Date
bors
20f1c045c4 Auto merge of #148721 - Zalathar:rollup-398va3y, r=Zalathar
Rollup of 22 pull requests

Successful merges:

 - rust-lang/rust#128666 (Add `overflow_checks` intrinsic)
 - rust-lang/rust#146305 (Add correct suggestion for multi-references for self type in method)
 - rust-lang/rust#147179 ([DebugInfo] Fix container types failing to find template args)
 - rust-lang/rust#147743 (Show packed field alignment in mir_transform_unaligned_packed_ref)
 - rust-lang/rust#148079 (Rename `downcast_[ref|mut]_unchecked` -> `downcast_unchecked_[ref|mut]`)
 - rust-lang/rust#148084 (Optimize path components iteration on platforms that don't have prefixes)
 - rust-lang/rust#148126 (Fix rust stdlib build failing for VxWorks)
 - rust-lang/rust#148204 (Modify contributor email entries in .mailmap)
 - rust-lang/rust#148279 (rustc_builtin_macros: rename bench parameter to avoid collisions with user-defined function names)
 - rust-lang/rust#148333 (constify result unwrap unchecked)
 - rust-lang/rust#148539 (Add Allocator proxy impls for Box, Rc, and Arc)
 - rust-lang/rust#148601 (`invalid_atomic_ordering`: also lint `update` & `try_update`)
 - rust-lang/rust#148612 (Add note for identifier with attempted hygiene violation)
 - rust-lang/rust#148613 (Switch hexagon targets to rust-lld)
 - rust-lang/rust#148619 (Enable std locking functions on AIX)
 - rust-lang/rust#148644 ([bootstrap] Make `--open` option work with `doc src/tools/error_index_generator`)
 - rust-lang/rust#148649 (don't completely reset `HeadUsages`)
 - rust-lang/rust#148673 (Remove a remnant of `dyn*` from the parser)
 - rust-lang/rust#148675 (Remove eslint-js from npm dependencies)
 - rust-lang/rust#148680 (Recover `[T: N]` as `[T; N]`)
 - rust-lang/rust#148688 (Remove unused argument `features` from `eval_config_entry`)
 - rust-lang/rust#148711 (Use the current lint note id when parsing `cfg!()`)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-11-09 08:27:35 +00:00
Stuart Cook
d3475140ee
Rollup merge of #128666 - pitaj:intrinsic-overflow_checks, r=BoxyUwU
Add `overflow_checks` intrinsic

This adds an intrinsic which allows code in a pre-built library to inherit the overflow checks option from a crate depending on it. This enables code in the standard library to explicitly change behavior based on whether `overflow_checks` are enabled, regardless of the setting used when standard library was compiled.

This is very similar to the `ub_checks` intrinsic, and refactors the two to use a common mechanism.

The primary use case for this is to allow the new `RangeFrom` iterator to yield the maximum element before overflowing, as requested [here](https://github.com/rust-lang/rust/issues/125687#issuecomment-2151118208). This PR includes a working `IterRangeFrom` implementation based on this new intrinsic that exhibits the desired behavior.

[Prior discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Ability.20to.20select.20code.20based.20on.20.60overflow_checks.60.3F)
2025-11-09 13:22:23 +11:00
Peter Jaszkowiak
cc8b95cc54 add overflow_checks intrinsic 2025-11-08 10:57:35 -07:00
Matthias Krüger
7d63382000
Rollup merge of #145656 - folkertdev:stabilize-s390x-vector, r=Amanieu
Stabilize s390x `vector` target feature and `is_s390x_feature_detected!` macro

closes https://github.com/rust-lang/rust/issues/145649
closes https://github.com/rust-lang/rust/issues/135413
cc: https://github.com/rust-lang/rust/issues/130869
reference PR: https://github.com/rust-lang/reference/pull/1972

# Stabilization report

## Summary

This PR stabilizes the following s390x target features:

- `vector`
- `vector-enhancements-1`
- `vector-enhancements-2`
- `vector-enhancements-3`
- `vector-packed-decimal`
- `vector-packed-decimal-enhancement`
- `vector-packed-decimal-enhancement-2`
- `vector-packed-decimal-enhancement-3`
- `nnp-assist`
- `miscellaneous-extensions-2`
- `miscellaneous-extensions-3`
- `miscellaneous-extensions-4`

Additionally, it stabilizes the `std::arch::is_s390x_feature_detected!` macro itself and stably accepts the target features listed above.

## Tests & ABI details

Only the `vector` target feature changes the ABI, much like e.g. `avx2` it will, depending on the ABI, pass vector types in vector registers. This behavior is tested extensively:

- [tests/assembly-llvm/s390x-vector-abi.rs](22a86f8280/tests/assembly-llvm/s390x-vector-abi.rs)
- [tests/codegen-llvm/s390x-simd.rs](22a86f8280/tests/assembly-llvm/s390x-vector-abi.rs)
- [tests/ui/abi/simd-abi-checks-s390x.rs ](22a86f8280/tests/ui/abi/simd-abi-checks-s390x.rs )

The remaining features don't influence the ABI, they only influence instruction selection. In stdarch we test that the expected instructions are in fact generated when the target feature is enabled.

## Implementation history

For `is_s390x_feature_detected!`:

- https://github.com/rust-lang/stdarch/pull/1699
- https://github.com/rust-lang/rust/pull/138275
- https://github.com/rust-lang/stdarch/pull/1720
- https://github.com/rust-lang/stdarch/pull/1832

For `vector` and friends

- https://github.com/rust-lang/rust/pull/127506
- https://github.com/rust-lang/rust/pull/135630
- https://github.com/rust-lang/rust/pull/141250

## Unresolved questions

There is a fixme in [tests/ui/abi/simd-abi-checks-s390x.rs](22a86f8280/tests/ui/abi/simd-abi-checks-s390x.rs):

```
// FIXME: +soft-float itself doesn't set -vector
//`@[z13_soft_float]` compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float
//`@[z13_soft_float]` needs-llvm-components: systemz
```

I'm not sure whether that blocks stabilization?

---

The implementation first extracts the listed target features into their own `s390x_target_feature_vector` rust feature, and then stabilizes that. best reviewed commit-by-commit

r? `@Amanieu`
cc `@uweigand`  `@taiki-e`
2025-11-08 15:42:19 +01:00
Jeremy Fitzhardinge
5f29f11a4d Add -Zannotate-moves for profiler visibility of move/copy operations
This implements a new unstable compiler flag `-Zannotate-moves` that makes
move and copy operations visible in profilers by creating synthetic debug
information. This is achieved with zero runtime cost by manipulating debug
info scopes to make moves/copies appear as calls to `compiler_move<T, SIZE>`
and `compiler_copy<T, SIZE>` marker functions in profiling tools.

This allows developers to identify expensive move/copy operations in their
code using standard profiling tools, without requiring specialized tooling
or runtime instrumentation.

The implementation works at codegen time. When processing MIR operands
(`Operand::Move` and `Operand::Copy`), the codegen creates an `OperandRef`
with an optional `move_annotation` field containing an `Instance` of the
appropriate profiling marker function. When storing the operand,
`store_with_annotation()` wraps the store operation in a synthetic debug
scope that makes it appear inlined from the marker.

Two marker functions (`compiler_move` and `compiler_copy`) are defined
in `library/core/src/profiling.rs`. These are never actually called -
they exist solely as debug info anchors.

Operations are only annotated if the type:
   - Meets the size threshold (default: 65 bytes, configurable via
     `-Zannotate-moves=SIZE`)
   - Has a non-scalar backend representation (scalars use registers,
     not memcpy)

This has a very small size impact on object file size. With the default
limit it's well under 0.1%, and even with a very small limit of 8 bytes
it's still ~1.5%. This could be enabled by default.
2025-11-06 15:39:45 -08:00
Folkert de Vries
7516645928
stabilize s390x_target_feature_vector 2025-11-06 12:49:48 +01:00
Folkert de Vries
0645ac31cb
extract s390x vector and friends to their own rust feature 2025-11-06 12:49:04 +01:00
Stuart Cook
c33d51b9d8
Rollup merge of #147355 - sayantn:masked-loads, r=RalfJung,bjorn3
Add alignment parameter to `simd_masked_{load,store}`

This PR adds an alignment parameter in `simd_masked_load` and `simd_masked_store`, in the form of a const-generic enum `core::intrinsics::simd::SimdAlign`. This represents the alignment of the `ptr` argument in these intrinsics as follows

 - `SimdAlign::Unaligned` - `ptr` is unaligned/1-byte aligned
 - `SimdAlign::Element` - `ptr` is aligned to the element type of the SIMD vector (default behavior in the old signature)
 - `SimdAlign::Vector` - `ptr` is aligned to the SIMD vector type

The main motive for this is stdarch - most vector loads are either fully aligned (to the vector size) or unaligned (byte-aligned), so the previous signature doesn't cut it.

Now, stdarch will mostly use `SimdAlign::Unaligned` and `SimdAlign::Vector`, whereas portable-simd will use `SimdAlign::Element`.

 - [x] `cg_llvm`
 - [x] `cg_clif`
 - [x] `miri`/`const_eval`

## Alternatives

Using a const-generic/"const" `u32` parameter as alignment (and we error during codegen if this argument is not a power of two). This, although more flexible than this, has a few drawbacks

 - If we use an const-generic argument, then portable-simd somehow needs to pass `align_of::<T>()` as the alignment, which isn't possible without GCE
 - "const" function parameters are just an ugly hack, and a pain to deal with in non-LLVM backends

We can remedy the problem with the const-generic `u32` parameter by adding a special rule for the element alignment case (e.g. `0` can mean "use the alignment of the element type), but I feel like this is not as expressive as the enum approach, although I am open to suggestions

cc `@workingjubilee` `@RalfJung` `@BoxyUwU`
2025-11-05 10:59:18 +11:00
Stuart Cook
b618119fa9
Rollup merge of #145974 - pmur:murp/stabilize-zno-jump-tables, r=wesleywiser
Stabilize -Zno-jump-tables into -Cjump-tables=bool

I propose stabilizing the -Zno-jump-tables option into -Cjump-tables=<bool>.

# `-Zno-jump-tables` stabilization report
## What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized?
No RFC was created for this option. This was a narrowly scoped option introduced in rust-lang/rust#105812 to support code generation requirements of the x86-64 linux kernel, and eventually other targets as Rust For Linux grows.

The tracking is rust-lang/rust#116592.

##  What behavior are we committing to that has been controversial? Summarize the major arguments pro/con.

The behavior of this flag is well defined, and mimics the existing `-fno-jump-tables` option currently available with LLVM and GCC with some caveats:

* Unlike clang or gcc, this option may be ignored by the code generation backend. Rust can support multiple code-generation backends. For stabilization, only the LLVM backend honors this option.
* The usage of this option will not guarantee a library or binary is free of jump tables. To ensure a jump-table free binary, all crates in the build graph must be compiled with this option. This includes implicitly linked crates such as std or core.
* This option only enforces the crate being compiled is free of jump tables.
* No verification is done to ensure other crates are compiled with this option. Enforcing code generation options are applied across the crate graph is out of scope for this option.

What should the flag name be?
* As introduced, this option was named `-Zno-jump-tables`. However, other major toolchains allow both positive and negative variants of this option to toggle this feature. Renaming the option to `-Cjump-tables=<bool>` makes this option consistent, and if for some reason, expandable to other arguments in the future. Notably, many LLVM targets have a configurable and different thresholds for when to lower into a jump table.

## Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those.
No. This option is used exclusively to gate a very specific class of optimization.

## Summarize the major parts of the implementation and provide links into the code (or to PRs)
* The original PR rust-lang/rust#105812 by ```@ojeda```
* The stabilized CLI option is parsed as a bool:
68bfda9025/compiler/rustc_session/src/options.rs (L2025-L2026)
* This options adds an attribute to each llvm function via:
68bfda9025/compiler/rustc_codegen_llvm/src/attributes.rs (L210-L215)
* Finally, the rustc book is updated with the new option:
68bfda9025/src/doc/rustc/src/codegen-options/index.md (L212-L223)

## Has a call-for-testing period been conducted? If so, what feedback was received?
No. The option has originally created is being used by Rust For Linux to build the x86-64 kernel without issue.

## What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking?
There are no outstanding issues.

## Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization

* ```@ojeda``` implemented this feature in rust-lang/rust#105815 as  `-Zno-jump-tables`.
* ```@tgross35``` created and maintained the tracking issue rust-lang/rust#116592, and provided feedback about the naming of the cli option.

## What FIXMEs are still in the code for that feature and why is it ok to leave them there?
There are none.

## What static checks are done that are needed to prevent undefined behavior?
This option cannot cause undefined behavior. It is a boolean option with well defined behavior in both cases.

## In what way does this feature interact with the reference/specification, and are those edits prepared?
This adds a new cli option to `rustc`. The documentation is updated, and the unstable documentation cleaned up in this PR.

## Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries?
No.

## What other unstable features may be exposed by this feature?
None.

## What is tooling support like for this feature, w.r.t rustdoc, clippy, rust-analzyer, rustfmt, etc.?
No support is required from other rust tooling.

## Open Items

- [x] Are there objections renaming `-Zno-jump-tables` to `-Cjump-tables=<bool>`? The consensus is no.
- [x] Is it desirable to keep `-Zno-jump-tables` for a period of time? The consensus is no.

---

Closes rust-lang/rust#116592
2025-11-04 13:44:48 +11:00
sayantn
75de619159
Add alignment parameter to simd_masked_{load,store} 2025-11-04 02:30:59 +05:30
bors
20383c9f1d Auto merge of #148350 - scottmcm:slice-range-attributes, r=JonathanBrouwer,davidtwco
Add LLVM range attributes to slice length parameters

It'll take a bunch more work to do this in layout -- because of cycles in `struct Foo<'a>(&'a Foo<'a>);` -- so until we figure out how to do that well, just look for slices specifically and add the proper range for the length.
2025-11-03 19:36:42 +00:00
Paul Murphy
bb9d800b78 Stabilize -Zjump-tables=<bool> into -Cjump-table=<bool> 2025-11-03 08:12:16 -06:00
Paul Murphy
4959d18a97 Rename -Zno-jump-tables to -Zjump-tables=<bool>
Both gcc and llvm accept -fjump-tables as well as -fno-jump-tables. For
consistency, allow rustc to accept -Zjump-tables=yes too.
2025-11-03 08:12:13 -06:00
Ralf Jung
3796f7de57 compiletest: rename add-core-stubs to add-minicore 2025-11-02 16:20:06 +01:00
Scott McMurray
0ba7bcfc44 Add LLVM range attributes to slice length parameters 2025-10-31 16:12:30 -07:00
Alisa Sireneva
420544a34a Move wasm throw intrinsic back to unwind
rustc assumes that regular `extern "Rust"` functions unwind only if the
`unwind` panic runtime is linked. `throw` was annotated as such, but
unwound unconditionally. This could cause UB when a crate built with `-C
panic=abort` called `throw` from `core` built with `-C panic=unwind`,
since no terminator was added to handle the panic arising from calling an
allegedly non-unwinding `extern "Rust"` function.

rustc was taught to recognize this condition since
https://github.com/rust-lang/rust/pull/144225 and prevented such
linkage, but this caused regressions in
https://github.com/rust-lang/rust/issues/148246, since this meant that
Emscripten projects could not be built with `-C panic=abort` without
recompiling std.

The most straightforward solution would be to move `throw` into the
`panic_unwind` crate, so that it's only compiled if the panic runtime is
guaranteed to be `unwind`, but this is messy due to our architecture.
Instead, move it into `unwind::wasm`, which is only compiled for
bare-metal targets that default to `panic = "abort"`, rendering the
issue moot.
2025-10-30 15:13:32 +03:00
Tomasz Miąsko
e9252a42f5 Skip parameter attribute deduction for MIR with spread_arg
When a MIR argument is spread at ABI level, deduced attributes are
potentially misapplied, since a spread argument can correspond to zero
or more arguments at ABI level.

Disable deduction for MIR using spread argument for the time being.
2025-10-28 23:07:04 +01:00
bors
f37aa9955f Auto merge of #147890 - tmiasko:deduce-captures-none, r=cjgillot
Deduce captures(none) for a return place and parameters

Extend attribute deduction to determine whether parameters using
indirect pass mode might have their address captured. Similarly to
the deduction of `readonly` attribute this information facilitates
memcpy optimizations.
2025-10-26 20:37:03 +00:00
Tomasz Miąsko
2a03a948b9 Deduce captures(none) for a return place and parameters
Extend attribute deduction to determine whether parameters using
indirect pass mode might have their address captured. Similarly to
the deduction of `readonly` attribute this information facilitates
memcpy optimizations.
2025-10-25 22:53:52 +02:00
Matthias Krüger
cee562c0b2
Rollup merge of #143361 - cjgillot:split-disambig, r=oli-obk
Stop passing resolver disambiguator state to AST lowering.

AST->HIR lowering can use a disjoint set of `DefPathData` as the resolver, so we don't need to pass the disambiguator state.

r? `@oli-obk`
2025-10-25 12:57:38 +02:00
Camille GILLOT
b67453fccd Stop passing resolver disambiguator state to AST lowering. 2025-10-24 02:41:52 +00:00
Augie Fackler
e3e342a90b rustc_codegen_llvm: adapt for LLVM 22 change to pass masked intrinsic alignment as an attribute
This was a bit more invasive than I had kind of hoped. An alternate
approach would be to add an extra call_intrinsic_with_attrs() that would
have the new-in-this-change signature for call_intrinsic, but this felt
about equivalent and made it a little easier to audit the relevant
callsites of call_intrinsic().
2025-10-23 17:23:01 -04:00
Camille Gillot
5dfbf67f94 Replace NullOp::SizeOf and NullOp::AlignOf by lang items. 2025-10-23 00:38:28 +00:00
bors
cf8346dd4c Auto merge of #147476 - ehuss:cold-attribute-test, r=chenyukang
Add a test for the cold attribute

This adds a test for the cold attribute to verify that it actually does something, and that it applies correctly in all the positions it is expected to work.
2025-10-21 07:41:32 +00:00
bors
fd847d4d5d Auto merge of #142696 - ZuseZ4:offload-device1, r=oli-obk
Offload host2

r? `@oli-obk`

A follow-up to my previous gpu host PR. With this, I can (in theory) run a sufficiently simple Rust function on GPUs. I tested it on AMD, where the amdgcn tartget of rustc causes issues due to Addressspace castings, which might not be valid. If I (manually) fix them, I can run the generated IR on an AMD GPU. This should conceptually also work on NVIDIA or Intel. I updated the dev-guide acordingly: https://rustc-dev-guide.rust-lang.org/offload/usage.html

I am unhappy with the amount of standalone functions in my offload code, so in my second commit I bundled some of the code around two structs which are Rust versions of the LLVM/Offload structs which they represent. The structs themselves only have doc comments. Since I directly lower everything to llvm-ir I didn't saw a big value in modelling the struct member variables.
2025-10-20 10:17:29 +00:00
Manuel Drehwald
b56d555a36 fix host code 2025-10-19 09:28:39 -07:00
Camille Gillot
97f88f5603 Generalize the non-freeze and needs_drop handling. 2025-10-17 16:28:37 +00:00
Camille Gillot
031929c369 deduced_param_attrs: check Freeze on monomorphic types. 2025-10-15 21:21:05 +00:00
Matthias Krüger
041ecb124a
Rollup merge of #146949 - pmur:murp/improve-ppc-inline-asm, r=Amanieu
Add vsx register support for ppc inline asm, and implement preserves_flag option

This should address the last(?) missing pieces of inline asm for ppc:

* Explicit VSX register support. ISA 2.06 (POWER7) added a 64x128b register overlay extending the fpr's to 128b, and unifies them with the vmx (altivec) registers. Implementations details within gcc/llvm percolate up, and require using the `x` template modifier. I have updated the inline asm to implicitly include this for vsx arguments which do not specify it. ~~Support for the gcc codegen backend is still a todo.~~

* Implement the `preserves_flags` option. All ABI's, and all ISAs store their flags in `cr`, and the carry bit lives inside `xer`. The other status registers hold sticky bits or control bits which do not affect branch instructions.

There is some interest in the e500 (powerpcspe) port. Architecturally, it has a very different FP ISA, and includes a simd extension called SPR (which is not IBM's cell SPE). Notably, it does not have altivec/fpr/vsx registers. It also has an SPE accumulator register which its ABI marks as volatile, but I am not sure if the compiler uses it.
2025-10-15 07:09:54 +02:00
Matthias Krüger
10e535a163
Rollup merge of #147638 - alessandrod:indirect-res, r=wesleywiser
bpf: return results larger than one register indirectly

Fixes triggering the "only small returns supported" error in the BPF target.
2025-10-14 19:47:30 +02:00
Paul Murphy
4945d21ed9 Implement ppc/ppc64 preserves_flags option for inline asm
Implemented preserves_flags on powerpc by making it do
nothing. This prevents having two different ways to mark
`cr0` as clobbered. clang and gcc alias `cr0` to `cc`.

The gcc inline documentation does not state what this does
on powerpc* targets, but inspection of the source shows
it is equivalent to condition register field `cr0`, so it
should not be added.
2025-10-14 10:05:07 -05:00
Paul Murphy
3c09d4a582 Allow vector-scalar (vs) registers in ppc inline assembly
Where supported, VSX is a 64x128b register set which encompasses
both the floating point and vector registers.

In the type tests, xvsqrtdp is used as it is the only two-argument
vsx opcode supported by all targets on llvm. If you need to copy
a vsx register, the preferred way is "xxlor xt, xa, xa".
2025-10-14 09:52:56 -05:00
Alessandro Decina
056c2da339 bpf: return results larger than one register indirectly
Fixes triggering the "only small returns supported" error in the BPF
target.
2025-10-13 16:52:12 +00:00
Ben Kimock
029579d177 Change int-to-ptr transmute lowering back to inttoptr 2025-10-10 20:14:23 -04:00
Eric Huss
50e1884aa1 Add a test for the cold attribute
This adds a test for the cold attribute to verify that it actually does
something, and that it applies correctly in all the positions it is
expected to work.
2025-10-09 20:24:45 -07:00
Stuart Cook
4e3e7ce078
Rollup merge of #147457 - the8472:slice_fill_memset2, r=RalfJung,joboet
specialize slice::fill to use memset when possible

It helps const eval performance https://github.com/rust-lang/miri/issues/4616, debug builds and the gcc backend.

Previously attempted in https://github.com/rust-lang/rust/pull/83245 but reverted due to unsoundness https://github.com/rust-lang/rust/issues/87891 around potentially-uninitialized types. This PR only handles primitives where the problem does not arise.

split off from https://github.com/rust-lang/rust/pull/147294
2025-10-09 18:43:22 +11:00
The 8472
99ab27f90c specialize slice::fill to use memset when possible
LLVM generally can do this on its own, but it helps miri and other backends.
2025-10-08 20:14:24 +02:00
Matthias Krüger
ffba05ee29
Rollup merge of #146865 - folkertdev:kcfi-only-reify-dyn-compatible, r=rcvalle
kcfi: only reify trait methods when dyn-compatible

fixes https://github.com/rust-lang/rust/issues/146853

Only generate a `ReifyShim` for trait method calls if the trait is dyn-compatible.

Until now kcfi would generate a `ReifyShim` whenever a trait method was cast to a function pointer. But technically the shim is only needed for dyn-compatible traits (where the method might end up in a vtable).

Up to this point that was only slightly inefficient, but in combination with c-variadic trait methods it is wrong. For c-variadic trait methods the generated shim is incorrect, and that is why c-variadic methods make a trait no longer dyn-compatible: we should simply never generate a `ReifyShim` that is c-variadic.

With this change the documentation on `ReifyReason` is now actually correct:

>  If KCFI is enabled, creating a function pointer from a method on a dyn-compatible trait. This includes the case of converting `::call`-like methods on closure-likes to function pointers.

cc ```@maurer``` ```@workingjubilee```

r? ```@rcvalle```
2025-10-07 19:39:06 +02:00
Manuel Drehwald
7c8fe29fd6 solve autodiffv2.rs FIXME and make identical_fnc test more robust 2025-10-05 03:07:51 -04:00
Matthias Krüger
a84359c5a7
Rollup merge of #147315 - ZuseZ4:fix-ad-batching-test, r=jieyouxu
bless autodiff batching test

This pr blesses a broken test and unblocks running rust in the Enzyme CI: https://github.com/EnzymeAD/Enzyme/pull/2430
Enzyme is the plugin used by our std::autodiff and (future) std::batching modules, both of which are not build by default.
In the near future we also hope to enable std::autodiff in the Rust CI.

This test is the only one to combine two features, automatic differentiation and batching/vectorization. This combination is even more experimental than either feature on its own. I have a wip branch in which I enable more vectorization/batching and as part of that I'll think more about how to write those tests in a robust way (and likely change the interface). Until that lands, I don't care too much about what specific IR we generate here; it's just nice to track changes.

r? compiler
2025-10-04 17:11:13 +02:00
Manuel Drehwald
12cfad9a8b update autodiff batching test 2025-10-03 18:12:22 -04:00
dianqk
c2a03cefd8
debuginfo: Use LocalRef to simplify reference debuginfos
If the `LocalRef` is `LocalRef::Place`, we can refer to it directly,
because the local of place is an indirect pointer.
Such a statement is `_1 = &(_2.1)`.
If the `LocalRef` is `LocalRef::Operand`,
the `OperandRef` should provide the pointer of the reference.
Such a statement is `_1 = &((*_2).1)`.

But there is a special case that hasn't been handled, scalar pairs like `(&[i32; 16], i32)`.
2025-10-03 08:08:22 +08:00
dianqk
8da04285cf
mir-opt: Eliminate dead statements even if they are used by debuginfos 2025-10-02 14:58:59 +08:00
dianqk
1bd89bd42e
codegen: Generate dbg_value for the ref statement 2025-10-02 14:55:51 +08:00
dianqk
571412f819
mir-opt: Eliminate dead ref statements 2025-10-02 14:55:50 +08:00
Stuart Cook
7b0236fbd8
Rollup merge of #147200 - ZuseZ4:fix-autodiff-emptry-ret, r=Zalathar
Fix autodiff empty ret regression

closes https://github.com/rust-lang/rust/issues/147144

The two gsoc summer projects caused a bit of churn, which was to be expected, especially since we don't run autodiff in CI yet.
This adds a void return testcase that we should have had anyway, and fixes the regression.

r? `@Zalathar` (Just guessing since I've seen you in a few LLVM PRs and Oli is probably still busy. Feel free to reroll!)
2025-10-01 22:15:01 +10:00
Manuel Drehwald
de189fa982 updating tests to not break from new typetree metadata 2025-09-30 22:47:43 -04:00
Manuel Drehwald
28ffbab353 add empty struct ret testcase 2025-09-30 22:47:43 -04:00
Jacob Pratt
b310eb91ab
Rollup merge of #146457 - alexcrichton:wasm-no-exn-instructions, r=bjorn3
Skip cleanups on unsupported targets

This commit is an update to the `AbortUnwindingCalls` MIR pass in the compiler. Specifically a new boolean is added for "can this target possibly unwind" and if that's `false` then terminators are all adjusted to be unreachable/not present. The end result is that this fixes rust-lang/rust#140293 for wasm targets.

The motivation for this PR is that currently on WebAssembly targets the usage of the `C-unwind` ABI can lead LLVM to either (a) emit exception-handling instructions or (b) hit a LLVM-ICE-style codegen error. WebAssembly as a base instruction set does not support unwinding at all, and a later proposal to WebAssembly, the exception-handling proposal, was what enabled this. This means that the current intent of WebAssembly targets is that they maintain the baseline of "don't emit exception-handling instructions unless enabled". The commit here is intended to restore this behavior by skipping these instructions even when `C-unwind` is present.

Exception-handling is a relatively tricky and also murky topic in WebAssembly, however. There are two sets of instructions LLVM can emit for WebAssembly exceptions, Rust's Emscripten target supports exceptions, WASI targets do not, the LLVM flags to enable this are not always obvious, and additionally this all touches on "changing exception-handling behavior should be a target-level concern, not a feature". Effectively WebAssembly's exception-handling integration into Rust is not finalized at this time. The best idea at this time is that a parallel set of targets will eventually be added which support exceptions, but it's not clear if/when to do this. In the meantime the goal is to keep existing targets working while still enabling experimentation with exception-handling with `-Zbuild-std` and various permutations of LLVM flags.

To that extent this commit does not blanket disable these landing pads and cleanup routines for WebAssembly but instead checks to see if panic=unwind is enabled or if `+exception-handling` is enabled. Tests are updated here as well to account for this where, by default, using a `C-unwind` ABI won't affect Rust codegen at all. If `+exception-handling` is enabled, however, then Rust codegen will look like native platforms where exceptions are caught and the program aborts. More-or-less I've done my best to keep exceptions working on wasm where it's possible to have them work, but turned them off where they're not supposed to be emitted.

Closes rust-lang/rust#140293
2025-09-29 21:37:50 -04:00
Matthias Krüger
c29fb2e57e
Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4
TypeTree support in autodiff

# TypeTrees for Autodiff

## What are TypeTrees?
Memory layout descriptors for Enzyme. Tell Enzyme exactly how types are structured in memory so it can compute derivatives efficiently.

## Structure
```rust
TypeTree(Vec<Type>)

Type {
    offset: isize,  // byte offset (-1 = everywhere)
    size: usize,    // size in bytes
    kind: Kind,     // Float, Integer, Pointer, etc.
    child: TypeTree // nested structure
}
```

## Example: `fn compute(x: &f32, data: &[f32]) -> f32`

**Input 0: `x: &f32`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, size: 4, kind: Float,
        child: TypeTree::new()
    }])
}])
```

**Input 1: `data: &[f32]`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, size: 4, kind: Float,  // -1 = all elements
        child: TypeTree::new()
    }])
}])
```

**Output: `f32`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 4, kind: Float,
    child: TypeTree::new()
}])
```

## Why Needed?
- Enzyme can't deduce complex type layouts from LLVM IR
- Prevents slow memory pattern analysis
- Enables correct derivative computation for nested structures
- Tells Enzyme which bytes are differentiable vs metadata

## What Enzyme Does With This Information:

Without TypeTrees (current state):
```llvm
; Enzyme sees generic LLVM IR:
define float ``@distance(ptr*`` %p1, ptr* %p2) {
; Has to guess what these pointers point to
; Slow analysis of all memory operations
; May miss optimization opportunities
}
```

With TypeTrees (our implementation):
```llvm
define "enzyme_type"="{[]:Float@float}" float ``@distance(``
    ptr "enzyme_type"="{[]:Pointer}" %p1,
    ptr "enzyme_type"="{[]:Pointer}" %p2
) {
; Enzyme knows exact type layout
; Can generate efficient derivative code directly
}
```

# TypeTrees - Offset and -1 Explained

## Type Structure

```rust
Type {
    offset: isize, // WHERE this type starts
    size: usize,   // HOW BIG this type is
    kind: Kind,    // WHAT KIND of data (Float, Int, Pointer)
    child: TypeTree // WHAT'S INSIDE (for pointers/containers)
}
```

## Offset Values

### Regular Offset (0, 4, 8, etc.)
**Specific byte position within a structure**

```rust
struct Point {
    x: f32, // offset 0, size 4
    y: f32, // offset 4, size 4
    id: i32, // offset 8, size 4
}
```

TypeTree for `&Point` (internal representation):
```rust
TypeTree(vec![
    Type { offset: 0, size: 4, kind: Float },   // x at byte 0
    Type { offset: 4, size: 4, kind: Float },   // y at byte 4
    Type { offset: 8, size: 4, kind: Integer }  // id at byte 8
])
```

Generates LLVM:
```llvm
"enzyme_type"="{[]:Float@float}"
```

### Offset -1 (Special: "Everywhere")
**Means "this pattern repeats for ALL elements"**

#### Example 1: Array `[f32; 100]`
```rust
TypeTree(vec![Type {
    offset: -1, // ALL positions
    size: 4,    // each f32 is 4 bytes
    kind: Float, // every element is float
}])
```

Instead of listing 100 separate Types with offsets `0,4,8,12...396`

#### Example 2: Slice `&[i32]`
```rust
// Pointer to slice data
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, // ALL slice elements
        size: 4,    // each i32 is 4 bytes
        kind: Integer
    }])
}])
```

#### Example 3: Mixed Structure
```rust
struct Container {
    header: i64,        // offset 0
    data: [f32; 1000],  // offset 8, but elements use -1
}
```

```rust
TypeTree(vec![
    Type { offset: 0, size: 8, kind: Integer }, // header
    Type { offset: 8, size: 4000, kind: Pointer,
        child: TypeTree(vec![Type {
            offset: -1, size: 4, kind: Float // ALL array elements
        }])
    }
])
```
2025-09-28 18:13:11 +02:00