about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
AgeCommit message (Collapse)AuthorLines
2025-07-31remove rustc_attr_data_structuresJana Dönszelmann-1/+1
2025-07-31Rollup merge of #144232 - xacrimon:explicit-tail-call, r=WaffleLapkinStuart Cook-11/+62
Implement support for `become` and explicit tail call codegen for the LLVM backend This PR implements codegen of explicit tail calls via `become` in `rustc_codegen_ssa` and support within the LLVM backend. Completes a task on (https://github.com/rust-lang/rust/issues/112788). This PR implements all the necessary bits to make explicit tail calls usable, other backends have received stubs for now and will ICE if you use `become` on them. I suspect there is some bikeshedding to be done on how we should go about implementing this for other backends, but it should be relatively straightforward for GCC after this is merged. During development I also put together a POC bytecode VM based on tail call dispatch to test these changes out and analyze the codegen to make sure it generates expected assembly. That is available [here](https://github.com/xacrimon/tcvm).
2025-07-27Auto merge of #144347 - scottmcm:ssa-enums-v0, r=WaffleLapkinbors-64/+79
No longer need `alloca`s for consuming `Result<!, i32>` and similar In optimized builds GVN gets rid of these already, but in `opt-level=0` we actually make `alloca`s for this, which particularly impacts `?`-style things that use actually-only-one-variant types like this. While doing so, rewrite `LocalAnalyzer::process_place` to be non-recursive, solving a 6+ year old FIXME. r? codegen
2025-07-26Auto merge of #143860 - scottmcm:transmute-always-rvalue, r=WaffleLapkinbors-96/+66
Let `codegen_transmute_operand` just handle everything When combined with rust-lang/rust#143720, this means `rvalue_creates_operand` can just return `true` for *every* `Rvalue`. (A future PR could consider removing it, though just letting it optimize out is fine for now.) It's nicer anyway, IMHO, because it avoids needing the layout checks to be consistent in the two places, and thus is an overall reduction in code. Plus it's a more helpful building block when used in other places this way. (TBH, it probably would have been better to have it this way the whole time, but I clearly didn't understand `rvalue_creates_operand` when I originally wrote rust-lang/rust#109843.)
2025-07-26Implement support for explicit tail calls in the MIR block builders and the ↵Joel Wejdenstål-11/+62
LLVM codegen backend.
2025-07-25Rollup merge of #144209 - scottmcm:assume_less, r=lcnr,dianqkMatthias Krüger-4/+24
Don't emit two `assume`s in transmutes when one is a subset of the other For example, transmuting between `bool` and `Ordering` doesn't need two `assume`s because one range is a superset of the other. Multiple are still used for things like `char` <-> `NonZero<u32>`, which overlap but where neither fully contains the other.
2025-07-23Remove useless lifetime parameter.Camille GILLOT-3/+3
2025-07-23Give an AllocId to ConstValue::Slice.Camille GILLOT-5/+2
2025-07-23Don't emit two `assume`s in transmutes when one is a subset of the otherScott McMurray-4/+24
For example, transmuting between `bool` and `Ordering` doesn't need two `assume`s because one range is a superset of the other. Multiple are still used for things like `char` <-> `NonZero<u32>`, which overlap but where neither fully contains the other.
2025-07-23Remove `rvalue_creates_operand` entirelyScott McMurray-47/+2
Split to a separate commit to it could be reverted later if necessary, should we get new `Rvalue`s where we can't handle it this way.
2025-07-23re-enable direct `bitcast`s for Int/Float vector transmutes (but not ones ↵Scott McMurray-0/+21
involving pointers)
2025-07-23Let `codegen_transmute_operand` just handle everythingScott McMurray-49/+43
When combined with 143720, this means `rvalue_creates_operand` can just return `true` for *every* `Rvalue`. (A future PR could consider removing it, though just letting it optimize out is fine for now.) It's nicer anyway, IMHO, because it avoids needing the layout checks to be consistent in the two places, and thus is an overall reduction in code. Plus it's a more helpful building block when used in other places this way.
2025-07-23No longer need `alloca`s for consuming `Result<!, i32>` and similarScott McMurray-64/+79
In optimized builds GVN gets rid of these already, but in `opt-level=0` we actually make `alloca`s for this, which particularly impacts `?`-style things that use actually-only-one-variant types like this.
2025-07-22Rename `tests/codegen` into `tests/codegen-llvm`Guillaume Gomez-1/+1
2025-07-20Ban projecting into SIMD types [MCP838]Scott McMurray-14/+5
2025-07-19Allow `Rvalue::Repeat` to return true in `rvalue_creates_operand` tooScott McMurray-4/+12
The conversation in 143502 made be realize how easy this is to handle, since the only possibilty is ZSTs -- everything else ends up with the destination being `LocalKind::Memory` and thus doesn't call `codegen_rvalue_operand` at all. This gets us perilously close to a world where `rvalue_creates_operand` only ever returns true. I'll try out such a world next :)
2025-07-19Auto merge of #143784 - scottmcm:enums-again-new-ex2, r=dianqkbors-29/+96
Simplify discriminant codegen for niche-encoded variants which don't wrap across an integer boundary Inspired by rust-lang/rust#139729, this attempts to be a much-simpler and more-localized change while still making a difference. (Specifically, this does not try to solve the problem with select-sinking, leaving that to be fixed by https://github.com/llvm/llvm-project/issues/134024 -- once it gets released -- instead of in rustc's codegen.) What this *does* improve is checking for the variant in a 3+ variant enum when that variant is the type providing the niche. Something like `if let Foo::WithBool(_) = ...` previously compiled to `ugt(add(x, -2), 2)`, which is non-trivial to think about because it's depending on the unsigned wrapping to shift the 0/1 up above 2. With this PR it compiles to just `ult(x, 2)`, which is probably what you'd have written yourself if you were doing it by hand to look for "is this byte a bool?". That's done by leaving most of the codegen alone, but adding a couple new special cases to the `is_niche` check. The default looks at the relative discriminant, but in the common cases where there's no wraparound involved, we can just check the original value, rather than the offsetted one. The first commit just adds some tests, so the best way to see the effect of this change is to look at the second commit and how it updates the test expectations.
2025-07-16use `codegen_instance_attrs` where an instance is (easily) availableFolkert de Vries-3/+11
2025-07-16add `codegen_instance_attrs` queryFolkert de Vries-4/+3
and use it for naked functions
2025-07-15Improve comments inside `codegen_get_discr`Scott McMurray-2/+46
2025-07-12Simplify codegen for niche-encoded variant testsScott McMurray-27/+50
2025-07-12Auto merge of #143766 - matthiaskrgr:rollup-0x7t69s, r=matthiaskrgrbors-10/+4
Rollup of 8 pull requests Successful merges: - rust-lang/rust#142391 (rust: library: Add `setsid` method to `CommandExt` trait) - rust-lang/rust#143302 (`tests/ui`: A New Order [27/N]) - rust-lang/rust#143303 (`tests/ui`: A New Order [28/28] FINAL PART) - rust-lang/rust#143568 (std: sys: net: uefi: tcp4: Add timeout support) - rust-lang/rust#143611 (Mention more APIs in `ParseIntError` docs) - rust-lang/rust#143661 (chore: Improve how the other suggestions message gets rendered) - rust-lang/rust#143708 (fix: Include frontmatter in -Zunpretty output ) - rust-lang/rust#143718 (Make UB transmutes really UB in LLVM) r? `@ghost` `@rustbot` modify labels: rollup try-job: i686-gnu-nopt-1 try-job: test-various
2025-07-11Rollup merge of #143718 - scottmcm:ub-transmute-is-ub, r=WaffleLapkinMatthias Krüger-10/+4
Make UB transmutes really UB in LLVM Ralf suggested in <https://github.com/rust-lang/rust/pull/143410#discussion_r2184928123> that UB transmutes shouldn't be trapping, which happened for the one path *that* PR was changing, but there's another path as well, so *this* PR changes that other path to match. r? codegen
2025-07-11Auto merge of #142911 - mejrs:unsized, r=compiler-errorsbors-64/+15
Remove support for dynamic allocas Followup to rust-lang/rust#141811
2025-07-10Add `BuilderMethods::unreachable_nonterminator`Scott McMurray-6/+2
So places that need `unreachable` but in the middle of a basic block can call that instead of figuring out the best way to do it.
2025-07-10Auto merge of #143696 - oli-obk:constable-type-id2, r=RalfJungbors-1/+1
Add opaque TypeId handles for CTFE Reopen of https://github.com/rust-lang/rust/pull/142789#issuecomment-3053155043 after some bors insta-merge chaos r? `@RalfJung`
2025-07-09Make UB transmutes really UB in LLVMScott McMurray-7/+5
Ralf suggested in <https://github.com/rust-lang/rust/pull/143410#discussion_r2184928123> that UB transmutes shouldn't be trapping, which happened for the one path that PR was changing, but there's another path as well, so this PR changes that other path to match.
2025-07-09Auto merge of #143502 - scottmcm:aggregate-simd, r=oli-obkbors-77/+126
Let `rvalue_creates_operand` return true for *all* `Rvalue::Aggregate`s ~~Draft for now because it's built on Ralf's rust-lang/rust#143291~~ Inspired by https://github.com/rust-lang/rust/pull/138759#discussion_r2156375342 where I noticed that we were nearly at this point, plus the comments I was writing in rust-lang/rust#143410 that reminded me a type-dependent `true` is fine. This PR splits the `OperandRef::builder` logic out to a separate type, with the updates needed to handle SIMD as well. In doing so, that makes the existing `Aggregate` path in `codegen_rvalue_operand` capable of handing SIMD values just fine. As a result, we no longer need to do layout calculations for aggregate result types when running the analysis to determine which things can be SSA in codegen.
2025-07-09Add opaque TypeId handles for CTFEOli Scherer-1/+1
2025-07-08Error on moving unsized values rather than ICE'ingmejrs-1/+6
2025-07-07Let `rvalue_creates_operand` return true for *all* `Rvalue::Aggregate`sScott McMurray-77/+126
Inspired by <https://github.com/rust-lang/rust/pull/138759#discussion_r2156375342> where I noticed that we were nearly at this point, plus the comments I was writing in 143410 that reminded me a type-dependent `true` is fine. This PR splits the `OperandRef::builder` logic out to a separate type, with the updates needed to handle SIMD as well. In doing so, that makes the existing `Aggregate` path in `codegen_rvalue_operand` capable of handing SIMD values just fine. As a result, we no longer need to do layout calculations for aggregate result types when running the analysis to determine which things can be SSA in codegen.
2025-07-07Remove support for dynamic allocasmejrs-64/+10
2025-07-07Auto merge of #143182 - xdoardo:more-addrspace, r=workingjubileebors-2/+2
Allow custom default address spaces and parse `p-` specifications in the datalayout string Some targets, such as CHERI, use as default an address space different from the "normal" default address space `0` (in the case of CHERI, [200 is used](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-877.pdf)). Currently, `rustc` does not allow to specify custom address spaces and does not take into consideration [`p-` specifications in the datalayout string](https://llvm.org/docs/LangRef.html#langref-datalayout). This patch tries to mitigate these problems by allowing targets to define a custom default address space (while keeping the default value to address space `0`) and adding the code to parse the `p-` specifications in `rustc_abi`. The main changes are that `TargetDataLayout` now uses functions to refer to pointer-related informations, instead of having specific fields for the size and alignment of pointers in the default address space; furthermore, the two `pointer_size` and `pointer_align` fields in `TargetDataLayout` are replaced with an `FxHashMap` that holds info for all the possible address spaces, as parsed by the `p-` specifications. The potential performance drawbacks of not having ad-hoc fields for the default address space will be tested in this PR's CI run. r? workingjubilee
2025-07-07compiler: Parse `p-` specs in datalayout string, allow definition of custom ↵Edoardo Marangoni-2/+2
default data address space
2025-07-05codegen_ssa: replace a Result by an EitherRalf Jung-23/+24
2025-07-04Rollup merge of #143410 - scottmcm:redo-transmute-again, ↵Jubilee-165/+111
r=RalfJung,workingjubilee Block SIMD in transmute_immediate; delete `OperandValueKind` Vectors have been causing me problems for years in this code, for example https://github.com/rust-lang/rust/pull/110021#discussion_r1160975086 and https://github.com/rust-lang/rust/pull/143194 See conversation in <https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/near/526262799>. By blocking SIMD in `transmute_immediate` it can be simplified to just take the `Scalar`s involved -- the backend types can be gotten from those `Scalar`s, rather than needing to be passed. And there's an assert added to ICE it if it does get hit. Accordingly, this changes `rvalue_creates_operand` to not send SIMD transmutes through the operand path, but to always go through memory instead, like they did back before rust-lang/rust#108442. And thanks to those changes, I could also remove the `OperandValueKind` type that I added back then which `@RalfJung` rightly considers pretty sketchy. cc `@folkertdev` `@workingjubilee` from the zulip conversation too
2025-07-04Address PR feedbackScott McMurray-41/+52
2025-07-04Rename `transmute_immediate` → `transmute_scalar`Scott McMurray-11/+13
2025-07-03Allow all MIR `Aggregate`s to take the operand path (if layout permits)Scott McMurray-67/+149
2025-07-03Block SIMD in transmute_immediate; delete `OperandValueKind`Scott McMurray-148/+81
See conversation in <https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/near/526262799>.
2025-07-02Rollup merge of #143194 - folkertdev:fix-single-element-simd-bitcast, ↵Matthias Krüger-8/+2
r=workingjubilee fix bitcast of single-element SIMD vectors in effect this reverts https://github.com/rust-lang/rust/pull/142768 and adds additional tests. That PR relaxed the conditions on an early return in an incorrect way that would create broken LLVM IR. https://godbolt.org/z/PaaGWTv5a ```rust #![feature(repr_simd)] #[repr(simd)] #[derive(Clone, Copy)] struct S([i64; 1]); #[no_mangle] pub extern "C" fn single_element_simd(b: S) -> i64 { unsafe { std::mem::transmute(b) } } ``` at the time of writing generates this LLVM IR, where the type of the return is different from the function's return type. ```llvm define noundef i64 ``````@single_element_simd(<1`````` x i64> %b) unnamed_addr { start: ret <1 x i64> %b } ``` The test output is actually the same for the existing tests, showing that the change didn't actually matter for any tested behavior. It is probably a bit faster to do the early return, but, well, it's incorrect in general. zullip thread: [#t-compiler > Is transmuting a &#96;T&#96; to &#96;Tx1&#96; (one-element SIMD vector) UB?](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/with/526262799) cc ``````@sayantn`````` r? ``````@scottmcm``````
2025-07-01Remove support for dyn*Michael Goulet-77/+0
2025-06-30Auto merge of #143233 - dianqk:rollup-lcx3278, r=dianqkbors-4/+4
Rollup of 14 pull requests Successful merges: - rust-lang/rust#142429 (`tests/ui`: A New Order [13/N]) - rust-lang/rust#142514 (Miri: handling of SNaN inputs in `f*::pow` operations) - rust-lang/rust#143066 (Use let chains in the new solver) - rust-lang/rust#143090 (Workaround for memory unsafety in third party DLLs) - rust-lang/rust#143118 (`tests/ui`: A New Order [15/N]) - rust-lang/rust#143159 (Do not freshen `ReError`) - rust-lang/rust#143168 (`tests/ui`: A New Order [16/N]) - rust-lang/rust#143176 (fix typos and improve clarity in documentation) - rust-lang/rust#143187 (Add my work email to mailmap) - rust-lang/rust#143190 (Use the `new` method for `BasicBlockData` and `Statement`) - rust-lang/rust#143195 (`tests/ui`: A New Order [17/N]) - rust-lang/rust#143196 (Port #[link_section] to the new attribute parsing infrastructure) - rust-lang/rust#143199 (Re-disable `tests/run-make/short-ice` on Windows MSVC again) - rust-lang/rust#143219 (Show auto trait and blanket impls for `!`) r? `@ghost` `@rustbot` modify labels: rollup
2025-06-30fix bitcast of single-element SIMD vectorsFolkert de Vries-8/+2
2025-06-30Require either wrapping nullary intrinsincs in const blocks or explicitly ↵Oli Scherer-1/+22
deciding not to
2025-06-30Stop backends from needing to support nullary intrinsicsOli Scherer-4/+0
2025-06-29mir: Add a `new` method to `statement`dianqk-4/+4
Avoid introducing a large number of changes when adding optional initialization fields.
2025-06-29Rollup merge of #143088 - firefighterduck:improve-doc-discr-tag, r=RalfJungMatthias Krüger-10/+1
Improve documentation of `TagEncoding` This PR is follow-up from the [discussion here](https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20VariantId.3DDiscriminant.20when.20tag.20is.20niche.20encoded.3F/with/524384295). It aims at making the `TagEncoding` documentation less ambiguous and more detailed with references to relevant implementation sides. It especially clears up the ambiguous use of discriminant/variant index, which sparked the discussion referenced above. PS: While working with layout data, I somehow ended up looking at the docs for `FakeBorrowKind` and noticed that the one example was not in a doc comment. I hope that this is minor enough of a fix for it to be okay in this otherwise unrelated PR.
2025-06-28move discr=varid check to layout_sanity_checkFlorian Sextl-10/+1
2025-06-28Auto merge of #141759 - 1c3t3a:discriminants-query, r=saethlinbors-0/+6
Insert checks for enum discriminants when debug assertions are enabled Similar to the existing null-pointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following: ```rust let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) }; ``` An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++. This check is similar to Miri's capabilities of checking for valid construction of enum values. This PR is inspired by saethlin@'s PR https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments! I also pair-programmed large parts of this together with vabr-g@. r? `@saethlin`