diff options
| author | bors <bors@rust-lang.org> | 2025-08-08 05:59:00 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-08-08 05:59:00 +0000 |
| commit | 2886b36df4a646dd8d82fb65bf0c9d8d96c1f71a (patch) | |
| tree | 1609159274b26a3f4a74193ec76c62dfe5046b00 /compiler/rustc_codegen_ssa/src/mir/operand.rs | |
| parent | 67d45f49e09cb8f355df2ffae22cfc3d7ee6c278 (diff) | |
| parent | f6283aebcb84c61888c7955a6760e928ecfd2209 (diff) | |
| download | rust-2886b36df4a646dd8d82fb65bf0c9d8d96c1f71a.tar.gz rust-2886b36df4a646dd8d82fb65bf0c9d8d96c1f71a.zip | |
Auto merge of #145077 - Zalathar:rollup-0k4194x, r=Zalathar
Rollup of 19 pull requests Successful merges: - rust-lang/rust#144400 (`tests/ui/issues/`: The Issues Strike Back [3/N]) - rust-lang/rust#144764 ([codegen] assume the tag, not the relative discriminant) - rust-lang/rust#144807 (Streamline config in bootstrap) - rust-lang/rust#144899 (Print CGU reuse statistics in `-Zprint-mono-items`) - rust-lang/rust#144909 (Add new `test::print_merged_doctests_times` used by rustdoc to display more detailed time information) - rust-lang/rust#144912 (Resolver: introduce a conditionally mutable Resolver for (non-)speculative resolution.) - rust-lang/rust#144914 (Add support for `ty::Instance` path shortening in diagnostics) - rust-lang/rust#144931 ([win][arm64ec] Fix msvc-wholearchive for Arm64EC) - rust-lang/rust#144999 (coverage: Remove all unstable support for MC/DC instrumentation) - rust-lang/rust#145009 (A couple small changes for rust-analyzer next-solver work) - rust-lang/rust#145030 (GVN: Do not flatten derefs with ProjectionElem::Index. ) - rust-lang/rust#145042 (stdarch subtree update) - rust-lang/rust#145047 (move `type_check` out of `compute_regions`) - rust-lang/rust#145051 (Prevent name collisions with internal implementation details) - rust-lang/rust#145053 (Add a lot of NLL `known-bug` tests) - rust-lang/rust#145055 (Move metadata symbol export from exported_non_generic_symbols to exported_symbols) - rust-lang/rust#145057 (Clean up some resolved test regressions of const trait removals in std) - rust-lang/rust#145068 (Readd myself to review queue) - rust-lang/rust#145070 (Add minimal `armv7a-vex-v5` tier three target) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/mir/operand.rs')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/operand.rs | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 5459f95c186..d851c332980 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -498,6 +498,35 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64); (is_niche, tagged_discr, 0) } else { + // Thanks to parameter attributes and load metadata, LLVM already knows + // the general valid range of the tag. It's possible, though, for there + // to be an impossible value *in the middle*, which those ranges don't + // communicate, so it's worth an `assume` to let the optimizer know. + // Most importantly, this means when optimizing a variant test like + // `SELECT(is_niche, complex, CONST) == CONST` it's ok to simplify that + // to `!is_niche` because the `complex` part can't possibly match. + // + // This was previously asserted on `tagged_discr` below, where the + // impossible value is more obvious, but that caused an intermediate + // value to become multi-use and thus not optimize, so instead this + // assumes on the original input which is always multi-use. See + // <https://github.com/llvm/llvm-project/issues/134024#issuecomment-3131782555> + // + // FIXME: If we ever get range assume operand bundles in LLVM (so we + // don't need the `icmp`s in the instruction stream any more), it + // might be worth moving this back to being on the switch argument + // where it's more obviously applicable. + if niche_variants.contains(&untagged_variant) + && bx.cx().sess().opts.optimize != OptLevel::No + { + let impossible = niche_start + .wrapping_add(u128::from(untagged_variant.as_u32())) + .wrapping_sub(u128::from(niche_variants.start().as_u32())); + let impossible = bx.cx().const_uint_big(tag_llty, impossible); + let ne = bx.icmp(IntPredicate::IntNE, tag, impossible); + bx.assume(ne); + } + // With multiple niched variants we'll have to actually compute // the variant index from the stored tag. // @@ -588,20 +617,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let untagged_variant_const = bx.cx().const_uint(cast_to, u64::from(untagged_variant.as_u32())); - // Thanks to parameter attributes and load metadata, LLVM already knows - // the general valid range of the tag. It's possible, though, for there - // to be an impossible value *in the middle*, which those ranges don't - // communicate, so it's worth an `assume` to let the optimizer know. - // Most importantly, this means when optimizing a variant test like - // `SELECT(is_niche, complex, CONST) == CONST` it's ok to simplify that - // to `!is_niche` because the `complex` part can't possibly match. - if niche_variants.contains(&untagged_variant) - && bx.cx().sess().opts.optimize != OptLevel::No - { - let ne = bx.icmp(IntPredicate::IntNE, tagged_discr, untagged_variant_const); - bx.assume(ne); - } - let discr = bx.select(is_niche, tagged_discr, untagged_variant_const); // In principle we could insert assumes on the possible range of `discr`, but |
