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
This commit is contained in:
commit
c817d5dc20
14 changed files with 316 additions and 71 deletions
48
Cargo.lock
48
Cargo.lock
|
@ -5768,16 +5768,16 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-component-ld"
|
name = "wasm-component-ld"
|
||||||
version = "0.5.8"
|
version = "0.5.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb17cdbc91766d4ea0bcd6026c36ba77a21b5c8199aeb1f0993461fe6a6bec2b"
|
checksum = "fde17bc96539700198e12516230c76095cc215c84ef39ad206e1af3f84243e0f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"lexopt",
|
"lexopt",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"wasi-preview1-component-adapter-provider",
|
"wasi-preview1-component-adapter-provider",
|
||||||
"wasmparser 0.217.0",
|
"wasmparser 0.218.0",
|
||||||
"wat",
|
"wat",
|
||||||
"wit-component",
|
"wit-component",
|
||||||
"wit-parser",
|
"wit-parser",
|
||||||
|
@ -5801,19 +5801,19 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-encoder"
|
name = "wasm-encoder"
|
||||||
version = "0.217.0"
|
version = "0.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760"
|
checksum = "22b896fa8ceb71091ace9bcb81e853f54043183a1c9667cf93422c40252ffa0a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"leb128",
|
"leb128",
|
||||||
"wasmparser 0.217.0",
|
"wasmparser 0.218.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-metadata"
|
name = "wasm-metadata"
|
||||||
version = "0.217.0"
|
version = "0.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65a146bf9a60e9264f0548a2599aa9656dba9a641eff9ab88299dc2a637e483c"
|
checksum = "aa5eeb071abe8a2132fdd5565dabffee70775ee8c24fc7e300ac43f51f4a8a91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
@ -5821,8 +5821,8 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"spdx",
|
"spdx",
|
||||||
"wasm-encoder 0.217.0",
|
"wasm-encoder 0.218.0",
|
||||||
"wasmparser 0.217.0",
|
"wasmparser 0.218.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5837,9 +5837,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmparser"
|
name = "wasmparser"
|
||||||
version = "0.217.0"
|
version = "0.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca917a21307d3adf2b9857b94dd05ebf8496bdcff4437a9b9fb3899d3e6c74e7"
|
checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
|
@ -5851,22 +5851,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wast"
|
name = "wast"
|
||||||
version = "217.0.0"
|
version = "218.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7"
|
checksum = "8a53cd1f0fa505df97557e36a58bddb8296e2fcdcd089529545ebfdb18a1b9d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"leb128",
|
"leb128",
|
||||||
"memchr",
|
"memchr",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"wasm-encoder 0.217.0",
|
"wasm-encoder 0.218.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wat"
|
name = "wat"
|
||||||
version = "1.217.0"
|
version = "1.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088"
|
checksum = "4f87f8e14e776762e07927c27c2054d2cf678aab9aae2d431a79b3e31e4dd391"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wast",
|
"wast",
|
||||||
]
|
]
|
||||||
|
@ -6143,9 +6143,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-component"
|
name = "wit-component"
|
||||||
version = "0.217.0"
|
version = "0.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7117809905e49db716d81e794f79590c052bf2fdbbcda1731ca0fb28f6f3ddf"
|
checksum = "aa53aa7e6bf2b3e8ccaffbcc963fbdb672a603dc0af393a481b6cec24c266406"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
|
@ -6154,17 +6154,17 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"wasm-encoder 0.217.0",
|
"wasm-encoder 0.218.0",
|
||||||
"wasm-metadata",
|
"wasm-metadata",
|
||||||
"wasmparser 0.217.0",
|
"wasmparser 0.218.0",
|
||||||
"wit-parser",
|
"wit-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-parser"
|
name = "wit-parser"
|
||||||
version = "0.217.0"
|
version = "0.218.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb893dcd6d370cfdf19a0d9adfcd403efb8e544e1a0ea3a8b81a21fe392eaa78"
|
checksum = "0d3d1066ab761b115f97fef2b191090faabcb0f37b555b758d3caf42d4ed9e55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"id-arena",
|
"id-arena",
|
||||||
|
@ -6175,7 +6175,7 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
"wasmparser 0.217.0",
|
"wasmparser 0.218.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -682,6 +682,11 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
|
||||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
|
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
|
||||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
||||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
|
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
|
||||||
|
InlineAsmRegClass::S390x(
|
||||||
|
S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg,
|
||||||
|
) => {
|
||||||
|
unreachable!("clobber-only")
|
||||||
|
}
|
||||||
InlineAsmRegClass::Err => unreachable!(),
|
InlineAsmRegClass::Err => unreachable!(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -757,6 +762,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
|
||||||
S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
|
S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
|
||||||
) => cx.type_i32(),
|
) => cx.type_i32(),
|
||||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
|
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
|
||||||
|
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
|
||||||
|
unreachable!("clobber-only")
|
||||||
|
}
|
||||||
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
|
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
|
||||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
|
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
|
||||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
||||||
|
|
|
@ -708,6 +708,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
|
||||||
S390x(S390xInlineAsmRegClass::reg) => "r",
|
S390x(S390xInlineAsmRegClass::reg) => "r",
|
||||||
S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
||||||
S390x(S390xInlineAsmRegClass::freg) => "f",
|
S390x(S390xInlineAsmRegClass::freg) => "f",
|
||||||
|
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
|
||||||
|
unreachable!("clobber-only")
|
||||||
|
}
|
||||||
Msp430(Msp430InlineAsmRegClass::reg) => "r",
|
Msp430(Msp430InlineAsmRegClass::reg) => "r",
|
||||||
M68k(M68kInlineAsmRegClass::reg) => "r",
|
M68k(M68kInlineAsmRegClass::reg) => "r",
|
||||||
M68k(M68kInlineAsmRegClass::reg_addr) => "a",
|
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(),
|
Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
|
||||||
S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
||||||
S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
|
S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
|
||||||
|
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
|
||||||
|
unreachable!("clobber-only")
|
||||||
|
}
|
||||||
Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
|
Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
|
||||||
M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
|
M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
|
||||||
M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
||||||
|
|
|
@ -411,6 +411,7 @@ symbols! {
|
||||||
arbitrary_enum_discriminant,
|
arbitrary_enum_discriminant,
|
||||||
arbitrary_self_types,
|
arbitrary_self_types,
|
||||||
arbitrary_self_types_pointers,
|
arbitrary_self_types_pointers,
|
||||||
|
areg,
|
||||||
args,
|
args,
|
||||||
arith_offset,
|
arith_offset,
|
||||||
arm,
|
arm,
|
||||||
|
|
|
@ -439,7 +439,7 @@ impl InlineAsmReg {
|
||||||
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
|
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
|
||||||
Self::LoongArch(_) => cb(self),
|
Self::LoongArch(_) => cb(self),
|
||||||
Self::Mips(_) => 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::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
|
||||||
Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
|
Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
|
||||||
Self::Msp430(_) => cb(self),
|
Self::Msp430(_) => cb(self),
|
||||||
|
@ -892,6 +892,7 @@ pub enum InlineAsmClobberAbi {
|
||||||
AArch64NoX18,
|
AArch64NoX18,
|
||||||
RiscV,
|
RiscV,
|
||||||
LoongArch,
|
LoongArch,
|
||||||
|
S390x,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlineAsmClobberAbi {
|
impl InlineAsmClobberAbi {
|
||||||
|
@ -941,6 +942,10 @@ impl InlineAsmClobberAbi {
|
||||||
"C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
|
"C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
|
||||||
_ => Err(&["C", "system"]),
|
_ => Err(&["C", "system"]),
|
||||||
},
|
},
|
||||||
|
InlineAsmArch::S390x => match name {
|
||||||
|
"C" | "system" => Ok(InlineAsmClobberAbi::S390x),
|
||||||
|
_ => Err(&["C", "system"]),
|
||||||
|
},
|
||||||
_ => Err(&[]),
|
_ => Err(&[]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1098,6 +1103,28 @@ impl InlineAsmClobberAbi {
|
||||||
f16, f17, f18, f19, f20, f21, f22, f23,
|
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,
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ def_reg_class! {
|
||||||
reg,
|
reg,
|
||||||
reg_addr,
|
reg_addr,
|
||||||
freg,
|
freg,
|
||||||
|
vreg,
|
||||||
|
areg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +37,13 @@ impl S390xInlineAsmRegClass {
|
||||||
|
|
||||||
pub fn supported_types(
|
pub fn supported_types(
|
||||||
self,
|
self,
|
||||||
arch: InlineAsmArch,
|
_arch: InlineAsmArch,
|
||||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||||
match (self, arch) {
|
match self {
|
||||||
(Self::reg | Self::reg_addr, _) => types! { _: I8, I16, I32, I64; },
|
Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
|
||||||
(Self::freg, _) => types! { _: F32, F64; },
|
Self::freg => types! { _: F32, F64; },
|
||||||
|
Self::vreg => &[],
|
||||||
|
Self::areg => &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +80,52 @@ def_regs! {
|
||||||
f13: freg = ["f13"],
|
f13: freg = ["f13"],
|
||||||
f14: freg = ["f14"],
|
f14: freg = ["f14"],
|
||||||
f15: freg = ["f15"],
|
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"] =>
|
#error = ["r11"] =>
|
||||||
"The frame pointer cannot be used as an operand for inline asm",
|
"The frame pointer cannot be used as an operand for inline asm",
|
||||||
#error = ["r15"] =>
|
#error = ["r15"] =>
|
||||||
|
@ -87,13 +137,8 @@ def_regs! {
|
||||||
"c12", "c13", "c14", "c15"
|
"c12", "c13", "c14", "c15"
|
||||||
] =>
|
] =>
|
||||||
"control registers are reserved by the kernel and cannot be used as operands for inline asm",
|
"control registers are reserved by the kernel and cannot be used as operands for inline asm",
|
||||||
#error = [
|
#error = ["a0", "a1"] =>
|
||||||
"a0", "a1", "a2", "a3",
|
"a0 and a1 are reserved for system use and cannot be used as operands for inline asm",
|
||||||
"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",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,4 +151,48 @@ impl S390xInlineAsmReg {
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
write!(out, "%{}", self.name())
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,13 @@ use rustc_infer::infer::canonical::{
|
||||||
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
|
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
|
||||||
};
|
};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
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_macros::extension;
|
||||||
use rustc_middle::arena::ArenaAllocatable;
|
use rustc_middle::arena::ArenaAllocatable;
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance};
|
||||||
|
use rustc_type_ir::relate::Relate;
|
||||||
|
|
||||||
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
|
use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
|
||||||
use crate::error_reporting::InferCtxtErrorExt;
|
use crate::error_reporting::InferCtxtErrorExt;
|
||||||
|
@ -133,6 +134,20 @@ where
|
||||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
.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`.
|
/// Checks whether `expected` is a subtype of `actual`: `expected <: actual`.
|
||||||
pub fn sub<T: ToTrace<'tcx>>(
|
pub fn sub<T: ToTrace<'tcx>>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -2,6 +2,9 @@ use std::fmt::Debug;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use rustc_hir::def_id::DefId;
|
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_infer::traits::util::PredicateSet;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
@ -13,7 +16,7 @@ use smallvec::{SmallVec, smallvec};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::errors::DumpVTableEntries;
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum VtblSegment<'tcx> {
|
pub enum VtblSegment<'tcx> {
|
||||||
|
@ -22,6 +25,8 @@ pub enum VtblSegment<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prepare the segments for a vtable
|
/// 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>(
|
pub fn prepare_vtable_segments<'tcx, T>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'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 {
|
let ty::Dynamic(source, _, _) = *key.self_ty().kind() else {
|
||||||
bug!();
|
bug!();
|
||||||
};
|
};
|
||||||
let source_principal = tcx
|
let source_principal =
|
||||||
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
|
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
|
||||||
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
|
|
||||||
|
|
||||||
let target_principal = tcx
|
let target_principal = ty::Binder::dummy(ty::ExistentialTraitRef::erase_self_ty(tcx, key));
|
||||||
.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 vtable_segment_callback = {
|
let vtable_segment_callback = {
|
||||||
let mut vptr_offset = 0;
|
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 => {
|
VtblSegment::MetadataDSA => {
|
||||||
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
|
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
|
||||||
}
|
}
|
||||||
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
|
VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
|
||||||
if tcx
|
if trait_refs_are_compatible(
|
||||||
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), trait_ref)
|
tcx,
|
||||||
== target_principal
|
vtable_principal
|
||||||
{
|
.map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
|
||||||
|
target_principal,
|
||||||
|
) {
|
||||||
return ControlFlow::Break(vptr_offset);
|
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 {
|
if emit_vptr {
|
||||||
vptr_offset += 1;
|
vptr_offset += 1;
|
||||||
|
@ -383,17 +387,14 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
|
||||||
let ty::Dynamic(target, _, _) = *target.kind() else {
|
let ty::Dynamic(target, _, _) = *target.kind() else {
|
||||||
bug!();
|
bug!();
|
||||||
};
|
};
|
||||||
let target_principal = tcx
|
let target_principal = target.principal()?;
|
||||||
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), target.principal()?)
|
|
||||||
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
|
|
||||||
|
|
||||||
// Given that we have a target principal, it is a bug for there not to be a source 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 {
|
let ty::Dynamic(source, _, _) = *source.kind() else {
|
||||||
bug!();
|
bug!();
|
||||||
};
|
};
|
||||||
let source_principal = tcx
|
let source_principal =
|
||||||
.normalize_erasing_regions(ty::ParamEnv::reveal_all(), source.principal().unwrap())
|
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self);
|
||||||
.with_self_ty(tcx, tcx.types.trait_object_dummy_self);
|
|
||||||
|
|
||||||
let vtable_segment_callback = {
|
let vtable_segment_callback = {
|
||||||
let mut vptr_offset = 0;
|
let mut vptr_offset = 0;
|
||||||
|
@ -402,11 +403,15 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
|
||||||
VtblSegment::MetadataDSA => {
|
VtblSegment::MetadataDSA => {
|
||||||
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
|
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
|
||||||
}
|
}
|
||||||
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
|
VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => {
|
||||||
vptr_offset += tcx.own_existential_vtable_entries(trait_ref.def_id()).len();
|
vptr_offset +=
|
||||||
if tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), trait_ref)
|
tcx.own_existential_vtable_entries(vtable_principal.def_id()).len();
|
||||||
== target_principal
|
if trait_refs_are_compatible(
|
||||||
{
|
tcx,
|
||||||
|
vtable_principal
|
||||||
|
.map_bound(|t| ty::ExistentialTraitRef::erase_self_ty(tcx, t)),
|
||||||
|
target_principal,
|
||||||
|
) {
|
||||||
if emit_vptr {
|
if emit_vptr {
|
||||||
return ControlFlow::Break(Some(vptr_offset));
|
return ControlFlow::Break(Some(vptr_offset));
|
||||||
} else {
|
} else {
|
||||||
|
@ -426,6 +431,41 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
|
||||||
prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap()
|
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) {
|
pub(super) fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
own_existential_vtable_entries,
|
own_existential_vtable_entries,
|
||||||
|
|
|
@ -274,7 +274,7 @@ fn test_lots_of_insertions() {
|
||||||
for _ in 0..loops {
|
for _ in 0..loops {
|
||||||
assert!(m.is_empty());
|
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 {
|
for i in 1..count {
|
||||||
assert!(m.insert(i, i).is_none());
|
assert!(m.insert(i, i).is_none());
|
||||||
|
|
|
@ -344,6 +344,7 @@ impl Step for Llvm {
|
||||||
.define("LLVM_INCLUDE_DOCS", "OFF")
|
.define("LLVM_INCLUDE_DOCS", "OFF")
|
||||||
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
|
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
|
||||||
.define("LLVM_INCLUDE_TESTS", enable_tests)
|
.define("LLVM_INCLUDE_TESTS", enable_tests)
|
||||||
|
// FIXME: remove this when minimal llvm is 19
|
||||||
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
||||||
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
||||||
.define("LLVM_ENABLE_BINDINGS", "OFF")
|
.define("LLVM_ENABLE_BINDINGS", "OFF")
|
||||||
|
|
|
@ -51,7 +51,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
|
||||||
| CSKY | `reg` | `r[0-31]` | `r` |
|
| CSKY | `reg` | `r[0-31]` | `r` |
|
||||||
| CSKY | `freg` | `f[0-31]` | `f` |
|
| CSKY | `freg` | `f[0-31]` | `f` |
|
||||||
| s390x | `reg` | `r[0-10]`, `r[12-14]` | `r` |
|
| 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 | `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 | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` |
|
||||||
| Arm64EC | `vreg` | `v[0-15]` | `w` |
|
| Arm64EC | `vreg` | `v[0-15]` | `w` |
|
||||||
| Arm64EC | `vreg_low16` | `v[0-15]` | `x` |
|
| 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`, |
|
| CSKY | `freg` | None | `f32`, |
|
||||||
| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` |
|
| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` |
|
||||||
| s390x | `freg` | None | `f32`, `f64` |
|
| 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 | `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` |
|
| 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 | `r15` | This is the link register. |
|
||||||
| CSKY | `r[26-30]` | Reserved by its ABI. |
|
| CSKY | `r[26-30]` | Reserved by its ABI. |
|
||||||
| CSKY | `r31` | This is the TLS register. |
|
| 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 | `xzr` | This is a constant zero register which can't be modified. |
|
||||||
| Arm64EC | `x18` | This is an OS-reserved register. |
|
| 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. |
|
| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. |
|
||||||
|
|
|
@ -10,4 +10,4 @@ name = "wasm-component-ld"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-component-ld = "0.5.4"
|
wasm-component-ld = "0.5.9"
|
||||||
|
|
50
tests/codegen/asm-s390x-clobbers.rs
Normal file
50
tests/codegen/asm-s390x-clobbers.rs
Normal file
|
@ -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));
|
||||||
|
}
|
|
@ -1,21 +1,22 @@
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@ check-pass
|
//@ build-pass
|
||||||
|
|
||||||
// We should be able to instantiate a binder during trait upcasting.
|
// Check that we are able to instantiate a binder during trait upcasting,
|
||||||
// This test could be `check-pass`, but we should make sure that we
|
// and that it doesn't cause any issues with codegen either.
|
||||||
// do so in both trait solvers.
|
|
||||||
|
|
||||||
#![feature(trait_upcasting)]
|
#![feature(trait_upcasting)]
|
||||||
|
|
||||||
trait Supertrait<'a, 'b> {}
|
trait Supertrait<'a, 'b> {}
|
||||||
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
|
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
|
||||||
|
|
||||||
impl<'a> Supertrait<'a, 'a> for () {}
|
impl Supertrait<'_, '_> for () {}
|
||||||
impl<'a> Subtrait<'a, 'a> for () {}
|
impl Subtrait<'_, '_> for () {}
|
||||||
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
|
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
ok(&());
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue