about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-25 10:40:01 +0000
committerbors <bors@rust-lang.org>2025-07-25 10:40:01 +0000
commita955f1cd09a027363729ceed919952d09f76f28e (patch)
treed3c298f939e50e78985c27fd360231560bc6a398 /compiler/rustc_codegen_ssa/src
parentb56aaec52bc0fa35591a872fb4aac81f606e265c (diff)
parent1caf7016534e0331a0ef0008e1ad78726db5e088 (diff)
downloadrust-a955f1cd09a027363729ceed919952d09f76f28e.tar.gz
rust-a955f1cd09a027363729ceed919952d09f76f28e.zip
Auto merge of #144440 - matthiaskrgr:rollup-peb88gb, r=matthiaskrgr
Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#142569 (Suggest clone in user-write-code instead of inside macro)
 - rust-lang/rust#143401 (tests: Don't check for self-printed output in std-backtrace.rs test)
 - rust-lang/rust#143424 (clippy fix: rely on autoderef)
 - rust-lang/rust#143970 (Update core::mem::copy documentation)
 - rust-lang/rust#143979 (Test fixes for Arm64EC Windows)
 - rust-lang/rust#144200 (Tweak output for non-`Clone` values moved into closures)
 - rust-lang/rust#144209 (Don't emit two `assume`s in transmutes when one is a subset of the other)
 - rust-lang/rust#144314 (Hint that choose_pivot returns index in bounds)
 - rust-lang/rust#144340 (UI test suite clarity changes: Rename `tests/ui/SUMMARY.md` and update rustc dev guide on `error-pattern`)
 - rust-lang/rust#144368 (resolve: Remove `Scope::CrateRoot`)
 - rust-lang/rust#144390 (Remove dead code and extend test coverage and diagnostics around it)
 - rust-lang/rust#144392 (rustc_public: Remove movability from `RigidTy/AggregateKind::Coroutine`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs28
1 files changed, 24 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 610e2fd2311..a5759b79be4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -288,7 +288,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // valid ranges. For example, `char`s are passed as just `i32`, with no
         // way for LLVM to know that they're 0x10FFFF at most. Thus we assume
         // the range of the input value too, not just the output range.
-        assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+        assume_scalar_range(bx, imm, from_scalar, from_backend_ty, None);
 
         imm = match (from_scalar.primitive(), to_scalar.primitive()) {
             (Int(_, is_signed), Int(..)) => bx.intcast(imm, to_backend_ty, is_signed),
@@ -1064,7 +1064,7 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // That said, last time we tried removing this, it didn't actually help
     // the rustc-perf results, so might as well keep doing it
     // <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182>
-    assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+    assume_scalar_range(bx, imm, from_scalar, from_backend_ty, Some(&to_scalar));
 
     imm = match (from_scalar.primitive(), to_scalar.primitive()) {
         (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
@@ -1092,22 +1092,42 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // since it's never passed to something with parameter metadata (especially
     // after MIR inlining) so the only way to tell the backend about the
     // constraint that the `transmute` introduced is to `assume` it.
-    assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
+    assume_scalar_range(bx, imm, to_scalar, to_backend_ty, Some(&from_scalar));
 
     imm = bx.to_immediate_scalar(imm, to_scalar);
     imm
 }
 
+/// Emits an `assume` call that `imm`'s value is within the known range of `scalar`.
+///
+/// If `known` is `Some`, only emits the assume if it's more specific than
+/// whatever is already known from the range of *that* scalar.
 fn assume_scalar_range<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     imm: Bx::Value,
     scalar: abi::Scalar,
     backend_ty: Bx::Type,
+    known: Option<&abi::Scalar>,
 ) {
-    if matches!(bx.cx().sess().opts.optimize, OptLevel::No) || scalar.is_always_valid(bx.cx()) {
+    if matches!(bx.cx().sess().opts.optimize, OptLevel::No) {
         return;
     }
 
+    match (scalar, known) {
+        (abi::Scalar::Union { .. }, _) => return,
+        (_, None) => {
+            if scalar.is_always_valid(bx.cx()) {
+                return;
+            }
+        }
+        (abi::Scalar::Initialized { valid_range, .. }, Some(known)) => {
+            let known_range = known.valid_range(bx.cx());
+            if valid_range.contains_range(known_range, scalar.size(bx.cx())) {
+                return;
+            }
+        }
+    }
+
     match scalar.primitive() {
         abi::Primitive::Int(..) => {
             let range = scalar.valid_range(bx.cx());