about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-01 16:32:19 +0000
committerbors <bors@rust-lang.org>2024-10-01 16:32:19 +0000
commitc817d5dc2050ec443516f9700c19b1419593a83d (patch)
treee21ddbb656fecc18a950d2edfdfa454bd40fa040
parent8dd5cd0bc1d683c30805e1dc831cac546b621a75 (diff)
parent91f079aacf2dcb7352b18bc909528f7af7ef506f (diff)
downloadrust-c817d5dc2050ec443516f9700c19b1419593a83d.tar.gz
rust-c817d5dc2050ec443516f9700c19b1419593a83d.zip
Auto merge of #131098 - GuillaumeGomez:rollup-kk74was, r=GuillaumeGomez
Rollup of 5 pull requests

Successful merges:

 - #130630 (Support clobber_abi and vector/access registers (clobber-only) in s390x inline assembly)
 - #131042 (Instantiate binders in `supertrait_vtable_slot`)
 - #131079 (Update wasm-component-ld to 0.5.9)
 - #131085 (make test_lots_of_insertions test take less long in Miri)
 - #131088 (add fixme to remove LLVM_ENABLE_TERMINFO when minimal llvm version is 19)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock48
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/asm/mod.rs29
-rw-r--r--compiler/rustc_target/src/asm/s390x.rs111
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs90
-rw-r--r--library/std/src/collections/hash/map/tests.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs1
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md7
-rw-r--r--src/tools/wasm-component-ld/Cargo.toml2
-rw-r--r--tests/codegen/asm-s390x-clobbers.rs50
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs15
14 files changed, 316 insertions, 71 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 582b5a763e6..6c1071ccbc2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5768,16 +5768,16 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
 
 [[package]]
 name = "wasm-component-ld"
-version = "0.5.8"
+version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb17cdbc91766d4ea0bcd6026c36ba77a21b5c8199aeb1f0993461fe6a6bec2b"
+checksum = "fde17bc96539700198e12516230c76095cc215c84ef39ad206e1af3f84243e0f"
 dependencies = [
  "anyhow",
  "clap",
  "lexopt",
  "tempfile",
  "wasi-preview1-component-adapter-provider",
- "wasmparser 0.217.0",
+ "wasmparser 0.218.0",
  "wat",
  "wit-component",
  "wit-parser",
@@ -5801,19 +5801,19 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.217.0"
+version = "0.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760"
+checksum = "22b896fa8ceb71091ace9bcb81e853f54043183a1c9667cf93422c40252ffa0a"
 dependencies = [
  "leb128",
- "wasmparser 0.217.0",
+ "wasmparser 0.218.0",
 ]
 
 [[package]]
 name = "wasm-metadata"
-version = "0.217.0"
+version = "0.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65a146bf9a60e9264f0548a2599aa9656dba9a641eff9ab88299dc2a637e483c"
+checksum = "aa5eeb071abe8a2132fdd5565dabffee70775ee8c24fc7e300ac43f51f4a8a91"
 dependencies = [
  "anyhow",
  "indexmap",
@@ -5821,8 +5821,8 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "spdx",
- "wasm-encoder 0.217.0",
- "wasmparser 0.217.0",
+ "wasm-encoder 0.218.0",
+ "wasmparser 0.218.0",
 ]
 
 [[package]]
@@ -5837,9 +5837,9 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.217.0"
+version = "0.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca917a21307d3adf2b9857b94dd05ebf8496bdcff4437a9b9fb3899d3e6c74e7"
+checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc"
 dependencies = [
  "ahash",
  "bitflags 2.6.0",
@@ -5851,22 +5851,22 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "217.0.0"
+version = "218.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7"
+checksum = "8a53cd1f0fa505df97557e36a58bddb8296e2fcdcd089529545ebfdb18a1b9d7"
 dependencies = [
  "bumpalo",
  "leb128",
  "memchr",
  "unicode-width",
- "wasm-encoder 0.217.0",
+ "wasm-encoder 0.218.0",
 ]
 
 [[package]]
 name = "wat"
-version = "1.217.0"
+version = "1.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088"
+checksum = "4f87f8e14e776762e07927c27c2054d2cf678aab9aae2d431a79b3e31e4dd391"
 dependencies = [
  "wast",
 ]
@@ -6143,9 +6143,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.217.0"
+version = "0.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7117809905e49db716d81e794f79590c052bf2fdbbcda1731ca0fb28f6f3ddf"
+checksum = "aa53aa7e6bf2b3e8ccaffbcc963fbdb672a603dc0af393a481b6cec24c266406"
 dependencies = [
  "anyhow",
  "bitflags 2.6.0",
@@ -6154,17 +6154,17 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "wasm-encoder 0.217.0",
+ "wasm-encoder 0.218.0",
  "wasm-metadata",
- "wasmparser 0.217.0",
+ "wasmparser 0.218.0",
  "wit-parser",
 ]
 
 [[package]]
 name = "wit-parser"
-version = "0.217.0"
+version = "0.218.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb893dcd6d370cfdf19a0d9adfcd403efb8e544e1a0ea3a8b81a21fe392eaa78"
+checksum = "0d3d1066ab761b115f97fef2b191090faabcb0f37b555b758d3caf42d4ed9e55"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -6175,7 +6175,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.217.0",
+ "wasmparser 0.218.0",
 ]
 
 [[package]]
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 13a00f7e08d..a04cd4735f4 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -682,6 +682,11 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
             InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
+            InlineAsmRegClass::S390x(
+                S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg,
+            ) => {
+                unreachable!("clobber-only")
+            }
             InlineAsmRegClass::Err => unreachable!(),
         },
     };
@@ -757,6 +762,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
             S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
         ) => cx.type_i32(),
         InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
+        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+            unreachable!("clobber-only")
+        }
         InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 7621f111fe2..82ca3f519f7 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -708,6 +708,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
             S390x(S390xInlineAsmRegClass::reg) => "r",
             S390x(S390xInlineAsmRegClass::reg_addr) => "a",
             S390x(S390xInlineAsmRegClass::freg) => "f",
+            S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+                unreachable!("clobber-only")
+            }
             Msp430(Msp430InlineAsmRegClass::reg) => "r",
             M68k(M68kInlineAsmRegClass::reg) => "r",
             M68k(M68kInlineAsmRegClass::reg_addr) => "a",
@@ -866,6 +869,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
         Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
         S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
         S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
+        S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
+            unreachable!("clobber-only")
+        }
         Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
         M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
         M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8f226b26bef..e8aa129c6cd 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -411,6 +411,7 @@ symbols! {
         arbitrary_enum_discriminant,
         arbitrary_self_types,
         arbitrary_self_types_pointers,
+        areg,
         args,
         arith_offset,
         arm,
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 4d8c5cea8a8..df13d24cb9e 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -439,7 +439,7 @@ impl InlineAsmReg {
             Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
             Self::LoongArch(_) => cb(self),
             Self::Mips(_) => cb(self),
-            Self::S390x(_) => cb(self),
+            Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
             Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
             Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
             Self::Msp430(_) => cb(self),
@@ -892,6 +892,7 @@ pub enum InlineAsmClobberAbi {
     AArch64NoX18,
     RiscV,
     LoongArch,
+    S390x,
 }
 
 impl InlineAsmClobberAbi {
@@ -941,6 +942,10 @@ impl InlineAsmClobberAbi {
                 "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
                 _ => Err(&["C", "system"]),
             },
+            InlineAsmArch::S390x => match name {
+                "C" | "system" => Ok(InlineAsmClobberAbi::S390x),
+                _ => Err(&["C", "system"]),
+            },
             _ => Err(&[]),
         }
     }
@@ -1098,6 +1103,28 @@ impl InlineAsmClobberAbi {
                     f16, f17, f18, f19, f20, f21, f22, f23,
                 }
             },
+            InlineAsmClobberAbi::S390x => clobbered_regs! {
+                S390x S390xInlineAsmReg {
+                    r0, r1, r2, r3, r4, r5,
+                    r14,
+
+                    // f0-f7, v0-v7
+                    f0, f1, f2, f3, f4, f5, f6, f7,
+                    v0, v1, v2, v3, v4, v5, v6, v7,
+
+                    // Technically the left halves of v8-v15 (i.e., f8-f15) are saved, but
+                    // we have no way of expressing this using clobbers.
+                    v8, v9, v10, v11, v12, v13, v14, v15,
+
+                    // Other vector registers are volatile
+                    v16, v17, v18, v19, v20, v21, v22, v23,
+                    v24, v25, v26, v27, v28, v29, v30, v31,
+
+                    // a0-a1 are reserved, other access registers are volatile
+                    a2, a3, a4, a5, a6, a7,
+                    a8, a9, a10, a11, a12, a13, a14, a15,
+                }
+            },
         }
     }
 }
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 4258b23ac57..9b31190a72b 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -9,6 +9,8 @@ def_reg_class! {
         reg,
         reg_addr,
         freg,
+        vreg,
+        areg,
     }
 }
 
@@ -35,11 +37,13 @@ impl S390xInlineAsmRegClass {
 
     pub fn supported_types(
         self,
-        arch: InlineAsmArch,
+        _arch: InlineAsmArch,
     ) -> &'static [(InlineAsmType, Option<Symbol>)] {
-        match (self, arch) {
-            (Self::reg | Self::reg_addr, _) => types! { _: I8, I16, I32, I64; },
-            (Self::freg, _) => types! { _: F32, F64; },
+        match self {
+            Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
+            Self::freg => types! { _: F32, F64; },
+            Self::vreg => &[],
+            Self::areg => &[],
         }
     }
 }
@@ -76,6 +80,52 @@ def_regs! {
         f13: freg = ["f13"],
         f14: freg = ["f14"],
         f15: freg = ["f15"],
+        v0: vreg = ["v0"],
+        v1: vreg = ["v1"],
+        v2: vreg = ["v2"],
+        v3: vreg = ["v3"],
+        v4: vreg = ["v4"],
+        v5: vreg = ["v5"],
+        v6: vreg = ["v6"],
+        v7: vreg = ["v7"],
+        v8: vreg = ["v8"],
+        v9: vreg = ["v9"],
+        v10: vreg = ["v10"],
+        v11: vreg = ["v11"],
+        v12: vreg = ["v12"],
+        v13: vreg = ["v13"],
+        v14: vreg = ["v14"],
+        v15: vreg = ["v15"],
+        v16: vreg = ["v16"],
+        v17: vreg = ["v17"],
+        v18: vreg = ["v18"],
+        v19: vreg = ["v19"],
+        v20: vreg = ["v20"],
+        v21: vreg = ["v21"],
+        v22: vreg = ["v22"],
+        v23: vreg = ["v23"],
+        v24: vreg = ["v24"],
+        v25: vreg = ["v25"],
+        v26: vreg = ["v26"],
+        v27: vreg = ["v27"],
+        v28: vreg = ["v28"],
+        v29: vreg = ["v29"],
+        v30: vreg = ["v30"],
+        v31: vreg = ["v31"],
+        a2: areg = ["a2"],
+        a3: areg = ["a3"],
+        a4: areg = ["a4"],
+        a5: areg = ["a5"],
+        a6: areg = ["a6"],
+        a7: areg = ["a7"],
+        a8: areg = ["a8"],
+        a9: areg = ["a9"],
+        a10: areg = ["a10"],
+        a11: areg = ["a11"],
+        a12: areg = ["a12"],
+        a13: areg = ["a13"],
+        a14: areg = ["a14"],
+        a15: areg = ["a15"],
         #error = ["r11"] =>
             "The frame pointer cannot be used as an operand for inline asm",
         #error = ["r15"] =>
@@ -87,13 +137,8 @@ def_regs! {
             "c12", "c13", "c14", "c15"
         ] =>
             "control registers are reserved by the kernel and cannot be used as operands for inline asm",
-        #error = [
-            "a0", "a1", "a2", "a3",
-            "a4", "a5", "a6", "a7",
-            "a8", "a9", "a10", "a11",
-            "a12", "a13", "a14", "a15"
-        ] =>
-            "access registers are not supported and cannot be used as operands for inline asm",
+        #error = ["a0", "a1"] =>
+            "a0 and a1 are reserved for system use and cannot be used as operands for inline asm",
     }
 }
 
@@ -106,4 +151,48 @@ impl S390xInlineAsmReg {
     ) -> fmt::Result {
         write!(out, "%{}", self.name())
     }
+
+    pub fn overlapping_regs(self, mut cb: impl FnMut(S390xInlineAsmReg)) {
+        macro_rules! reg_conflicts {
+            (
+                $(
+                    $full:ident : $($field:ident)*
+                ),*;
+            ) => {
+                match self {
+                    $(
+                        Self::$full => {
+                            cb(Self::$full);
+                            $(cb(Self::$field);)*
+                        }
+                        $(Self::$field)|* => {
+                            cb(Self::$full);
+                            cb(self);
+                        }
+                    )*
+                    r => cb(r),
+                }
+            };
+        }
+
+        // The left halves of v0-v15 are aliased to f0-f15.
+        reg_conflicts! {
+            v0 : f0,
+            v1 : f1,
+            v2 : f2,
+            v3 : f3,
+            v4 : f4,
+            v5 : f5,
+            v6 : f6,
+            v7 : f7,
+            v8 : f8,
+            v9 : f9,
+            v10 : f10,
+            v11 : f11,
+            v12 : f12,
+            v13 : f13,
+            v14 : f14,
+            v15 : f15;
+        }
+    }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index de1d4ef15ac..d562692c1a8 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -9,12 +9,13 @@ use rustc_infer::infer::canonical::{
     Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
 };
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError};
+use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace};
 use rustc_macros::extension;
 use rustc_middle::arena::ArenaAllocatable;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
+use rustc_type_ir::relate::Relate;
 
 use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
 use crate::error_reporting::InferCtxtErrorExt;
@@ -133,6 +134,20 @@ where
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
 
+    pub fn eq_trace<T: Relate<TyCtxt<'tcx>>>(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        trace: TypeTrace<'tcx>,
+        expected: T,
+        actual: T,
+    ) -> Result<(), TypeError<'tcx>> {
+        self.infcx
+            .at(cause, param_env)
+            .eq_trace(DefineOpaqueTypes::Yes, trace, expected, actual)
+            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
+    }
+
     /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
     pub fn sub<T: ToTrace<'tcx>>(
         &self,
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index a2760fe6049..6e6f948a2cd 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -2,6 +2,9 @@ use std::fmt::Debug;
 use std::ops::ControlFlow;
 
 use rustc_hir::def_id::DefId;
+use rustc_infer::infer::at::ToTrace;
+use rustc_infer::infer::{BoundRegionConversionTime, TyCtxtInferExt};
+use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::util::PredicateSet;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
@@ -13,7 +16,7 @@ use smallvec::{SmallVec, smallvec};
 use tracing::debug;
 
 use crate::errors::DumpVTableEntries;
-use crate::traits::{impossible_predicates, is_vtable_safe_method};
+use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method};
 
 #[derive(Clone, Debug)]
 pub enum VtblSegment<'tcx> {
@@ -22,6 +25,8 @@ pub enum VtblSegment<'tcx> {
 }
 
 /// Prepare the segments for a vtable
+// FIXME: This should take a `PolyExistentialTraitRef`, since we don't care
+// about our `Self` type here.
 pub fn prepare_vtable_segments<'tcx, T>(
     tcx: TyCtxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
@@ -327,14 +332,10 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
     let ty::Dynamic(source, _, _) = *key.self_ty().kind() else {
         bug!();
     };
-    let source_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
-        .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let source_principal =
+        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
 
-    let target_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), key)
-        // We don't care about the self type, since it will always be the same thing.
-        .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let target_principal = ty::Binder::dummy(ty::ExistentialTraitRef::erase_self_ty(tcx, key));
 
     let vtable_segment_callback = {
         let mut vptr_offset = 0;
@@ -343,15 +344,18 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
                 VtblSegment::MetadataDSA => {
                     vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
                 }
-                VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
-                    if tcx
-                        .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref)
-                        == target_principal
-                    {
+                VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
+                    if trait_refs_are_compatible(
+                        tcx,
+                        vtable_principal
+                            .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
+                        target_principal,
+                    ) {
                         return ControlFlow::Break(vptr_offset);
                     }
 
-                    vptr_offset += tcx.own_existential_vtable_entries(trait_ref.def_id()).len();
+                    vptr_offset +=
+                        tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
 
                     if emit_vptr {
                         vptr_offset += 1;
@@ -383,17 +387,14 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
     let ty::Dynamic(target, _, _) = *target.kind() else {
         bug!();
     };
-    let target_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal()?)
-        .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let target_principal = target.principal()?;
 
     // Given that we have a target principal, it is a bug for there not to be a source principal.
     let ty::Dynamic(source, _, _) = *source.kind() else {
         bug!();
     };
-    let source_principal = tcx
-        .normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
-        .with_self_ty(tcx, tcx.types.trait_object_dummy_self);
+    let source_principal =
+        source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
 
     let vtable_segment_callback = {
         let mut vptr_offset = 0;
@@ -402,11 +403,15 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
                 VtblSegment::MetadataDSA => {
                     vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
                 }
-                VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
-                    vptr_offset += tcx.own_existential_vtable_entries(trait_ref.def_id()).len();
-                    if tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), trait_ref)
-                        == target_principal
-                    {
+                VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
+                    vptr_offset +=
+                        tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
+                    if trait_refs_are_compatible(
+                        tcx,
+                        vtable_principal
+                            .map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
+                        target_principal,
+                    ) {
                         if emit_vptr {
                             return ControlFlow::Break(Some(vptr_offset));
                         } else {
@@ -426,6 +431,41 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
     prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap()
 }
 
+fn trait_refs_are_compatible<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    hr_vtable_principal: ty::PolyExistentialTraitRef<'tcx>,
+    hr_target_principal: ty::PolyExistentialTraitRef<'tcx>,
+) -> bool {
+    if hr_vtable_principal.def_id() != hr_target_principal.def_id() {
+        return false;
+    }
+
+    let infcx = tcx.infer_ctxt().build();
+    let param_env = ty::ParamEnv::reveal_all();
+    let ocx = ObligationCtxt::new(&infcx);
+    let hr_source_principal =
+        ocx.normalize(&ObligationCause::dummy(), param_env, hr_vtable_principal);
+    let hr_target_principal =
+        ocx.normalize(&ObligationCause::dummy(), param_env, hr_target_principal);
+    infcx.enter_forall(hr_target_principal, |target_principal| {
+        let source_principal = infcx.instantiate_binder_with_fresh_vars(
+            DUMMY_SP,
+            BoundRegionConversionTime::HigherRankedType,
+            hr_source_principal,
+        );
+        let Ok(()) = ocx.eq_trace(
+            &ObligationCause::dummy(),
+            param_env,
+            ToTrace::to_trace(&ObligationCause::dummy(), hr_target_principal, hr_source_principal),
+            target_principal,
+            source_principal,
+        ) else {
+            return false;
+        };
+        ocx.select_all_or_error().is_empty()
+    })
+}
+
 pub(super) fn provide(providers: &mut Providers) {
     *providers = Providers {
         own_existential_vtable_entries,
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 2599060ef62..fa8ea95b891 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -274,7 +274,7 @@ fn test_lots_of_insertions() {
     for _ in 0..loops {
         assert!(m.is_empty());
 
-        let count = if cfg!(miri) { 101 } else { 1001 };
+        let count = if cfg!(miri) { 66 } else { 1001 };
 
         for i in 1..count {
             assert!(m.insert(i, i).is_none());
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index e4011221286..30213584157 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -344,6 +344,7 @@ impl Step for Llvm {
             .define("LLVM_INCLUDE_DOCS", "OFF")
             .define("LLVM_INCLUDE_BENCHMARKS", "OFF")
             .define("LLVM_INCLUDE_TESTS", enable_tests)
+            // FIXME: remove this when minimal llvm is 19
             .define("LLVM_ENABLE_TERMINFO", "OFF")
             .define("LLVM_ENABLE_LIBEDIT", "OFF")
             .define("LLVM_ENABLE_BINDINGS", "OFF")
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index 43e11b6d57d..b1c429c7676 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -51,7 +51,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `reg`          | `r[0-31]`                          | `r`                  |
 | CSKY         | `freg`         | `f[0-31]`                          | `f`                  |
 | s390x        | `reg`          | `r[0-10]`, `r[12-14]`              | `r`                  |
+| s390x        | `reg_addr`     | `r[1-10]`, `r[12-14]`              | `a`                  |
 | s390x        | `freg`         | `f[0-15]`                          | `f`                  |
+| s390x        | `vreg`         | `v[0-31]`                          | Only clobbers        |
+| s390x        | `areg`         | `a[2-15]`                          | Only clobbers        |
 | Arm64EC      | `reg`          | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r`            |
 | Arm64EC      | `vreg`         | `v[0-15]`                          | `w`                  |
 | Arm64EC      | `vreg_low16`   | `v[0-15]`                          | `x`                  |
@@ -90,6 +93,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `freg`                          | None           | `f32`,                                  |
 | s390x        | `reg`, `reg_addr`               | None           | `i8`, `i16`, `i32`, `i64`               |
 | s390x        | `freg`                          | None           | `f32`, `f64`                            |
+| s390x        | `vreg`                          | N/A            | Only clobbers                           |
+| s390x        | `areg`                          | N/A            | Only clobbers                           |
 | Arm64EC      | `reg`                           | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
 | Arm64EC      | `vreg`                          | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
 
@@ -157,6 +162,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `r15`                                   | This is the link register. |
 | CSKY         | `r[26-30]`                              | Reserved by its ABI.       |
 | CSKY         | `r31`                                   | This is the TLS register.  |
+| s390x        | `c[0-15]`                               | Reserved by the kernel. |
+| s390x        | `a[0-1]`                                | Reserved for system use. |
 | Arm64EC      | `xzr`                                   | This is a constant zero register which can't be modified. |
 | Arm64EC      | `x18`                                   | This is an OS-reserved register. |
 | Arm64EC      | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. |
diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml
index 91ff19ad9fc..49f4e59650e 100644
--- a/src/tools/wasm-component-ld/Cargo.toml
+++ b/src/tools/wasm-component-ld/Cargo.toml
@@ -10,4 +10,4 @@ name = "wasm-component-ld"
 path = "src/main.rs"
 
 [dependencies]
-wasm-component-ld = "0.5.4"
+wasm-component-ld = "0.5.9"
diff --git a/tests/codegen/asm-s390x-clobbers.rs b/tests/codegen/asm-s390x-clobbers.rs
new file mode 100644
index 00000000000..45f72206bdf
--- /dev/null
+++ b/tests/codegen/asm-s390x-clobbers.rs
@@ -0,0 +1,50 @@
+//@ revisions: s390x
+//@[s390x] compile-flags: --target s390x-unknown-linux-gnu
+//@[s390x] needs-llvm-components: systemz
+
+#![crate_type = "rlib"]
+#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+// CHECK-LABEL: @cc_clobber
+// CHECK: call void asm sideeffect "", "~{cc}"()
+#[no_mangle]
+pub unsafe fn cc_clobber() {
+    asm!("", options(nostack, nomem));
+}
+
+// CHECK-LABEL: @no_clobber
+// CHECK: call void asm sideeffect "", ""()
+#[no_mangle]
+pub unsafe fn no_clobber() {
+    asm!("", options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @a2_clobber
+// CHECK: call void asm sideeffect "", "~{a2}"()
+#[no_mangle]
+pub unsafe fn a2_clobber() {
+    asm!("", out("a2") _, options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @v0_clobber
+// CHECK: call void asm sideeffect "", "~{v0}"()
+#[no_mangle]
+pub unsafe fn v0_clobber() {
+    asm!("", out("v0") _, options(nostack, nomem, preserves_flags));
+}
+
+// CHECK-LABEL: @clobber_abi
+// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5},={r14},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15}"()
+#[no_mangle]
+pub unsafe fn clobber_abi() {
+    asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
+}
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
index 7f793e1269f..c4c070e49fd 100644
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
+++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
@@ -1,21 +1,22 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
-//@ check-pass
+//@ build-pass
 
-// We should be able to instantiate a binder during trait upcasting.
-// This test could be `check-pass`, but we should make sure that we
-// do so in both trait solvers.
+// Check that we are able to instantiate a binder during trait upcasting,
+// and that it doesn't cause any issues with codegen either.
 
 #![feature(trait_upcasting)]
 
 trait Supertrait<'a, 'b> {}
 trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
 
-impl<'a> Supertrait<'a, 'a> for () {}
-impl<'a> Subtrait<'a, 'a> for () {}
+impl Supertrait<'_, '_> for () {}
+impl Subtrait<'_, '_> for () {}
 fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
     x
 }
 
-fn main() {}
+fn main() {
+    ok(&());
+}