summaryrefslogtreecommitdiffstats
path: root/src/test/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/README.md22
-rw-r--r--src/test/codegen/abi-repr-ext.rs46
-rw-r--r--src/test/codegen/asm-may_unwind.rs1
-rw-r--r--src/test/codegen/async-fn-debug-awaitee-field.rs4
-rw-r--r--src/test/codegen/async-fn-debug-msvc.rs7
-rw-r--r--src/test/codegen/atomic-operations-llvm-12.rs84
-rw-r--r--src/test/codegen/atomic-operations.rs1
-rw-r--r--src/test/codegen/avr/avr-func-addrspace.rs2
-rw-r--r--src/test/codegen/branch-protection.rs1
-rw-r--r--src/test/codegen/debug-vtable.rs2
-rw-r--r--src/test/codegen/external-no-mangle-statics.rs5
-rw-r--r--src/test/codegen/generator-debug-msvc.rs12
-rw-r--r--src/test/codegen/generator-debug.rs4
-rw-r--r--src/test/codegen/instrument-coverage.rs17
-rw-r--r--src/test/codegen/intrinsics/mask.rs11
-rw-r--r--src/test/codegen/issue-34634.rs2
-rw-r--r--src/test/codegen/issue-85872-multiple-reverse.rs20
-rw-r--r--src/test/codegen/issue-96274.rs17
-rw-r--r--src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs19
-rw-r--r--src/test/codegen/layout-size-checks.rs31
-rw-r--r--src/test/codegen/mem-replace-direct-memcpy.rs12
-rw-r--r--src/test/codegen/merge-functions.rs7
-rw-r--r--src/test/codegen/mir-inlined-line-numbers.rs25
-rw-r--r--src/test/codegen/pic-relocation-model.rs7
-rw-r--r--src/test/codegen/pie-relocation-model.rs2
-rw-r--r--src/test/codegen/some-abis-do-extend-params-to-32-bits.rs204
-rw-r--r--src/test/codegen/try_question_mark_nop.rs54
-rw-r--r--src/test/codegen/unwind-abis/aapcs-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs2
-rw-r--r--src/test/codegen/unwind-abis/c-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/cdecl-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/fastcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs2
-rw-r--r--src/test/codegen/unwind-abis/nounwind.rs2
-rw-r--r--src/test/codegen/unwind-abis/stdcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/system-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/sysv64-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/thiscall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-abis/win64-unwind-abi.rs2
-rw-r--r--src/test/codegen/unwind-extern-exports.rs2
42 files changed, 510 insertions, 139 deletions
diff --git a/src/test/codegen/README.md b/src/test/codegen/README.md
index 00de55eea..8f2daaafc 100644
--- a/src/test/codegen/README.md
+++ b/src/test/codegen/README.md
@@ -1,2 +1,24 @@
The files here use the LLVM FileCheck framework, documented at
<https://llvm.org/docs/CommandGuide/FileCheck.html>.
+
+One extension worth noting is the use of revisions as custom prefixes for
+FileCheck. If your codegen test has different behavior based on the chosen
+target or different compiler flags that you want to exercise, you can use a
+revisions annotation, like so:
+
+```rust
+// revisions: aaa bbb
+// [bbb] compile-flags: --flags-for-bbb
+```
+
+After specifying those variations, you can write different expected, or
+explicitly *unexpected* output by using `<prefix>-SAME:` and `<prefix>-NOT:`,
+like so:
+
+```rust
+// CHECK: expected code
+// aaa-SAME: emitted-only-for-aaa
+// aaa-NOT: emitted-only-for-bbb
+// bbb-NOT: emitted-only-for-aaa
+// bbb-SAME: emitted-only-for-bbb
+```
diff --git a/src/test/codegen/abi-repr-ext.rs b/src/test/codegen/abi-repr-ext.rs
index 2b34eaf94..23ade3c72 100644
--- a/src/test/codegen/abi-repr-ext.rs
+++ b/src/test/codegen/abi-repr-ext.rs
@@ -1,6 +1,32 @@
// compile-flags: -O
-#![crate_type="lib"]
+// revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv
+
+//[x86_64] compile-flags: --target x86_64-unknown-uefi
+//[x86_64] needs-llvm-components: x86
+//[i686] compile-flags: --target i686-unknown-linux-musl
+//[i686] needs-llvm-components: x86
+//[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc
+//[aarch64-windows] needs-llvm-components: aarch64
+//[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64-linux] needs-llvm-components: aarch64
+//[aarch64-apple] compile-flags: --target aarch64-apple-darwin
+//[aarch64-apple] needs-llvm-components: aarch64
+//[arm] compile-flags: --target armv7r-none-eabi
+//[arm] needs-llvm-components: arm
+//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
+//[riscv] needs-llvm-components: riscv
+
+// See bottom of file for a corresponding C source file that is meant to yield
+// equivalent declarations.
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
#[repr(i8)]
pub enum Type {
@@ -8,7 +34,23 @@ pub enum Type {
Type2 = 1
}
-// CHECK: define{{( dso_local)?}} noundef signext i8 @test()
+// To accommodate rust#97800, one might consider writing the below as:
+//
+// `define{{( dso_local)?}} noundef{{( signext)?}} i8 @test()`
+//
+// but based on rust#80556, it seems important to actually check for the
+// presence of the `signext` for those targets where we expect it.
+
+// CHECK: define{{( dso_local)?}} noundef
+// x86_64-SAME: signext
+// aarch64-apple-SAME: signext
+// aarch64-windows-NOT: signext
+// aarch64-linux-NOT: signext
+// arm-SAME: signext
+// riscv-SAME: signext
+// CHECK-SAME: i8 @test()
+
+
#[no_mangle]
pub extern "C" fn test() -> Type {
Type::Type1
diff --git a/src/test/codegen/asm-may_unwind.rs b/src/test/codegen/asm-may_unwind.rs
index bf4202764..c97933035 100644
--- a/src/test/codegen/asm-may_unwind.rs
+++ b/src/test/codegen/asm-may_unwind.rs
@@ -1,4 +1,3 @@
-// min-llvm-version: 13.0.0
// compile-flags: -O
// only-x86_64
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
index efb345fa9..909cd0062 100644
--- a/src/test/codegen/async-fn-debug-awaitee-field.rs
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -12,11 +12,11 @@ async fn async_fn_test() {
}
// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
-// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
fn main() {
let _fn = async_fn_test();
diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs
index 8995605e3..73c652c9d 100644
--- a/src/test/codegen/async-fn-debug-msvc.rs
+++ b/src/test/codegen/async-fn-debug-msvc.rs
@@ -16,7 +16,7 @@ async fn async_fn_test() {
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>",
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 11,
@@ -36,16 +36,17 @@ async fn async_fn_test() {
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 14,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], file: !2, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
diff --git a/src/test/codegen/atomic-operations-llvm-12.rs b/src/test/codegen/atomic-operations-llvm-12.rs
deleted file mode 100644
index bd4c63dcf..000000000
--- a/src/test/codegen/atomic-operations-llvm-12.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-// Code generation of atomic operations for LLVM 12
-// ignore-llvm-version: 13 - 99
-// compile-flags: -O
-#![crate_type = "lib"]
-
-use std::sync::atomic::{AtomicI32, Ordering::*};
-
-// CHECK-LABEL: @compare_exchange
-#[no_mangle]
-pub fn compare_exchange(a: &AtomicI32) {
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 10 monotonic monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 11 acquire acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 12 seq_cst seq_cst
- let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
- let _ = a.compare_exchange(0, 11, Relaxed, Acquire);
- let _ = a.compare_exchange(0, 12, Relaxed, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 20 release monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 21 acq_rel acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 22 seq_cst seq_cst
- let _ = a.compare_exchange(0, 20, Release, Relaxed);
- let _ = a.compare_exchange(0, 21, Release, Acquire);
- let _ = a.compare_exchange(0, 22, Release, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 30 acquire monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 31 acquire acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 32 seq_cst seq_cst
- let _ = a.compare_exchange(0, 30, Acquire, Relaxed);
- let _ = a.compare_exchange(0, 31, Acquire, Acquire);
- let _ = a.compare_exchange(0, 32, Acquire, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 40 acq_rel monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 41 acq_rel acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 42 seq_cst seq_cst
- let _ = a.compare_exchange(0, 40, AcqRel, Relaxed);
- let _ = a.compare_exchange(0, 41, AcqRel, Acquire);
- let _ = a.compare_exchange(0, 42, AcqRel, SeqCst);
-
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 50 seq_cst monotonic
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 51 seq_cst acquire
- // CHECK: cmpxchg i32* %{{.*}}, i32 0, i32 52 seq_cst seq_cst
- let _ = a.compare_exchange(0, 50, SeqCst, Relaxed);
- let _ = a.compare_exchange(0, 51, SeqCst, Acquire);
- let _ = a.compare_exchange(0, 52, SeqCst, SeqCst);
-}
-
-// CHECK-LABEL: @compare_exchange_weak
-#[no_mangle]
-pub fn compare_exchange_weak(w: &AtomicI32) {
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 10 monotonic monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 11 acquire acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 12 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 10, Relaxed, Relaxed);
- let _ = w.compare_exchange_weak(1, 11, Relaxed, Acquire);
- let _ = w.compare_exchange_weak(1, 12, Relaxed, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 20 release monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 21 acq_rel acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 22 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 20, Release, Relaxed);
- let _ = w.compare_exchange_weak(1, 21, Release, Acquire);
- let _ = w.compare_exchange_weak(1, 22, Release, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 30 acquire monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 31 acquire acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 32 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 30, Acquire, Relaxed);
- let _ = w.compare_exchange_weak(1, 31, Acquire, Acquire);
- let _ = w.compare_exchange_weak(1, 32, Acquire, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 40 acq_rel monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 41 acq_rel acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 42 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 40, AcqRel, Relaxed);
- let _ = w.compare_exchange_weak(1, 41, AcqRel, Acquire);
- let _ = w.compare_exchange_weak(1, 42, AcqRel, SeqCst);
-
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 50 seq_cst monotonic
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 51 seq_cst acquire
- // CHECK: cmpxchg weak i32* %{{.*}}, i32 1, i32 52 seq_cst seq_cst
- let _ = w.compare_exchange_weak(1, 50, SeqCst, Relaxed);
- let _ = w.compare_exchange_weak(1, 51, SeqCst, Acquire);
- let _ = w.compare_exchange_weak(1, 52, SeqCst, SeqCst);
-}
diff --git a/src/test/codegen/atomic-operations.rs b/src/test/codegen/atomic-operations.rs
index 771cf5872..d2bc618df 100644
--- a/src/test/codegen/atomic-operations.rs
+++ b/src/test/codegen/atomic-operations.rs
@@ -1,5 +1,4 @@
// Code generation of atomic operations.
-// min-llvm-version: 13.0
// compile-flags: -O
#![crate_type = "lib"]
diff --git a/src/test/codegen/avr/avr-func-addrspace.rs b/src/test/codegen/avr/avr-func-addrspace.rs
index 530164edd..a038dfe76 100644
--- a/src/test/codegen/avr/avr-func-addrspace.rs
+++ b/src/test/codegen/avr/avr-func-addrspace.rs
@@ -77,7 +77,7 @@ fn update_bar_value() {
}
}
-// CHECK: define void @test(){{.+}}addrspace(1)
+// CHECK: define dso_local void @test(){{.+}}addrspace(1)
#[no_mangle]
pub extern "C" fn test() {
let mut buf = 7;
diff --git a/src/test/codegen/branch-protection.rs b/src/test/codegen/branch-protection.rs
index b23073778..994c71b26 100644
--- a/src/test/codegen/branch-protection.rs
+++ b/src/test/codegen/branch-protection.rs
@@ -1,7 +1,6 @@
// Test that the correct module flags are emitted with different branch protection flags.
// revisions: BTI PACRET LEAF BKEY NONE
-// min-llvm-version: 12.0.0
// needs-llvm-components: aarch64
// [BTI] compile-flags: -Z branch-protection=bti
// [PACRET] compile-flags: -Z branch-protection=pac-ret
diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs
index b9cb4f93d..bdd312878 100644
--- a/src/test/codegen/debug-vtable.rs
+++ b/src/test/codegen/debug-vtable.rs
@@ -46,7 +46,7 @@
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::bar::{closure_env#0} as core::ops::function::FnOnce<(core::option::Option<&dyn core::ops::function::Fn<(), Output=()>>)>>::{vtable}"
-// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > >, {{.*}}, {{.*}}, Some> > > >::vtable$"
+// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::bar::closure_env$0, core::ops::function::FnOnce<tuple$<enum2$<core::option::Option<ref$<dyn$<core::ops::function::Fn<tuple$<>,assoc$<Output,tuple$<> > > > > > > > > >::vtable$"
// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::generic_closure::{closure_env#0}<bool> as core::ops::function::FnOnce<()>>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::generic_closure::closure_env$0<bool>, core::ops::function::FnOnce<tuple$<> > >::vtable$
diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs
index 6274434cd..c6ecb7aa9 100644
--- a/src/test/codegen/external-no-mangle-statics.rs
+++ b/src/test/codegen/external-no-mangle-statics.rs
@@ -1,12 +1,11 @@
// revisions: lib staticlib
// ignore-emscripten default visibility is hidden
// compile-flags: -O
+// [lib] compile-flags: --crate-type lib
+// [staticlib] compile-flags: --crate-type staticlib
// `#[no_mangle]`d static variables always have external linkage, i.e., no `internal` in their
// definitions
-#![cfg_attr(lib, crate_type = "lib")]
-#![cfg_attr(staticlib, crate_type = "staticlib")]
-
// CHECK: @A = local_unnamed_addr constant
#[no_mangle]
static A: u8 = 0;
diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs
index 033da80be..9d70ccdef 100644
--- a/src/test/codegen/generator-debug-msvc.rs
+++ b/src/test/codegen/generator-debug-msvc.rs
@@ -20,18 +20,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// FIXME: No way to reliably check the filename.
-// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>"
+// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<generator_debug_msvc::generator_test::generator_env$0>"
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]],
// For brevity, we only check the struct name and members of the last variant.
// CHECK-SAME: file: [[FILE:![0-9]*]], line: 14,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant1", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant2", scope: [[GEN]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant3", scope: [[GEN]],
@@ -40,16 +40,18 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant4", scope: [[GEN]],
// CHECK-SAME: file: [[FILE]], line: 17,
-// CHECK-SAME: baseType: [[VARIANT:![0-9]*]]
+// CHECK-SAME: baseType: [[VARIANT_WRAPPER:![0-9]*]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
+// CHECK: [[VARIANT_WRAPPER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Variant4", scope: [[GEN]],
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "value", scope: [[VARIANT_WRAPPER]], {{.*}}, baseType: [[VARIANT:![0-9]*]],
// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]]
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
-// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]],
+// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "tag", scope: [[GEN]],
// CHECK-NOT: flags: DIFlagArtificial
fn main() {
diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs
index 9c9f5518b..3ec860f2c 100644
--- a/src/test/codegen/generator-debug.rs
+++ b/src/test/codegen/generator-debug.rs
@@ -33,11 +33,11 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> {
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]],
-// CHECK-SAME: file: [[FILE]], line: 14,
+// CHECK-SAME: file: [[FILE]], line: 18,
// CHECK-NOT: flags: DIFlagArtificial
// CHECK-SAME: )
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]],
diff --git a/src/test/codegen/instrument-coverage.rs b/src/test/codegen/instrument-coverage.rs
new file mode 100644
index 000000000..78f8875a2
--- /dev/null
+++ b/src/test/codegen/instrument-coverage.rs
@@ -0,0 +1,17 @@
+// Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR.
+
+// needs-profiler-support
+// compile-flags: -Cinstrument-coverage
+
+// CHECK: @__llvm_profile_filename = {{.*}}"default_%m_%p.profraw\00"{{.*}}
+
+#![crate_type="lib"]
+
+#[inline(never)]
+fn some_function() {
+
+}
+
+pub fn some_other_function() {
+ some_function();
+}
diff --git a/src/test/codegen/intrinsics/mask.rs b/src/test/codegen/intrinsics/mask.rs
new file mode 100644
index 000000000..2e984db1b
--- /dev/null
+++ b/src/test/codegen/intrinsics/mask.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+// CHECK-LABEL: @mask_ptr
+// CHECK-SAME: [[WORD:i[0-9]+]] %mask
+#[no_mangle]
+pub fn mask_ptr(ptr: *const u16, mask: usize) -> *const u16 {
+ // CHECK: call
+ // CHECK-SAME: @llvm.ptrmask.{{p0|p0i8}}.[[WORD]]({{ptr|i8\*}} {{%ptr|%0}}, [[WORD]] %mask)
+ core::intrinsics::ptr_mask(ptr, mask)
+}
diff --git a/src/test/codegen/issue-34634.rs b/src/test/codegen/issue-34634.rs
index 6c18adbcb..f53fa240c 100644
--- a/src/test/codegen/issue-34634.rs
+++ b/src/test/codegen/issue-34634.rs
@@ -1,5 +1,5 @@
// Test that `wrapping_div` only checks divisor once.
-// This test checks that there is only a single compare agains -1 and -1 is not present as a
+// This test checks that there is only a single compare against -1 and -1 is not present as a
// switch case (the second check present until rustc 1.12).
// This test also verifies that a single panic call is generated (for the division by zero case).
diff --git a/src/test/codegen/issue-85872-multiple-reverse.rs b/src/test/codegen/issue-85872-multiple-reverse.rs
new file mode 100644
index 000000000..591a1aca7
--- /dev/null
+++ b/src/test/codegen/issue-85872-multiple-reverse.rs
@@ -0,0 +1,20 @@
+// min-llvm-version: 15.0.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn u16_be_to_arch(mut data: [u8; 2]) -> [u8; 2] {
+ // CHECK-LABEL: @u16_be_to_arch
+ // CHECK: @llvm.bswap.i16
+ data.reverse();
+ data
+}
+
+#[no_mangle]
+pub fn u32_be_to_arch(mut data: [u8; 4]) -> [u8; 4] {
+ // CHECK-LABEL: @u32_be_to_arch
+ // CHECK: @llvm.bswap.i32
+ data.reverse();
+ data
+}
diff --git a/src/test/codegen/issue-96274.rs b/src/test/codegen/issue-96274.rs
new file mode 100644
index 000000000..28bfcce0d
--- /dev/null
+++ b/src/test/codegen/issue-96274.rs
@@ -0,0 +1,17 @@
+// min-llvm-version: 15.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+#![feature(inline_const)]
+
+use std::mem::MaybeUninit;
+
+pub fn maybe_uninit() -> [MaybeUninit<u8>; 3000] {
+ // CHECK-NOT: memset
+ [MaybeUninit::uninit(); 3000]
+}
+
+pub fn maybe_uninit_const<T>() -> [MaybeUninit<T>; 8192] {
+ // CHECK-NOT: memset
+ [const { MaybeUninit::uninit() }; 8192]
+}
diff --git a/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs b/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs
new file mode 100644
index 000000000..7da29cd79
--- /dev/null
+++ b/src/test/codegen/issue-98294-get-mut-copy-from-slice-opt.rs
@@ -0,0 +1,19 @@
+// min-llvm-version: 15.0.0
+// ignore-debug: The debug assertions get in the way
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// There should be no calls to panic / len_mismatch_fail.
+
+#[no_mangle]
+pub fn test(a: &mut [u8], offset: usize, bytes: &[u8]) {
+ // CHECK-LABEL: @test(
+ // CHECK-NOT: call
+ // CHECK: call void @llvm.memcpy
+ // CHECK-NOT: call
+ // CHECK: }
+ if let Some(dst) = a.get_mut(offset..offset + bytes.len()) {
+ dst.copy_from_slice(bytes);
+ }
+}
diff --git a/src/test/codegen/layout-size-checks.rs b/src/test/codegen/layout-size-checks.rs
new file mode 100644
index 000000000..d067cc10a
--- /dev/null
+++ b/src/test/codegen/layout-size-checks.rs
@@ -0,0 +1,31 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+use std::alloc::Layout;
+
+type RGB48 = [u16; 3];
+
+// CHECK-LABEL: @layout_array_rgb48
+#[no_mangle]
+pub fn layout_array_rgb48(n: usize) -> Layout {
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: icmp ugt i64 %n, 1537228672809129301
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: mul nuw nsw i64 %n, 6
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ Layout::array::<RGB48>(n).unwrap()
+}
+
+// CHECK-LABEL: @layout_array_i32
+#[no_mangle]
+pub fn layout_array_i32(n: usize) -> Layout {
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: icmp ugt i64 %n, 2305843009213693951
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ // CHECK: shl nuw nsw i64 %n, 2
+ // CHECK-NOT: llvm.umul.with.overflow.i64
+ Layout::array::<i32>(n).unwrap()
+}
diff --git a/src/test/codegen/mem-replace-direct-memcpy.rs b/src/test/codegen/mem-replace-direct-memcpy.rs
index 8095d309f..b41ef538d 100644
--- a/src/test/codegen/mem-replace-direct-memcpy.rs
+++ b/src/test/codegen/mem-replace-direct-memcpy.rs
@@ -1,15 +1,3 @@
-// ignore-test
-
-// WHY IS THIS TEST BEING IGNORED:
-//
-// This test depends on characteristics of how the stdlib was compiled,
-// namely that sufficient inlining occurred to ensure that the call to
-// `std::mem::replace` boils down to just two calls of `llvm.memcpy`.
-//
-// But the MIR inlining policy is in flux as of 1.64-beta, and the intermittent
-// breakage of this test that results is causing problems for people trying to
-// do development.
-
// This test ensures that `mem::replace::<T>` only ever calls `@llvm.memcpy`
// with `size_of::<T>()` as the size, and never goes through any wrapper that
// may e.g. multiply `size_of::<T>()` with a variable "count" (which is only
diff --git a/src/test/codegen/merge-functions.rs b/src/test/codegen/merge-functions.rs
index 5eefc0f98..8e8fe5c96 100644
--- a/src/test/codegen/merge-functions.rs
+++ b/src/test/codegen/merge-functions.rs
@@ -1,7 +1,10 @@
-// compile-flags: -O
+// min-llvm-version: 14.0
+// revisions: O Os
+//[Os] compile-flags: -Copt-level=s
+//[O] compile-flags: -O
#![crate_type = "lib"]
-// CHECK: @func2 = {{.*}}alias{{.*}}@func1
+// CHECK: @func{{2|1}} = {{.*}}alias{{.*}}@func{{1|2}}
#[no_mangle]
pub fn func1(c: char) -> bool {
diff --git a/src/test/codegen/mir-inlined-line-numbers.rs b/src/test/codegen/mir-inlined-line-numbers.rs
new file mode 100644
index 000000000..19d83f0ee
--- /dev/null
+++ b/src/test/codegen/mir-inlined-line-numbers.rs
@@ -0,0 +1,25 @@
+// compile-flags: -O -g
+
+#![crate_type = "lib"]
+
+#[inline(always)]
+fn foo() {
+ bar();
+}
+
+#[inline(never)]
+#[no_mangle]
+fn bar() {
+ panic!();
+}
+
+#[no_mangle]
+pub fn example() {
+ foo();
+}
+
+// CHECK-LABEL: @example
+// CHECK: tail call void @bar(), !dbg [[DBG_ID:![0-9]+]]
+// CHECK: [[DBG_ID]] = !DILocation(line: 7,
+// CHECK-SAME: inlinedAt: [[INLINE_ID:![0-9]+]])
+// CHECK: [[INLINE_ID]] = !DILocation(line: 18,
diff --git a/src/test/codegen/pic-relocation-model.rs b/src/test/codegen/pic-relocation-model.rs
index 6e1d5a6c3..602a08067 100644
--- a/src/test/codegen/pic-relocation-model.rs
+++ b/src/test/codegen/pic-relocation-model.rs
@@ -10,7 +10,10 @@ pub fn call_foreign_fn() -> u8 {
}
}
-// CHECK: declare zeroext i8 @foreign_fn()
+// (Allow but do not require `zeroext` here, because it is not worth effort to
+// spell out which targets have it and which ones do not; see rust#97800.)
+
+// CHECK: declare{{( zeroext)?}} i8 @foreign_fn()
extern "C" {fn foreign_fn() -> u8;}
-// CHECK: !{i32 7, !"PIC Level", i32 2}
+// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
diff --git a/src/test/codegen/pie-relocation-model.rs b/src/test/codegen/pie-relocation-model.rs
index a843202a9..ec44edc06 100644
--- a/src/test/codegen/pie-relocation-model.rs
+++ b/src/test/codegen/pie-relocation-model.rs
@@ -18,5 +18,5 @@ pub fn call_foreign_fn() -> u8 {
// CHECK: declare zeroext i8 @foreign_fn()
extern "C" {fn foreign_fn() -> u8;}
-// CHECK: !{i32 7, !"PIC Level", i32 2}
+// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
// CHECK: !{i32 7, !"PIE Level", i32 2}
diff --git a/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs b/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs
new file mode 100644
index 000000000..7fc34af3d
--- /dev/null
+++ b/src/test/codegen/some-abis-do-extend-params-to-32-bits.rs
@@ -0,0 +1,204 @@
+// compile-flags: -Cno-prepopulate-passes
+
+// revisions:x86_64 i686 aarch64-apple aarch64-windows aarch64-linux arm riscv
+
+//[x86_64] compile-flags: --target x86_64-unknown-uefi
+//[x86_64] needs-llvm-components: x86
+//[i686] compile-flags: --target i686-unknown-linux-musl
+//[i686] needs-llvm-components: x86
+//[aarch64-windows] compile-flags: --target aarch64-pc-windows-msvc
+//[aarch64-windows] needs-llvm-components: aarch64
+//[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64-linux] needs-llvm-components: aarch64
+//[aarch64-apple] compile-flags: --target aarch64-apple-darwin
+//[aarch64-apple] needs-llvm-components: aarch64
+//[arm] compile-flags: --target armv7r-none-eabi
+//[arm] needs-llvm-components: arm
+//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
+//[riscv] needs-llvm-components: riscv
+
+// See bottom of file for a corresponding C source file that is meant to yield
+// equivalent declarations.
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
+
+// The patterns in this file are written in the style of a table to make the
+// uniformities and distinctions more apparent.
+//
+// ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING
+// ============================== =======================
+// x86_64: void @c_arg_u8(i8 zeroext %_a)
+// i686: void @c_arg_u8(i8 zeroext %_a)
+// aarch64-apple: void @c_arg_u8(i8 zeroext %_a)
+// aarch64-windows: void @c_arg_u8(i8 %_a)
+// aarch64-linux: void @c_arg_u8(i8 %_a)
+// arm: void @c_arg_u8(i8 zeroext %_a)
+// riscv: void @c_arg_u8(i8 zeroext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) { }
+
+// x86_64: void @c_arg_u16(i16 zeroext %_a)
+// i686: void @c_arg_u16(i16 zeroext %_a)
+// aarch64-apple: void @c_arg_u16(i16 zeroext %_a)
+// aarch64-windows: void @c_arg_u16(i16 %_a)
+// aarch64-linux: void @c_arg_u16(i16 %_a)
+// arm: void @c_arg_u16(i16 zeroext %_a)
+// riscv: void @c_arg_u16(i16 zeroext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) { }
+
+// x86_64: void @c_arg_u32(i32 %_a)
+// i686: void @c_arg_u32(i32 %_a)
+// aarch64-apple: void @c_arg_u32(i32 %_a)
+// aarch64-windows: void @c_arg_u32(i32 %_a)
+// aarch64-linux: void @c_arg_u32(i32 %_a)
+// arm: void @c_arg_u32(i32 %_a)
+// riscv: void @c_arg_u32(i32 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) { }
+
+// x86_64: void @c_arg_u64(i64 %_a)
+// i686: void @c_arg_u64(i64 %_a)
+// aarch64-apple: void @c_arg_u64(i64 %_a)
+// aarch64-windows: void @c_arg_u64(i64 %_a)
+// aarch64-linux: void @c_arg_u64(i64 %_a)
+// arm: void @c_arg_u64(i64 %_a)
+// riscv: void @c_arg_u64(i64 %_a)
+#[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) { }
+
+// x86_64: void @c_arg_i8(i8 signext %_a)
+// i686: void @c_arg_i8(i8 signext %_a)
+// aarch64-apple: void @c_arg_i8(i8 signext %_a)
+// aarch64-windows: void @c_arg_i8(i8 %_a)
+// aarch64-linux: void @c_arg_i8(i8 %_a)
+// arm: void @c_arg_i8(i8 signext %_a)
+// riscv: void @c_arg_i8(i8 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) { }
+
+// x86_64: void @c_arg_i16(i16 signext %_a)
+// i686: void @c_arg_i16(i16 signext %_a)
+// aarch64-apple: void @c_arg_i16(i16 signext %_a)
+// aarch64-windows: void @c_arg_i16(i16 %_a)
+// aarch64-linux: void @c_arg_i16(i16 %_a)
+// arm: void @c_arg_i16(i16 signext %_a)
+// riscv: void @c_arg_i16(i16 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) { }
+
+// x86_64: void @c_arg_i32(i32 %_a)
+// i686: void @c_arg_i32(i32 %_a)
+// aarch64-apple: void @c_arg_i32(i32 %_a)
+// aarch64-windows: void @c_arg_i32(i32 %_a)
+// aarch64-linux: void @c_arg_i32(i32 %_a)
+// arm: void @c_arg_i32(i32 %_a)
+// riscv: void @c_arg_i32(i32 signext %_a)
+#[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) { }
+
+// x86_64: void @c_arg_i64(i64 %_a)
+// i686: void @c_arg_i64(i64 %_a)
+// aarch64-apple: void @c_arg_i64(i64 %_a)
+// aarch64-windows: void @c_arg_i64(i64 %_a)
+// aarch64-linux: void @c_arg_i64(i64 %_a)
+// arm: void @c_arg_i64(i64 %_a)
+// riscv: void @c_arg_i64(i64 %_a)
+#[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) { }
+
+// x86_64: zeroext i8 @c_ret_u8()
+// i686: zeroext i8 @c_ret_u8()
+// aarch64-apple: zeroext i8 @c_ret_u8()
+// aarch64-windows: i8 @c_ret_u8()
+// aarch64-linux: i8 @c_ret_u8()
+// arm: zeroext i8 @c_ret_u8()
+// riscv: zeroext i8 @c_ret_u8()
+#[no_mangle] pub extern "C" fn c_ret_u8() -> u8 { 0 }
+
+// x86_64: zeroext i16 @c_ret_u16()
+// i686: zeroext i16 @c_ret_u16()
+// aarch64-apple: zeroext i16 @c_ret_u16()
+// aarch64-windows: i16 @c_ret_u16()
+// aarch64-linux: i16 @c_ret_u16()
+// arm: zeroext i16 @c_ret_u16()
+// riscv: zeroext i16 @c_ret_u16()
+#[no_mangle] pub extern "C" fn c_ret_u16() -> u16 { 0 }
+
+// x86_64: i32 @c_ret_u32()
+// i686: i32 @c_ret_u32()
+// aarch64-apple: i32 @c_ret_u32()
+// aarch64-windows: i32 @c_ret_u32()
+// aarch64-linux: i32 @c_ret_u32()
+// arm: i32 @c_ret_u32()
+// riscv: signext i32 @c_ret_u32()
+#[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 }
+
+// x86_64: i64 @c_ret_u64()
+// i686: i64 @c_ret_u64()
+// aarch64-apple: i64 @c_ret_u64()
+// aarch64-windows: i64 @c_ret_u64()
+// aarch64-linux: i64 @c_ret_u64()
+// arm: i64 @c_ret_u64()
+// riscv: i64 @c_ret_u64()
+#[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 }
+
+// x86_64: signext i8 @c_ret_i8()
+// i686: signext i8 @c_ret_i8()
+// aarch64-apple: signext i8 @c_ret_i8()
+// aarch64-windows: i8 @c_ret_i8()
+// aarch64-linux: i8 @c_ret_i8()
+// arm: signext i8 @c_ret_i8()
+// riscv: signext i8 @c_ret_i8()
+#[no_mangle] pub extern "C" fn c_ret_i8() -> i8 { 0 }
+
+// x86_64: signext i16 @c_ret_i16()
+// i686: signext i16 @c_ret_i16()
+// aarch64-apple: signext i16 @c_ret_i16()
+// aarch64-windows: i16 @c_ret_i16()
+// aarch64-linux: i16 @c_ret_i16()
+// arm: signext i16 @c_ret_i16()
+// riscv: signext i16 @c_ret_i16()
+#[no_mangle] pub extern "C" fn c_ret_i16() -> i16 { 0 }
+
+// x86_64: i32 @c_ret_i32()
+// i686: i32 @c_ret_i32()
+// aarch64-apple: i32 @c_ret_i32()
+// aarch64-windows: i32 @c_ret_i32()
+// aarch64-linux: i32 @c_ret_i32()
+// arm: i32 @c_ret_i32()
+// riscv: signext i32 @c_ret_i32()
+#[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 }
+
+// x86_64: i64 @c_ret_i64()
+// i686: i64 @c_ret_i64()
+// aarch64-apple: i64 @c_ret_i64()
+// aarch64-windows: i64 @c_ret_i64()
+// aarch64-linux: i64 @c_ret_i64()
+// arm: i64 @c_ret_i64()
+// riscv: i64 @c_ret_i64()
+#[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 }
+
+const C_SOURCE_FILE: &'static str = r##"
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+void c_arg_u8(uint8_t _a) { }
+void c_arg_u16(uint16_t _a) { }
+void c_arg_u32(uint32_t _a) { }
+void c_arg_u64(uint64_t _a) { }
+
+void c_arg_i8(int8_t _a) { }
+void c_arg_i16(int16_t _a) { }
+void c_arg_i32(int32_t _a) { }
+void c_arg_i64(int64_t _a) { }
+
+uint8_t c_ret_u8() { return 0; }
+uint16_t c_ret_u16() { return 0; }
+uint32_t c_ret_u32() { return 0; }
+uint64_t c_ret_u64() { return 0; }
+
+int8_t c_ret_i8() { return 0; }
+int16_t c_ret_i16() { return 0; }
+int32_t c_ret_i32() { return 0; }
+int64_t c_ret_i64() { return 0; }
+"##;
diff --git a/src/test/codegen/try_question_mark_nop.rs b/src/test/codegen/try_question_mark_nop.rs
new file mode 100644
index 000000000..d23938776
--- /dev/null
+++ b/src/test/codegen/try_question_mark_nop.rs
@@ -0,0 +1,54 @@
+// min-llvm-version: 15.0
+// compile-flags: -O -Z merge-functions=disabled --edition=2021
+// only-x86_64
+
+#![crate_type = "lib"]
+#![feature(try_blocks)]
+
+// These are now NOPs in LLVM 15, presumably thanks to nikic's change mentioned in
+// <https://github.com/rust-lang/rust/issues/85133#issuecomment-1072168354>.
+// Unfortunately, as of 2022-08-17 they're not yet nops for `u64`s nor `Option`.
+
+use std::ops::ControlFlow::{self, Continue, Break};
+
+// CHECK-LABEL: @result_nop_match_32
+#[no_mangle]
+pub fn result_nop_match_32(x: Result<i32, u32>) -> Result<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ match x {
+ Ok(x) => Ok(x),
+ Err(x) => Err(x),
+ }
+}
+
+// CHECK-LABEL: @result_nop_traits_32
+#[no_mangle]
+pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ try {
+ x?
+ }
+}
+
+// CHECK-LABEL: @control_flow_nop_match_32
+#[no_mangle]
+pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ match x {
+ Continue(x) => Continue(x),
+ Break(x) => Break(x),
+ }
+}
+
+// CHECK-LABEL: @control_flow_nop_traits_32
+#[no_mangle]
+pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> {
+ // CHECK: start
+ // CHECK-NEXT: ret i64 %0
+ try {
+ x?
+ }
+}
diff --git a/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
index 1fe048068..c092e28a0 100644
--- a/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `aapcs` and
+// Test that `nounwind` attributes are correctly applied to exported `aapcs` and
// `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
index e817d5715..8447bbeb1 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -1,6 +1,6 @@
// compile-flags: -C panic=abort
-// Test that `nounwind` atributes are also applied to extern `C-unwind` Rust functions
+// Test that `nounwind` attributes are also applied to extern `C-unwind` Rust functions
// when the code is compiled with `panic=abort`.
#![crate_type = "lib"]
diff --git a/src/test/codegen/unwind-abis/c-unwind-abi.rs b/src/test/codegen/unwind-abis/c-unwind-abi.rs
index f15765367..e258dbcac 100644
--- a/src/test/codegen/unwind-abis/c-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/c-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `C` and `C-unwind` extern
+// Test that `nounwind` attributes are correctly applied to exported `C` and `C-unwind` extern
// functions. `C-unwind` functions MUST NOT have this attribute. We disable optimizations above
// to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
index 52e0d2d6e..19a722883 100644
--- a/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `cdecl` and
+// Test that `nounwind` attributes are correctly applied to exported `cdecl` and
// `cdecl-unwind` extern functions. `cdecl-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
index ed23235eb..b74099a5d 100644
--- a/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `fastcall` and
+// Test that `nounwind` attributes are correctly applied to exported `fastcall` and
// `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
index 9a4b3d3b4..106d593b2 100644
--- a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
+++ b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-abort.rs
@@ -3,7 +3,7 @@
#![crate_type = "lib"]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK: Function Attrs:{{.*}}nounwind
// CHECK-NEXT: @foo
diff --git a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
index 2783c83d3..c1c5bbdda 100644
--- a/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
+++ b/src/test/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
@@ -3,7 +3,7 @@
#![crate_type = "lib"]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
extern "C" {
fn bar();
diff --git a/src/test/codegen/unwind-abis/nounwind.rs b/src/test/codegen/unwind-abis/nounwind.rs
index cfc140361..c46d71733 100644
--- a/src/test/codegen/unwind-abis/nounwind.rs
+++ b/src/test/codegen/unwind-abis/nounwind.rs
@@ -4,7 +4,7 @@
#![crate_type = "lib"]
#![feature(c_unwind)]
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK: Function Attrs:{{.*}}nounwind
// CHECK-NEXT: @foo
diff --git a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
index f1dff27ad..8eff0719f 100644
--- a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `stdcall` and `stdcall-unwind`
+// Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind`
// extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable
// optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/system-unwind-abi.rs b/src/test/codegen/unwind-abis/system-unwind-abi.rs
index c4d513283..2591c1d48 100644
--- a/src/test/codegen/unwind-abis/system-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/system-unwind-abi.rs
@@ -1,6 +1,6 @@
// compile-flags: -C opt-level=0
-// Test that `nounwind` atributes are correctly applied to exported `system` and `system-unwind`
+// Test that `nounwind` attributes are correctly applied to exported `system` and `system-unwind`
// extern functions. `system-unwind` functions MUST NOT have this attribute. We disable
// optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
index a38736f2a..694fde17c 100644
--- a/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `sysv64` and
+// Test that `nounwind` attributes are correctly applied to exported `sysv64` and
// `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
index d2cf041b7..7e81367fc 100644
--- a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `thiscall` and
+// Test that `nounwind` attributes are correctly applied to exported `thiscall` and
// `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
index 0fb9612a5..d7eca2a97 100644
--- a/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `vectorcall` and
+// Test that `nounwind` attributes are correctly applied to exported `vectorcall` and
// `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute.
// We disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-abis/win64-unwind-abi.rs b/src/test/codegen/unwind-abis/win64-unwind-abi.rs
index 5d8482da6..6591348c3 100644
--- a/src/test/codegen/unwind-abis/win64-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/win64-unwind-abi.rs
@@ -5,7 +5,7 @@
#[lang="sized"]
trait Sized { }
-// Test that `nounwind` atributes are correctly applied to exported `win64` and
+// Test that `nounwind` attributes are correctly applied to exported `win64` and
// `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We
// disable optimizations above to prevent LLVM from inferring the attribute.
diff --git a/src/test/codegen/unwind-extern-exports.rs b/src/test/codegen/unwind-extern-exports.rs
index c939235fb..6ac3c079f 100644
--- a/src/test/codegen/unwind-extern-exports.rs
+++ b/src/test/codegen/unwind-extern-exports.rs
@@ -5,7 +5,7 @@
#![feature(c_unwind)]
// Make sure these all do *not* get the attribute.
-// We disable optimizations to prevent LLVM from infering the attribute.
+// We disable optimizations to prevent LLVM from inferring the attribute.
// CHECK-NOT: nounwind
// "C" ABI