diff options
Diffstat (limited to '')
170 files changed, 2905 insertions, 2236 deletions
diff --git a/tests/codegen/aarch64-struct-align-128.rs b/tests/codegen/aarch64-struct-align-128.rs new file mode 100644 index 000000000..bf3471778 --- /dev/null +++ b/tests/codegen/aarch64-struct-align-128.rs @@ -0,0 +1,150 @@ +// Test that structs aligned to 128 bits are passed with the correct ABI on aarch64. + +// revisions:linux darwin windows +//[linux] compile-flags: --target aarch64-unknown-linux-gnu +//[darwin] compile-flags: --target aarch64-apple-darwin +//[windows] compile-flags: --target aarch64-pc-windows-msvc +//[linux] needs-llvm-components: aarch64 +//[darwin] needs-llvm-components: aarch64 +//[windows] needs-llvm-components: aarch64 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="freeze"] +trait Freeze { } +#[lang="copy"] +trait Copy { } + + + +// Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits. +#[repr(C)] +pub struct Align8 { + pub a: u64, + pub b: u64, +} + +// repr(transparent), so same as above. +#[repr(transparent)] +pub struct Transparent8 { + a: Align8 +} + +// Passed as `[i64 x 2]`, since it's an aggregate with size <= 128 bits, align < 128 bits. +#[repr(C)] +pub struct Wrapped8 { + a: Align8, +} + +extern "C" { + // linux: declare void @test_8([2 x i64], [2 x i64], [2 x i64]) + // darwin: declare void @test_8([2 x i64], [2 x i64], [2 x i64]) + // windows: declare void @test_8([2 x i64], [2 x i64], [2 x i64]) + fn test_8(a: Align8, b: Transparent8, c: Wrapped8); +} + + + +// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. +// EXCEPT on Linux, where there's a special case to use its unadjusted alignment, +// making it the same as `Align8`, so it's be passed as `[i64 x 2]`. +#[repr(C)] +#[repr(align(16))] +pub struct Align16 { + pub a: u64, + pub b: u64, +} + +// repr(transparent), so same as above. +#[repr(transparent)] +pub struct Transparent16 { + a: Align16 +} + +// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. +// On Linux, the "unadjustedness" doesn't recurse into fields, so this is passed as `i128`. +#[repr(C)] +pub struct Wrapped16 { + pub a: Align16, +} + +extern "C" { + // linux: declare void @test_16([2 x i64], [2 x i64], i128) + // darwin: declare void @test_16(i128, i128, i128) + // windows: declare void @test_16(i128, i128, i128) + fn test_16(a: Align16, b: Transparent16, c: Wrapped16); +} + + + +// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. +#[repr(C)] +pub struct I128 { + pub a: i128, +} + +// repr(transparent), so same as above. +#[repr(transparent)] +pub struct TransparentI128 { + a: I128 +} + +// Passed as `i128`, since it's an aggregate with size <= 128 bits, align = 128 bits. +#[repr(C)] +pub struct WrappedI128 { + pub a: I128 +} + +extern "C" { + // linux: declare void @test_i128(i128, i128, i128) + // darwin: declare void @test_i128(i128, i128, i128) + // windows: declare void @test_i128(i128, i128, i128) + fn test_i128(a: I128, b: TransparentI128, c: WrappedI128); +} + + + +// Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits. +// Note that the Linux special case does not apply, because packing is not considered "adjustment". +#[repr(C)] +#[repr(packed)] +pub struct Packed { + pub a: i128, +} + +// repr(transparent), so same as above. +#[repr(transparent)] +pub struct TransparentPacked { + a: Packed +} + +// Passed as `[2 x i64]`, since it's an aggregate with size <= 128 bits, align < 128 bits. +#[repr(C)] +pub struct WrappedPacked { + pub a: Packed +} + +extern "C" { + // linux: declare void @test_packed([2 x i64], [2 x i64], [2 x i64]) + // darwin: declare void @test_packed([2 x i64], [2 x i64], [2 x i64]) + // windows: declare void @test_packed([2 x i64], [2 x i64], [2 x i64]) + fn test_packed(a: Packed, b: TransparentPacked, c: WrappedPacked); +} + + + +pub unsafe fn main( + a1: Align8, a2: Transparent8, a3: Wrapped8, + b1: Align16, b2: Transparent16, b3: Wrapped16, + c1: I128, c2: TransparentI128, c3: WrappedI128, + d1: Packed, d2: TransparentPacked, d3: WrappedPacked, +) { + test_8(a1, a2, a3); + test_16(b1, b2, b3); + test_i128(c1, c2, c3); + test_packed(d1, d2, d3); +} diff --git a/tests/codegen/abi-main-signature-16bit-c-int.rs b/tests/codegen/abi-main-signature-16bit-c-int.rs index 353e7489b..ce4d35dea 100644 --- a/tests/codegen/abi-main-signature-16bit-c-int.rs +++ b/tests/codegen/abi-main-signature-16bit-c-int.rs @@ -2,22 +2,10 @@ // entry point. It must match C's `int main(int, char **)`. // This test is for targets with 16bit c_int only. -// ignore-aarch64 -// ignore-arm -// ignore-asmjs -// ignore-hexagon -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-powerpc64 -// ignore-riscv64 -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-wasm32 -// ignore-x86 -// ignore-x86_64 -// ignore-loongarch64 +// revisions: avr msp +//[avr] only-avr +//[msp] only-msp430 + fn main() { } diff --git a/tests/codegen/abi-main-signature-32bit-c-int.rs b/tests/codegen/abi-main-signature-32bit-c-int.rs index 7f22ddcfc..34571823f 100644 --- a/tests/codegen/abi-main-signature-32bit-c-int.rs +++ b/tests/codegen/abi-main-signature-32bit-c-int.rs @@ -3,8 +3,9 @@ // This test is for targets with 32bit c_int only. // ignore-msp430 +// ignore-avr fn main() { } -// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) +// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, ptr{{( %1)?}}) diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs index bea1aad23..97af61815 100644 --- a/tests/codegen/addr-of-mutate.rs +++ b/tests/codegen/addr-of-mutate.rs @@ -1,12 +1,11 @@ // compile-flags: -C opt-level=3 -C no-prepopulate-passes -// min-llvm-version: 15.0 (for opaque pointers) #![crate_type = "lib"] // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`. // See <https://github.com/rust-lang/rust/issues/111502>. -// CHECK: i8 @foo(ptr noalias nocapture noundef dereferenceable(128) %x) +// CHECK: i8 @foo(ptr noalias nocapture noundef align 1 dereferenceable(128) %x) #[no_mangle] pub fn foo(x: [u8; 128]) -> u8 { let ptr = core::ptr::addr_of!(x).cast_mut(); @@ -16,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 { x[0] } -// CHECK: i1 @second(ptr noalias nocapture noundef dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @second(ptr noalias nocapture noundef align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut(); @@ -25,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { } // If going through a deref (and there are no other mutating accesses), then `readonly` is fine. -// CHECK: i1 @third(ptr noalias nocapture noundef readonly dereferenceable({{[0-9]+}}) %a_ptr_and_b) +// CHECK: i1 @third(ptr noalias nocapture noundef readonly align {{[0-9]+}} dereferenceable({{[0-9]+}}) %a_ptr_and_b) #[no_mangle] pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut(); diff --git a/tests/codegen/adjustments.rs b/tests/codegen/adjustments.rs index b53a68a55..0739c79ba 100644 --- a/tests/codegen/adjustments.rs +++ b/tests/codegen/adjustments.rs @@ -13,9 +13,9 @@ pub fn helper(_: usize) { pub fn no_op_slice_adjustment(x: &[u8]) -> &[u8] { // We used to generate an extra alloca and memcpy for the block's trailing expression value, so // check that we copy directly to the return value slot -// CHECK: %0 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } poison, {{\[0 x i8\]\*|ptr}} %x.0, 0 -// CHECK: %1 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %0, [[USIZE]] %x.1, 1 -// CHECK: ret { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %1 +// CHECK: %0 = insertvalue { ptr, [[USIZE]] } poison, ptr %x.0, 0 +// CHECK: %1 = insertvalue { ptr, [[USIZE]] } %0, [[USIZE]] %x.1, 1 +// CHECK: ret { ptr, [[USIZE]] } %1 { x } } diff --git a/tests/codegen/align-byval-vector.rs b/tests/codegen/align-byval-vector.rs new file mode 100644 index 000000000..3c8be6596 --- /dev/null +++ b/tests/codegen/align-byval-vector.rs @@ -0,0 +1,58 @@ +// revisions:x86-linux x86-darwin + +//[x86-linux] compile-flags: --target i686-unknown-linux-gnu +//[x86-linux] needs-llvm-components: x86 +//[x86-darwin] compile-flags: --target i686-apple-darwin +//[x86-darwin] needs-llvm-components: x86 + +// Tests that aggregates containing vector types get their alignment increased to 16 on Darwin. + +#![feature(no_core, lang_items, repr_simd, simd_ffi)] +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![allow(non_camel_case_types)] + +#[lang = "sized"] +trait Sized {} +#[lang = "freeze"] +trait Freeze {} +#[lang = "copy"] +trait Copy {} + +#[repr(simd)] +pub struct i32x4(i32, i32, i32, i32); + +#[repr(C)] +pub struct Foo { + a: i32x4, + b: i8, +} + +// This tests that we recursively check for vector types, not just at the top level. +#[repr(C)] +pub struct DoubleFoo { + one: Foo, + two: Foo, +} + +extern "C" { + // x86-linux: declare void @f({{.*}}byval(%Foo) align 4{{.*}}) + // x86-darwin: declare void @f({{.*}}byval(%Foo) align 16{{.*}}) + fn f(foo: Foo); + + // x86-linux: declare void @g({{.*}}byval(%DoubleFoo) align 4{{.*}}) + // x86-darwin: declare void @g({{.*}}byval(%DoubleFoo) align 16{{.*}}) + fn g(foo: DoubleFoo); +} + +pub fn main() { + unsafe { f(Foo { a: i32x4(1, 2, 3, 4), b: 0 }) } + + unsafe { + g(DoubleFoo { + one: Foo { a: i32x4(1, 2, 3, 4), b: 0 }, + two: Foo { a: i32x4(1, 2, 3, 4), b: 0 }, + }) + } +} diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs new file mode 100644 index 000000000..e2446e02e --- /dev/null +++ b/tests/codegen/align-byval.rs @@ -0,0 +1,342 @@ +// ignore-tidy-linelength +// revisions:m68k wasm x86_64-linux x86_64-windows i686-linux i686-windows + +//[m68k] compile-flags: --target m68k-unknown-linux-gnu +//[m68k] needs-llvm-components: m68k +//[wasm] compile-flags: --target wasm32-unknown-emscripten +//[wasm] needs-llvm-components: webassembly +//[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64-linux] needs-llvm-components: x86 +//[x86_64-windows] compile-flags: --target x86_64-pc-windows-msvc +//[x86_64-windows] needs-llvm-components: x86 +//[i686-linux] compile-flags: --target i686-unknown-linux-gnu +//[i686-linux] needs-llvm-components: x86 +//[i686-windows] compile-flags: --target i686-pc-windows-msvc +//[i686-windows] needs-llvm-components: x86 + +// Tests that `byval` alignment is properly specified (#80127). +// The only targets that use `byval` are m68k, wasm, x86-64, and x86. +// Note also that Windows mandates a by-ref ABI here, so it does not use byval. + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_std] +#![no_core] + +#[lang="sized"] trait Sized { } +#[lang="freeze"] trait Freeze { } +#[lang="copy"] trait Copy { } + +impl Copy for i32 {} +impl Copy for i64 {} + +// This struct can be represented as a pair, so it exercises the OperandValue::Pair +// codepath in `codegen_argument`. +#[repr(C)] +pub struct NaturalAlign1 { + a: i8, + b: i8, +} + +// This struct cannot be represented as an immediate, so it exercises the OperandValue::Ref +// codepath in `codegen_argument`. +#[repr(C)] +pub struct NaturalAlign2 { + a: [i16; 16], + b: i16, +} + +#[repr(C)] +#[repr(align(4))] +pub struct ForceAlign4 { + a: [i8; 16], + b: i8, +} + +// On i686-windows, this is passed on stack using `byval` +#[repr(C)] +pub struct NaturalAlign8 { + a: i64, + b: i64, + c: i64 +} + +// On i686-windows, this is passed by reference (because alignment is >4 and requested/forced), +// even though it has the exact same layout as `NaturalAlign8`! +#[repr(C)] +#[repr(align(8))] +pub struct ForceAlign8 { + a: i64, + b: i64, + c: i64 +} + +// On i686-windows, this is passed on stack, because requested alignment is <=4. +#[repr(C)] +#[repr(align(4))] +pub struct LowerFA8 { + a: i64, + b: i64, + c: i64 +} + +// On i686-windows, this is passed by reference, because it contains a field with +// requested/forced alignment. +#[repr(C)] +pub struct WrappedFA8 { + a: ForceAlign8 +} + +// On i686-windows, this has the same ABI as ForceAlign8, i.e. passed by reference. +#[repr(transparent)] +pub struct TransparentFA8 { + _0: (), + a: ForceAlign8 +} + +#[repr(C)] +#[repr(align(16))] +pub struct ForceAlign16 { + a: [i32; 16], + b: i8 +} + +// CHECK-LABEL: @call_na1 +#[no_mangle] +pub unsafe fn call_na1(x: NaturalAlign1) { + // CHECK: start: + + // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca { i8, i8 }, align 1 + // m68k: call void @natural_align_1({{.*}}byval({ i8, i8 }) align 1{{.*}} [[ALLOCA]]) + + // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca { i8, i8 }, align 1 + // wasm: call void @natural_align_1({{.*}}byval({ i8, i8 }) align 1{{.*}} [[ALLOCA]]) + + // x86_64-linux: call void @natural_align_1(i16 + + // x86_64-windows: call void @natural_align_1(i16 + + // i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca { i8, i8 }, align 4 + // i686-linux: call void @natural_align_1({{.*}}byval({ i8, i8 }) align 4{{.*}} [[ALLOCA]]) + + // i686-windows: [[ALLOCA:%[a-z0-9+]]] = alloca { i8, i8 }, align 4 + // i686-windows: call void @natural_align_1({{.*}}byval({ i8, i8 }) align 4{{.*}} [[ALLOCA]]) + natural_align_1(x); +} + +// CHECK-LABEL: @call_na2 +#[no_mangle] +pub unsafe fn call_na2(x: NaturalAlign2) { + // CHECK: start: + + // m68k-NEXT: call void @natural_align_2 + // wasm-NEXT: call void @natural_align_2 + // x86_64-linux-NEXT: call void @natural_align_2 + // x86_64-windows-NEXT: call void @natural_align_2 + + // i686-linux: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 + // i686-linux: call void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}} [[ALLOCA]]) + + // i686-windows: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 + // i686-windows: call void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}} [[ALLOCA]]) + natural_align_2(x); +} + +// CHECK-LABEL: @call_fa4 +#[no_mangle] +pub unsafe fn call_fa4(x: ForceAlign4) { + // CHECK: start: + // CHECK-NEXT: call void @force_align_4 + force_align_4(x); +} + +// CHECK-LABEL: @call_na8 +#[no_mangle] +pub unsafe fn call_na8(x: NaturalAlign8) { + // CHECK: start: + // CHECK-NEXT: call void @natural_align_8 + natural_align_8(x); +} + +// CHECK-LABEL: @call_fa8 +#[no_mangle] +pub unsafe fn call_fa8(x: ForceAlign8) { + // CHECK: start: + // CHECK-NEXT: call void @force_align_8 + force_align_8(x); +} + +// CHECK-LABEL: @call_lfa8 +#[no_mangle] +pub unsafe fn call_lfa8(x: LowerFA8) { + // CHECK: start: + // CHECK-NEXT: call void @lower_fa8 + lower_fa8(x); +} + +// CHECK-LABEL: @call_wfa8 +#[no_mangle] +pub unsafe fn call_wfa8(x: WrappedFA8) { + // CHECK: start: + // CHECK-NEXT: call void @wrapped_fa8 + wrapped_fa8(x); +} + +// CHECK-LABEL: @call_tfa8 +#[no_mangle] +pub unsafe fn call_tfa8(x: TransparentFA8) { + // CHECK: start: + // CHECK-NEXT: call void @transparent_fa8 + transparent_fa8(x); +} + +// CHECK-LABEL: @call_fa16 +#[no_mangle] +pub unsafe fn call_fa16(x: ForceAlign16) { + // CHECK: start: + // CHECK-NEXT: call void @force_align_16 + force_align_16(x); +} + +extern "C" { + // m68k: declare void @natural_align_1({{.*}}byval({ i8, i8 }) align 1{{.*}}) + + // wasm: declare void @natural_align_1({{.*}}byval({ i8, i8 }) align 1{{.*}}) + + // x86_64-linux: declare void @natural_align_1(i16) + + // x86_64-windows: declare void @natural_align_1(i16) + + // i686-linux: declare void @natural_align_1({{.*}}byval({ i8, i8 }) align 4{{.*}}) + + // i686-windows: declare void @natural_align_1({{.*}}byval({ i8, i8 }) align 4{{.*}}) + fn natural_align_1(x: NaturalAlign1); + + // m68k: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) + + // wasm: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) + + // x86_64-linux: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 2{{.*}}) + + // x86_64-windows: declare void @natural_align_2( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 2{{.*}}) + + // i686-linux: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}}) + + // i686-windows: declare void @natural_align_2({{.*}}byval(%NaturalAlign2) align 4{{.*}}) + fn natural_align_2(x: NaturalAlign2); + + // m68k: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) + + // wasm: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) + + // x86_64-linux: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) + + // x86_64-windows: declare void @force_align_4( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 4{{.*}}) + + // i686-linux: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) + + // i686-windows: declare void @force_align_4({{.*}}byval(%ForceAlign4) align 4{{.*}}) + fn force_align_4(x: ForceAlign4); + + // m68k: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) + + // wasm: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 8{{.*}}) + + // x86_64-linux: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 8{{.*}}) + + // x86_64-windows: declare void @natural_align_8( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 8{{.*}}) + + // i686-linux: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) + + // i686-windows: declare void @natural_align_8({{.*}}byval(%NaturalAlign8) align 4{{.*}}) + fn natural_align_8(x: NaturalAlign8); + + // m68k: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) + + // wasm: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) + + // x86_64-linux: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 8{{.*}}) + + // x86_64-windows: declare void @force_align_8( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 8{{.*}}) + + // i686-linux: declare void @force_align_8({{.*}}byval(%ForceAlign8) align 4{{.*}}) + + // i686-windows: declare void @force_align_8( + // i686-windows-NOT: byval + // i686-windows-SAME: align 8{{.*}}) + fn force_align_8(x: ForceAlign8); + + // m68k: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) + + // wasm: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}}) + + // x86_64-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}}) + + // x86_64-windows: declare void @lower_fa8( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 8{{.*}}) + + // i686-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) + + // i686-windows: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}}) + fn lower_fa8(x: LowerFA8); + + // m68k: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) + + // wasm: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) + + // x86_64-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}}) + + // x86_64-windows: declare void @wrapped_fa8( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 8{{.*}}) + + // i686-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 4{{.*}}) + + // i686-windows: declare void @wrapped_fa8( + // i686-windows-NOT: byval + // i686-windows-SAME: align 8{{.*}}) + fn wrapped_fa8(x: WrappedFA8); + + // m68k: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) + + // wasm: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) + + // x86_64-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}}) + + // x86_64-windows: declare void @transparent_fa8( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 8{{.*}}) + + // i686-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 4{{.*}}) + + // i686-windows: declare void @transparent_fa8( + // i686-windows-NOT: byval + // i686-windows-SAME: align 8{{.*}}) + fn transparent_fa8(x: TransparentFA8); + + // m68k: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) + + // wasm: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) + + // x86_64-linux: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}}) + + // x86_64-windows: declare void @force_align_16( + // x86_64-windows-NOT: byval + // x86_64-windows-SAME: align 16{{.*}}) + + // i686-linux: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 4{{.*}}) + + // i686-windows: declare void @force_align_16( + // i686-windows-NOT: byval + // i686-windows-SAME: align 16{{.*}}) + fn force_align_16(x: ForceAlign16); +} diff --git a/tests/codegen/align-enum.rs b/tests/codegen/align-enum.rs index 70f09ace0..5901f0113 100644 --- a/tests/codegen/align-enum.rs +++ b/tests/codegen/align-enum.rs @@ -20,7 +20,7 @@ pub struct Nested64 { #[no_mangle] pub fn align64(a: u32) -> Align64 { // CHECK: %a64 = alloca %Align64, align 64 -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 64 %{{.*}}, {{i8\*|ptr}} align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64::A(a); a64 } diff --git a/tests/codegen/align-offset.rs b/tests/codegen/align-offset.rs index 7c7660c5a..d4d8b18d3 100644 --- a/tests/codegen/align-offset.rs +++ b/tests/codegen/align-offset.rs @@ -1,5 +1,4 @@ // compile-flags: -O -// min-llvm-version: 15.0 (because we're using opaque pointers) // ignore-debug (debug assertions in `slice::from_raw_parts` block optimizations) #![crate_type = "lib"] diff --git a/tests/codegen/align-struct.rs b/tests/codegen/align-struct.rs index a2f47354b..40bba6d52 100644 --- a/tests/codegen/align-struct.rs +++ b/tests/codegen/align-struct.rs @@ -32,7 +32,7 @@ pub enum Enum64 { #[no_mangle] pub fn align64(i : i32) -> Align64 { // CHECK: %a64 = alloca %Align64, align 64 -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 64 %{{.*}}, {{i8\*|ptr}} align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64(i); a64 } @@ -42,7 +42,7 @@ pub fn align64(i : i32) -> Align64 { // CHECK-LABEL: @align64_load #[no_mangle] pub fn align64_load(a: Align64) -> i32 { -// CHECK: {{%.*}} = load i32, {{i32\*|ptr}} {{%.*}}, align 64 +// CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 64 a.0 } diff --git a/tests/codegen/array-codegen.rs b/tests/codegen/array-codegen.rs index 98488eb92..ba0d444f9 100644 --- a/tests/codegen/array-codegen.rs +++ b/tests/codegen/array-codegen.rs @@ -1,15 +1,14 @@ // compile-flags: -O -C no-prepopulate-passes -// min-llvm-version: 15.0 (for opaque pointers) #![crate_type = "lib"] // CHECK-LABEL: @array_load #[no_mangle] pub fn array_load(a: &[u8; 4]) -> [u8; 4] { - // CHECK: %0 = alloca [4 x i8], align 1 + // CHECK: %_0 = alloca [4 x i8], align 1 // CHECK: %[[TEMP1:.+]] = load <4 x i8>, ptr %a, align 1 - // CHECK: store <4 x i8> %[[TEMP1]], ptr %0, align 1 - // CHECK: %[[TEMP2:.+]] = load i32, ptr %0, align 1 + // CHECK: store <4 x i8> %[[TEMP1]], ptr %_0, align 1 + // CHECK: %[[TEMP2:.+]] = load i32, ptr %_0, align 1 // CHECK: ret i32 %[[TEMP2]] *a } diff --git a/tests/codegen/array-equality.rs b/tests/codegen/array-equality.rs index abfe295f8..1941452ea 100644 --- a/tests/codegen/array-equality.rs +++ b/tests/codegen/array-equality.rs @@ -16,8 +16,8 @@ pub fn array_eq_value(a: [u16; 3], b: [u16; 3]) -> bool { #[no_mangle] pub fn array_eq_ref(a: &[u16; 3], b: &[u16; 3]) -> bool { // CHECK: start: - // CHECK: load i48, {{i48\*|ptr}} %{{.+}}, align 2 - // CHECK: load i48, {{i48\*|ptr}} %{{.+}}, align 2 + // CHECK: load i48, ptr %{{.+}}, align 2 + // CHECK: load i48, ptr %{{.+}}, align 2 // CHECK: icmp eq i48 // CHECK-NEXT: ret a == b @@ -27,7 +27,7 @@ pub fn array_eq_ref(a: &[u16; 3], b: &[u16; 3]) -> bool { #[no_mangle] pub fn array_eq_value_still_passed_by_pointer(a: [u16; 9], b: [u16; 9]) -> bool { // CHECK-NEXT: start: - // CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{i8\*|ptr}} {{.*}} dereferenceable(18) %{{.+}}, {{i8\*|ptr}} {{.*}} dereferenceable(18) %{{.+}}, i64 18) + // CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(ptr {{.*}} dereferenceable(18) %{{.+}}, ptr {{.*}} dereferenceable(18) %{{.+}}, i64 18) // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0 // CHECK-NEXT: ret i1 %[[EQ]] a == b @@ -37,7 +37,7 @@ pub fn array_eq_value_still_passed_by_pointer(a: [u16; 9], b: [u16; 9]) -> bool #[no_mangle] pub fn array_eq_long(a: &[u16; 1234], b: &[u16; 1234]) -> bool { // CHECK-NEXT: start: - // CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{i8\*|ptr}} {{.*}} dereferenceable(2468) %{{.+}}, {{i8\*|ptr}} {{.*}} dereferenceable(2468) %{{.+}}, i64 2468) + // CHECK: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(ptr {{.*}} dereferenceable(2468) %{{.+}}, ptr {{.*}} dereferenceable(2468) %{{.+}}, i64 2468) // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0 // CHECK-NEXT: ret i1 %[[EQ]] a == b diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs index 24f3f43d0..4d218e6a9 100644 --- a/tests/codegen/array-map.rs +++ b/tests/codegen/array-map.rs @@ -30,7 +30,6 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] { pub fn long_integer_map(x: [u32; 512]) -> [u32; 512] { // CHECK: start: // CHECK-NEXT: alloca [512 x i32] - // CHECK-NEXT: alloca %"core::mem::manually_drop::ManuallyDrop<[u32; 512]>" // CHECK-NOT: alloca // CHECK: mul <{{[0-9]+}} x i32> // CHECK: add <{{[0-9]+}} x i32> diff --git a/tests/codegen/atomic-operations.rs b/tests/codegen/atomic-operations.rs index d2bc618df..20980c489 100644 --- a/tests/codegen/atomic-operations.rs +++ b/tests/codegen/atomic-operations.rs @@ -7,37 +7,37 @@ use std::sync::atomic::{AtomicI32, Ordering::*}; // CHECK-LABEL: @compare_exchange #[no_mangle] pub fn compare_exchange(a: &AtomicI32) { - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 10 monotonic monotonic - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 11 monotonic acquire - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 12 monotonic seq_cst + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 10 monotonic monotonic + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 11 monotonic acquire + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 12 monotonic 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\*|ptr}} %{{.*}}, i32 0, i32 20 release monotonic - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 21 release acquire - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 22 release seq_cst + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 20 release monotonic + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 21 release acquire + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 22 release 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\*|ptr}} %{{.*}}, i32 0, i32 30 acquire monotonic - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 31 acquire acquire - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 32 acquire seq_cst + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 30 acquire monotonic + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 31 acquire acquire + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 32 acquire 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\*|ptr}} %{{.*}}, i32 0, i32 40 acq_rel monotonic - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 41 acq_rel acquire - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 42 acq_rel seq_cst + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 40 acq_rel monotonic + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 41 acq_rel acquire + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 42 acq_rel 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\*|ptr}} %{{.*}}, i32 0, i32 50 seq_cst monotonic - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 51 seq_cst acquire - // CHECK: cmpxchg {{i32\*|ptr}} %{{.*}}, i32 0, i32 52 seq_cst seq_cst + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 50 seq_cst monotonic + // CHECK: cmpxchg ptr %{{.*}}, i32 0, i32 51 seq_cst acquire + // CHECK: cmpxchg ptr %{{.*}}, 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); @@ -46,37 +46,37 @@ pub fn compare_exchange(a: &AtomicI32) { // CHECK-LABEL: @compare_exchange_weak #[no_mangle] pub fn compare_exchange_weak(w: &AtomicI32) { - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 10 monotonic monotonic - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 11 monotonic acquire - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 12 monotonic seq_cst + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 10 monotonic monotonic + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 11 monotonic acquire + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 12 monotonic 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\*|ptr}} %{{.*}}, i32 1, i32 20 release monotonic - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 21 release acquire - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 22 release seq_cst + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 20 release monotonic + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 21 release acquire + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 22 release 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\*|ptr}} %{{.*}}, i32 1, i32 30 acquire monotonic - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 31 acquire acquire - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 32 acquire seq_cst + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 30 acquire monotonic + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 31 acquire acquire + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 32 acquire 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\*|ptr}} %{{.*}}, i32 1, i32 40 acq_rel monotonic - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 41 acq_rel acquire - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 42 acq_rel seq_cst + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 40 acq_rel monotonic + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 41 acq_rel acquire + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 42 acq_rel 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\*|ptr}} %{{.*}}, i32 1, i32 50 seq_cst monotonic - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 51 seq_cst acquire - // CHECK: cmpxchg weak {{i32\*|ptr}} %{{.*}}, i32 1, i32 52 seq_cst seq_cst + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 50 seq_cst monotonic + // CHECK: cmpxchg weak ptr %{{.*}}, i32 1, i32 51 seq_cst acquire + // CHECK: cmpxchg weak ptr %{{.*}}, 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/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index bc11e1081..dc36a9fac 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -94,7 +94,7 @@ pub extern "C" fn test() { // Validate that we can codegen transmutes between data ptrs and fn ptrs. -// CHECK: define{{.+}}{{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}} @transmute_data_ptr_to_fn({{\{\}\*|ptr}}{{.*}} %x) +// CHECK: define{{.+}}ptr addrspace(1) @transmute_data_ptr_to_fn(ptr{{.*}} %x) #[no_mangle] pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() { // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), @@ -102,7 +102,7 @@ pub unsafe fn transmute_data_ptr_to_fn(x: *const ()) -> fn() { transmute(x) } -// CHECK: define{{.+}}{{\{\}\*|ptr}} @transmute_fn_ptr_to_data({{void \(\) addrspace\(1\)\*|ptr addrspace\(1\)}}{{.*}} %x) +// CHECK: define{{.+}}ptr @transmute_fn_ptr_to_data(ptr addrspace(1){{.*}} %x) #[no_mangle] pub unsafe fn transmute_fn_ptr_to_data(x: fn()) -> *const () { // It doesn't matter precisely how this is codegenned (through memory or an addrspacecast), @@ -116,7 +116,7 @@ pub enum Either<T, U> { A(T), B(U) } // with the `ptr` field representing both `&i32` and `fn()` depending on the variant. // This is incorrect, because `fn()` should be `ptr addrspace(1)`, not `ptr`. -// CHECK: define{{.+}}void @should_not_combine_addrspace({{.+\*|ptr}}{{.+}}sret{{.+}}%0, {{.+\*|ptr}}{{.+}}%x) +// CHECK: define{{.+}}void @should_not_combine_addrspace(ptr{{.+}}sret{{.+}}%_0, ptr{{.+}}%x) #[no_mangle] #[inline(never)] pub fn should_not_combine_addrspace(x: Either<&i32, fn()>) -> Either<&i32, fn()> { diff --git a/tests/codegen/box-maybe-uninit-llvm14.rs b/tests/codegen/box-maybe-uninit-llvm14.rs deleted file mode 100644 index c9f88fb3f..000000000 --- a/tests/codegen/box-maybe-uninit-llvm14.rs +++ /dev/null @@ -1,34 +0,0 @@ -// compile-flags: -O - -// Once we're done with llvm 14 and earlier, this test can be deleted. - -#![crate_type = "lib"] - -use std::mem::MaybeUninit; - -// Boxing a `MaybeUninit` value should not copy junk from the stack -#[no_mangle] -pub fn box_uninitialized() -> Box<MaybeUninit<usize>> { - // CHECK-LABEL: @box_uninitialized - // CHECK-NOT: store - // CHECK-NOT: alloca - // CHECK-NOT: memcpy - // CHECK-NOT: memset - Box::new(MaybeUninit::uninit()) -} - -// https://github.com/rust-lang/rust/issues/58201 -#[no_mangle] -pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> { - // CHECK-LABEL: @box_uninitialized2 - // CHECK-NOT: store - // CHECK-NOT: alloca - // CHECK-NOT: memcpy - // CHECK-NOT: memset - Box::new(MaybeUninit::uninit()) -} - -// Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc -// from the CHECK-NOT above. We don't check the attributes here because we can't rely -// on all of them being set until LLVM 15. -// CHECK: declare {{(dso_local )?}}noalias{{.*}} @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+.*}} noundef) diff --git a/tests/codegen/box-maybe-uninit.rs b/tests/codegen/box-maybe-uninit.rs index 5c08b5832..282af99b0 100644 --- a/tests/codegen/box-maybe-uninit.rs +++ b/tests/codegen/box-maybe-uninit.rs @@ -1,5 +1,4 @@ // compile-flags: -O -// min-llvm-version: 15.0 #![crate_type = "lib"] use std::mem::MaybeUninit; diff --git a/tests/codegen/c-variadic-copy.rs b/tests/codegen/cffi/c-variadic-copy.rs index 4c61c4fcf..4c61c4fcf 100644 --- a/tests/codegen/c-variadic-copy.rs +++ b/tests/codegen/cffi/c-variadic-copy.rs diff --git a/tests/codegen/c-variadic-opt.rs b/tests/codegen/cffi/c-variadic-opt.rs index 969dce80f..969dce80f 100644 --- a/tests/codegen/c-variadic-opt.rs +++ b/tests/codegen/cffi/c-variadic-opt.rs diff --git a/tests/codegen/c-variadic.rs b/tests/codegen/cffi/c-variadic.rs index cab326522..cab326522 100644 --- a/tests/codegen/c-variadic.rs +++ b/tests/codegen/cffi/c-variadic.rs diff --git a/tests/codegen/ffi-const.rs b/tests/codegen/cffi/ffi-const.rs index 937205034..937205034 100644 --- a/tests/codegen/ffi-const.rs +++ b/tests/codegen/cffi/ffi-const.rs diff --git a/tests/codegen/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index 099726b2f..099726b2f 100644 --- a/tests/codegen/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs diff --git a/tests/codegen/ffi-pure.rs b/tests/codegen/cffi/ffi-pure.rs index 2ed735813..2ed735813 100644 --- a/tests/codegen/ffi-pure.rs +++ b/tests/codegen/cffi/ffi-pure.rs diff --git a/tests/codegen/ffi-returns-twice.rs b/tests/codegen/cffi/ffi-returns-twice.rs index 0fbe03f0b..0fbe03f0b 100644 --- a/tests/codegen/ffi-returns-twice.rs +++ b/tests/codegen/cffi/ffi-returns-twice.rs diff --git a/tests/codegen/comparison-operators-2-tuple.rs b/tests/codegen/comparison-operators-2-tuple.rs index a9d25e3b5..7a2a3fc93 100644 --- a/tests/codegen/comparison-operators-2-tuple.rs +++ b/tests/codegen/comparison-operators-2-tuple.rs @@ -1,5 +1,4 @@ // compile-flags: -C opt-level=1 -Z merge-functions=disabled -// min-llvm-version: 15.0 // only-x86_64 #![crate_type = "lib"] diff --git a/tests/codegen/comparison-operators-newtype.rs b/tests/codegen/comparison-operators-newtype.rs index 683a2bd4f..8fd8a81df 100644 --- a/tests/codegen/comparison-operators-newtype.rs +++ b/tests/codegen/comparison-operators-newtype.rs @@ -3,7 +3,6 @@ // in the operators for such a type all optimize away. // compile-flags: -C opt-level=1 -// min-llvm-version: 15.0 #![crate_type = "lib"] diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index fc2badc41..3797e1a99 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -42,7 +42,7 @@ pub fn inline_enum_const() -> E<i8, i16> { #[no_mangle] pub fn low_align_const() -> E<i16, [i16; 3]> { // Check that low_align_const and high_align_const use the same constant - // CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 2 %{{[0-9]+}}, {{i8\*|ptr}} align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false) + // CHECK: memcpy.{{.+}}(ptr align 2 %_0, ptr align 2 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false) *&E::A(0) } @@ -50,6 +50,6 @@ pub fn low_align_const() -> E<i16, [i16; 3]> { #[no_mangle] pub fn high_align_const() -> E<i16, i32> { // Check that low_align_const and high_align_const use the same constant - // CHECK: memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false) + // CHECK: memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[LOW_HIGH]]{{.*}}, i{{(32|64)}} 8, i1 false) *&E::A(0) } diff --git a/tests/codegen/drop-in-place-noalias.rs b/tests/codegen/drop-in-place-noalias.rs index 725e6fc04..ece1e426c 100644 --- a/tests/codegen/drop-in-place-noalias.rs +++ b/tests/codegen/drop-in-place-noalias.rs @@ -7,9 +7,9 @@ use std::marker::PhantomPinned; -// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructUnpin{{.*}}({{.*\*|ptr}} noalias noundef align 4 dereferenceable(12) %{{.+}}) +// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructUnpin{{.*}}(ptr noalias noundef align 4 dereferenceable(12) %{{.+}}) -// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructNotUnpin{{.*}}({{.*\*|ptr}} noundef nonnull align 4 %{{.+}}) +// CHECK: define internal void @{{.*}}core{{.*}}ptr{{.*}}drop_in_place{{.*}}StructNotUnpin{{.*}}(ptr noundef nonnull align 4 %{{.+}}) pub struct StructUnpin { a: i32, diff --git a/tests/codegen/enum-bounds-check-derived-idx.rs b/tests/codegen/enum/enum-bounds-check-derived-idx.rs index aa66c2ed0..aa66c2ed0 100644 --- a/tests/codegen/enum-bounds-check-derived-idx.rs +++ b/tests/codegen/enum/enum-bounds-check-derived-idx.rs diff --git a/tests/codegen/enum-bounds-check-issue-13926.rs b/tests/codegen/enum/enum-bounds-check-issue-13926.rs index b26945bc5..b26945bc5 100644 --- a/tests/codegen/enum-bounds-check-issue-13926.rs +++ b/tests/codegen/enum/enum-bounds-check-issue-13926.rs diff --git a/tests/codegen/enum-bounds-check-issue-82871.rs b/tests/codegen/enum/enum-bounds-check-issue-82871.rs index 32fdc4a5f..32fdc4a5f 100644 --- a/tests/codegen/enum-bounds-check-issue-82871.rs +++ b/tests/codegen/enum/enum-bounds-check-issue-82871.rs diff --git a/tests/codegen/enum-bounds-check.rs b/tests/codegen/enum/enum-bounds-check.rs index 17322d591..17322d591 100644 --- a/tests/codegen/enum-bounds-check.rs +++ b/tests/codegen/enum/enum-bounds-check.rs diff --git a/tests/codegen/enum-debug-clike.rs b/tests/codegen/enum/enum-debug-clike.rs index 1e369a2c4..1e369a2c4 100644 --- a/tests/codegen/enum-debug-clike.rs +++ b/tests/codegen/enum/enum-debug-clike.rs diff --git a/tests/codegen/enum-debug-niche-2.rs b/tests/codegen/enum/enum-debug-niche-2.rs index 4b607d505..4b607d505 100644 --- a/tests/codegen/enum-debug-niche-2.rs +++ b/tests/codegen/enum/enum-debug-niche-2.rs diff --git a/tests/codegen/enum-debug-niche.rs b/tests/codegen/enum/enum-debug-niche.rs index b718a6854..b718a6854 100644 --- a/tests/codegen/enum-debug-niche.rs +++ b/tests/codegen/enum/enum-debug-niche.rs diff --git a/tests/codegen/enum-debug-tagged.rs b/tests/codegen/enum/enum-debug-tagged.rs index 095c49ac3..095c49ac3 100644 --- a/tests/codegen/enum-debug-tagged.rs +++ b/tests/codegen/enum/enum-debug-tagged.rs diff --git a/tests/codegen/enum-discriminant-value.rs b/tests/codegen/enum/enum-discriminant-value.rs index cc14c2120..cc14c2120 100644 --- a/tests/codegen/enum-discriminant-value.rs +++ b/tests/codegen/enum/enum-discriminant-value.rs diff --git a/tests/codegen/enum-match.rs b/tests/codegen/enum/enum-match.rs index 36c6be190..5548cd251 100644 --- a/tests/codegen/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -15,7 +15,7 @@ pub enum Enum0 { // CHECK-NEXT: start: // CHECK-NEXT: %1 = icmp eq i8 %0, 2 // CHECK-NEXT: %2 = and i8 %0, 1 -// CHECK-NEXT: %.0 = select i1 %1, i8 13, i8 %2 +// CHECK-NEXT: %_0.0 = select i1 %1, i8 13, i8 %2 #[no_mangle] pub fn match0(e: Enum0) -> u8 { use Enum0::*; diff --git a/tests/codegen/enum-u128.rs b/tests/codegen/enum/enum-u128.rs index f50d360ac..f50d360ac 100644 --- a/tests/codegen/enum-u128.rs +++ b/tests/codegen/enum/enum-u128.rs diff --git a/tests/codegen/fastcall-inreg.rs b/tests/codegen/fastcall-inreg.rs index 02f5d5459..ab19efa45 100644 --- a/tests/codegen/fastcall-inreg.rs +++ b/tests/codegen/fastcall-inreg.rs @@ -19,7 +19,7 @@ pub mod tests { #[no_mangle] pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {} - // CHECK: @f2({{i32\*|ptr}} inreg noundef %_1, {{i32\*|ptr}} inreg noundef %_2, {{i32\*|ptr}} noundef %_3) + // CHECK: @f2(ptr inreg noundef %_1, ptr inreg noundef %_2, ptr noundef %_3) #[no_mangle] pub extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {} diff --git a/tests/codegen/fewer-names.rs b/tests/codegen/fewer-names.rs index a09c79592..df1080bff 100644 --- a/tests/codegen/fewer-names.rs +++ b/tests/codegen/fewer-names.rs @@ -13,8 +13,8 @@ pub fn sum(x: u32, y: u32) -> u32 { // NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y) // NO-NEXT: start: - // NO-NEXT: %0 = add i32 %y, %x - // NO-NEXT: ret i32 %0 + // NO-NEXT: %z = add i32 %y, %x + // NO-NEXT: ret i32 %z let z = x + y; z } diff --git a/tests/codegen/function-arguments-noopt.rs b/tests/codegen/function-arguments-noopt.rs index 0c62e0d35..8fe6c790d 100644 --- a/tests/codegen/function-arguments-noopt.rs +++ b/tests/codegen/function-arguments-noopt.rs @@ -23,13 +23,13 @@ pub fn boolean_call(x: bool, f: fn(bool) -> bool) -> bool { f(x) } -// CHECK: align 4 {{i32\*|ptr}} @borrow({{i32\*|ptr}} align 4 %x) +// CHECK: align 4 ptr @borrow(ptr align 4 %x) #[no_mangle] pub fn borrow(x: &i32) -> &i32 { x } -// CHECK: align 4 {{i32\*|ptr}} @borrow_mut({{i32\*|ptr}} align 4 %x) +// CHECK: align 4 ptr @borrow_mut(ptr align 4 %x) #[no_mangle] pub fn borrow_mut(x: &mut i32) -> &mut i32 { x @@ -38,11 +38,11 @@ pub fn borrow_mut(x: &mut i32) -> &mut i32 { // CHECK-LABEL: @borrow_call #[no_mangle] pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 { - // CHECK: call align 4 {{i32\*|ptr}} %f({{i32\*|ptr}} align 4 %x) + // CHECK: call align 4 ptr %f(ptr align 4 %x) f(x) } -// CHECK: void @struct_({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %x) +// CHECK: void @struct_(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %x) #[no_mangle] pub fn struct_(x: S) -> S { x @@ -51,7 +51,7 @@ pub fn struct_(x: S) -> S { // CHECK-LABEL: @struct_call #[no_mangle] pub fn struct_call(x: S, f: fn(S) -> S) -> S { - // CHECK: call void %f({{%S\*|ptr}} sret(%S){{( %0)?}}, {{%S\*|ptr}} %{{.+}}) + // CHECK: call void %f(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %{{.+}}) f(x) } diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index d6f019016..a218596da 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -80,95 +80,95 @@ pub fn option_nonzero_int(x: Option<NonZeroU64>) -> Option<NonZeroU64> { x } -// CHECK: @readonly_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1) +// CHECK: @readonly_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn readonly_borrow(_: &i32) { } -// CHECK: noundef align 4 dereferenceable(4) {{i32\*|ptr}} @readonly_borrow_ret() +// CHECK: noundef align 4 dereferenceable(4) ptr @readonly_borrow_ret() #[no_mangle] pub fn readonly_borrow_ret() -> &'static i32 { loop {} } -// CHECK: @static_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1) +// CHECK: @static_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // static borrow may be captured #[no_mangle] pub fn static_borrow(_: &'static i32) { } -// CHECK: @named_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1) +// CHECK: @named_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // borrow with named lifetime may be captured #[no_mangle] pub fn named_borrow<'r>(_: &'r i32) { } -// CHECK: @unsafe_borrow({{i16\*|ptr}} noundef nonnull align 2 %_1) +// CHECK: @unsafe_borrow(ptr noundef nonnull align 2 %_1) // unsafe interior means this isn't actually readonly and there may be aliases ... #[no_mangle] pub fn unsafe_borrow(_: &UnsafeInner) { } -// CHECK: @mutable_unsafe_borrow({{i16\*|ptr}} noalias noundef align 2 dereferenceable(2) %_1) +// CHECK: @mutable_unsafe_borrow(ptr noalias noundef align 2 dereferenceable(2) %_1) // ... unless this is a mutable borrow, those never alias #[no_mangle] pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) { } -// CHECK: @mutable_borrow({{i32\*|ptr}} noalias noundef align 4 dereferenceable(4) %_1) +// CHECK: @mutable_borrow(ptr noalias noundef align 4 dereferenceable(4) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn mutable_borrow(_: &mut i32) { } -// CHECK: noundef align 4 dereferenceable(4) {{i32\*|ptr}} @mutable_borrow_ret() +// CHECK: noundef align 4 dereferenceable(4) ptr @mutable_borrow_ret() #[no_mangle] pub fn mutable_borrow_ret() -> &'static mut i32 { loop {} } #[no_mangle] -// CHECK: @mutable_notunpin_borrow({{i32\*|ptr}} noundef nonnull align 4 %_1) +// CHECK: @mutable_notunpin_borrow(ptr noundef nonnull align 4 %_1) // This one is *not* `noalias` because it might be self-referential. // It is also not `dereferenceable` due to // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>. pub fn mutable_notunpin_borrow(_: &mut NotUnpin) { } -// CHECK: @notunpin_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable(4) %_1) +// CHECK: @notunpin_borrow(ptr noalias noundef readonly align 4 dereferenceable(4) %_1) // But `&NotUnpin` behaves perfectly normal. #[no_mangle] pub fn notunpin_borrow(_: &NotUnpin) { } -// CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef readonly dereferenceable(32) %_1) +// CHECK: @indirect_struct(ptr noalias nocapture noundef readonly align 4 dereferenceable(32) %_1) #[no_mangle] pub fn indirect_struct(_: S) { } -// CHECK: @borrowed_struct({{%S\*|ptr}} noalias noundef readonly align 4 dereferenceable(32) %_1) +// CHECK: @borrowed_struct(ptr noalias noundef readonly align 4 dereferenceable(32) %_1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn borrowed_struct(_: &S) { } -// CHECK: @option_borrow({{i32\*|ptr}} noalias noundef readonly align 4 dereferenceable_or_null(4) %x) +// CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %x) #[no_mangle] pub fn option_borrow(x: Option<&i32>) { } -// CHECK: @option_borrow_mut({{i32\*|ptr}} noalias noundef align 4 dereferenceable_or_null(4) %x) +// CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %x) #[no_mangle] pub fn option_borrow_mut(x: Option<&mut i32>) { } -// CHECK: @raw_struct({{%S\*|ptr}} noundef %_1) +// CHECK: @raw_struct(ptr noundef %_1) #[no_mangle] pub fn raw_struct(_: *const S) { } -// CHECK: @raw_option_nonnull_struct({{i32\*|ptr}} noundef %_1) +// CHECK: @raw_option_nonnull_struct(ptr noundef %_1) #[no_mangle] pub fn raw_option_nonnull_struct(_: Option<NonNull<S>>) { } @@ -176,19 +176,19 @@ pub fn raw_option_nonnull_struct(_: Option<NonNull<S>>) { // `Box` can get deallocated during execution of the function, so it should // not get `dereferenceable`. -// CHECK: noundef nonnull align 4 {{i32\*|ptr}} @_box({{i32\*|ptr}} noalias noundef nonnull align 4 %x) +// CHECK: noundef nonnull align 4 ptr @_box(ptr noalias noundef nonnull align 4 %x) #[no_mangle] pub fn _box(x: Box<i32>) -> Box<i32> { x } -// CHECK: noundef nonnull align 4 {{i32\*|ptr}} @notunpin_box({{i32\*|ptr}} noundef nonnull align 4 %x) +// CHECK: noundef nonnull align 4 ptr @notunpin_box(ptr noundef nonnull align 4 %x) #[no_mangle] pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> { x } -// CHECK: @struct_return({{%S\*|ptr}} noalias nocapture noundef sret(%S) dereferenceable(32){{( %0)?}}) +// CHECK: @struct_return(ptr noalias nocapture noundef sret(%S) align 4 dereferenceable(32){{( %_0)?}}) #[no_mangle] pub fn struct_return() -> S { S { @@ -202,68 +202,68 @@ pub fn struct_return() -> S { pub fn helper(_: usize) { } -// CHECK: @slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @slice(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn slice(_: &[u8]) { } -// CHECK: @mutable_slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @mutable_slice(ptr noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn mutable_slice(_: &mut [u8]) { } -// CHECK: @unsafe_slice({{\[0 x i16\]\*|ptr}} noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @unsafe_slice(ptr noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1) // unsafe interior means this isn't actually readonly and there may be aliases ... #[no_mangle] pub fn unsafe_slice(_: &[UnsafeInner]) { } -// CHECK: @raw_slice({{\[0 x i8\]\*|ptr}} noundef %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @raw_slice(ptr noundef %_1.0, [[USIZE]] noundef %_1.1) #[no_mangle] pub fn raw_slice(_: *const [u8]) { } -// CHECK: @str({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) +// CHECK: @str(ptr noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn str(_: &[u8]) { } -// CHECK: @trait_borrow({{\{\}\*|ptr}} noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) +// CHECK: @trait_borrow(ptr noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn trait_borrow(_: &dyn Drop) { } -// CHECK: @option_trait_borrow({{i8\*|ptr}} noundef align 1 %x.0, {{i8\*|ptr}} %x.1) +// CHECK: @option_trait_borrow(ptr noundef align 1 %x.0, ptr %x.1) #[no_mangle] pub fn option_trait_borrow(x: Option<&dyn Drop>) { } -// CHECK: @option_trait_borrow_mut({{i8\*|ptr}} noundef align 1 %x.0, {{i8\*|ptr}} %x.1) +// CHECK: @option_trait_borrow_mut(ptr noundef align 1 %x.0, ptr %x.1) #[no_mangle] pub fn option_trait_borrow_mut(x: Option<&mut dyn Drop>) { } -// CHECK: @trait_raw({{\{\}\*|ptr}} noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) +// CHECK: @trait_raw(ptr noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1) #[no_mangle] pub fn trait_raw(_: *const dyn Drop) { } -// CHECK: @trait_box({{\{\}\*|ptr}} noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}}) +// CHECK: @trait_box(ptr noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}}) #[no_mangle] pub fn trait_box(_: Box<dyn Drop + Unpin>) { } -// CHECK: { {{i8\*|ptr}}, {{i8\*|ptr}} } @trait_option({{i8\*|ptr}} noalias noundef align 1 %x.0, {{i8\*|ptr}} %x.1) +// CHECK: { ptr, ptr } @trait_option(ptr noalias noundef align 1 %x.0, ptr %x.1) #[no_mangle] pub fn trait_option(x: Option<Box<dyn Drop + Unpin>>) -> Option<Box<dyn Drop + Unpin>> { x } -// CHECK: { {{\[0 x i16\]\*|ptr}}, [[USIZE]] } @return_slice({{\[0 x i16\]\*|ptr}} noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1) +// CHECK: { ptr, [[USIZE]] } @return_slice(ptr noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1) #[no_mangle] pub fn return_slice(x: &[u16]) -> &[u16] { x @@ -281,7 +281,7 @@ pub fn enum_id_2(x: Option<u8>) -> Option<u8> { x } -// CHECK: { {{\{\}\*|ptr}}, {{.+}} } @dyn_star({{\{\}\*|ptr}} noundef %x.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1) +// CHECK: { ptr, {{.+}} } @dyn_star(ptr noundef %x.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1) // Expect an ABI something like `{ {}*, [3 x i64]* }`, but that's hard to match on generically, // so do like the `trait_box` test and just match on `{{.+}}` for the vtable. #[no_mangle] diff --git a/tests/codegen/global_asm.rs b/tests/codegen/global_asm.rs index 41a99530a..4c2ccf4e0 100644 --- a/tests/codegen/global_asm.rs +++ b/tests/codegen/global_asm.rs @@ -1,24 +1,6 @@ -// ignore-aarch64 -// ignore-arm -// ignore-avr -// ignore-bpf -// ignore-bpf -// ignore-hexagon -// ignore-mips -// ignore-mips64 -// ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc -// ignore-sparc -// ignore-sparc64 -// ignore-s390x -// ignore-thumb -// ignore-nvptx64 -// ignore-spirv -// ignore-wasm32 -// ignore-wasm64 -// ignore-emscripten -// ignore-loongarch64 +// revisions: x32 x64 +//[x32] only-x86 +//[x64] only-x86_64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/global_asm_include.rs index e25c164f4..0fede8c71 100644 --- a/tests/codegen/global_asm_include.rs +++ b/tests/codegen/global_asm_include.rs @@ -1,24 +1,6 @@ -// ignore-aarch64 -// ignore-arm -// ignore-avr -// ignore-bpf -// ignore-bpf -// ignore-hexagon -// ignore-mips -// ignore-mips64 -// ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc -// ignore-sparc -// ignore-sparc64 -// ignore-s390x -// ignore-thumb -// ignore-nvptx64 -// ignore-spirv -// ignore-wasm32 -// ignore-wasm64 -// ignore-emscripten -// ignore-loongarch64 +// revisions: x32 x64 +//[x32] only-x86 +//[x64] only-x86_64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/global_asm_x2.rs index 71ecef124..1fc2825b2 100644 --- a/tests/codegen/global_asm_x2.rs +++ b/tests/codegen/global_asm_x2.rs @@ -1,24 +1,6 @@ -// ignore-aarch64 -// ignore-arm -// ignore-avr -// ignore-bpf -// ignore-bpf -// ignore-hexagon -// ignore-mips -// ignore-mips64 -// ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc -// ignore-sparc -// ignore-sparc64 -// ignore-s390x -// ignore-thumb -// ignore-nvptx64 -// ignore-spirv -// ignore-wasm32 -// ignore-wasm64 -// ignore-emscripten -// ignore-loongarch64 +// revisions: x32 x64 +//[x32] only-x86 +//[x64] only-x86_64 // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/tests/codegen/intrinsics/compare_bytes.rs b/tests/codegen/intrinsics/compare_bytes.rs new file mode 100644 index 000000000..e69224d81 --- /dev/null +++ b/tests/codegen/intrinsics/compare_bytes.rs @@ -0,0 +1,34 @@ +// revisions: INT32 INT16 +// compile-flags: -O +// [INT32] ignore-16bit +// [INT16] only-16bit + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::compare_bytes; + +#[no_mangle] +// CHECK-LABEL: @bytes_cmp( +pub unsafe fn bytes_cmp(a: *const u8, b: *const u8, n: usize) -> i32 { + // INT32: %[[TEMP:.+]] = tail call i32 @memcmp(ptr %a, ptr %b, {{i32|i64}} %n) + // INT32-NOT: sext + // INT32: ret i32 %[[TEMP]] + + // INT16: %[[TEMP1:.+]] = tail call i16 @memcmp(ptr %a, ptr %b, i16 %n) + // INT16: %[[TEMP2:.+]] = sext i16 %[[TEMP1]] to i32 + // INT16: ret i32 %[[TEMP2]] + compare_bytes(a, b, n) +} + +// Ensure that, even though there's an `sext` emitted by the intrinsic, +// that doesn't end up pessiming checks against zero. +#[no_mangle] +// CHECK-LABEL: @bytes_eq( +pub unsafe fn bytes_eq(a: *const u8, b: *const u8, n: usize) -> bool { + // CHECK: call {{.+}} @{{bcmp|memcmp}}(ptr %a, ptr %b, {{i16|i32|i64}} %n) + // CHECK-NOT: sext + // INT32: icmp eq i32 + // INT16: icmp eq i16 + compare_bytes(a, b, n) == 0_i32 +} diff --git a/tests/codegen/intrinsics/mask.rs b/tests/codegen/intrinsics/mask.rs index 8f93da2e5..82131c558 100644 --- a/tests/codegen/intrinsics/mask.rs +++ b/tests/codegen/intrinsics/mask.rs @@ -7,6 +7,6 @@ #[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|%1}}, [[WORD]] %mask) + // CHECK-SAME: @llvm.ptrmask.{{p0|p0i8}}.[[WORD]](ptr {{%ptr|%1}}, [[WORD]] %mask) core::intrinsics::ptr_mask(ptr, mask) } diff --git a/tests/codegen/intrinsics/nontemporal.rs b/tests/codegen/intrinsics/nontemporal.rs index d8ee29452..dc020c121 100644 --- a/tests/codegen/intrinsics/nontemporal.rs +++ b/tests/codegen/intrinsics/nontemporal.rs @@ -6,7 +6,7 @@ #[no_mangle] pub fn a(a: &mut u32, b: u32) { // CHECK-LABEL: define{{.*}}void @a - // CHECK: store i32 %b, {{i32\*|ptr}} %a, align 4, !nontemporal + // CHECK: store i32 %b, ptr %a, align 4, !nontemporal unsafe { std::intrinsics::nontemporal_store(a, b); } diff --git a/tests/codegen/intrinsics/offset.rs b/tests/codegen/intrinsics/offset.rs index 7fc4f4498..542bacf99 100644 --- a/tests/codegen/intrinsics/offset.rs +++ b/tests/codegen/intrinsics/offset.rs @@ -1,5 +1,4 @@ // compile-flags: -O -C no-prepopulate-passes -// min-llvm-version: 15.0 (because we're using opaque pointers) #![crate_type = "lib"] #![feature(core_intrinsics)] diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs index 69e9b1d12..e9c8d803c 100644 --- a/tests/codegen/intrinsics/transmute-niched.rs +++ b/tests/codegen/intrinsics/transmute-niched.rs @@ -2,7 +2,6 @@ // [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes // [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes // only-64bit (so I don't need to worry about usize) -// min-llvm-version: 15.0 # this test assumes `ptr`s #![crate_type = "lib"] @@ -169,16 +168,16 @@ pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool { // CHECK-LABEL: @check_bool_to_ordering( #[no_mangle] pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering { - // CHECK: %0 = zext i1 %x to i8 - // OPT: %1 = icmp ule i8 %0, 1 - // OPT: call void @llvm.assume(i1 %1) - // OPT: %2 = icmp uge i8 %0, -1 - // OPT: %3 = icmp ule i8 %0, 1 - // OPT: %4 = or i1 %2, %3 - // OPT: call void @llvm.assume(i1 %4) + // CHECK: %_0 = zext i1 %x to i8 + // OPT: %0 = icmp ule i8 %_0, 1 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp uge i8 %_0, -1 + // OPT: %2 = icmp ule i8 %_0, 1 + // OPT: %3 = or i1 %1, %2 + // OPT: call void @llvm.assume(i1 %3) // DBG-NOT: icmp // DBG-NOT: assume - // CHECK: ret i8 %0 + // CHECK: ret i8 %_0 transmute(x) } diff --git a/tests/codegen/intrinsics/transmute-x64.rs b/tests/codegen/intrinsics/transmute-x64.rs index 99d258c62..19020f628 100644 --- a/tests/codegen/intrinsics/transmute-x64.rs +++ b/tests/codegen/intrinsics/transmute-x64.rs @@ -1,6 +1,5 @@ // compile-flags: -O -C no-prepopulate-passes // only-x86_64 (it's using arch-specific types) -// min-llvm-version: 15.0 # this test assumes `ptr`s #![crate_type = "lib"] @@ -11,8 +10,8 @@ use std::mem::transmute; #[no_mangle] pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i { // CHECK-NOT: alloca - // CHECK: %1 = load <4 x float>, ptr %x, align 16 - // CHECK: store <4 x float> %1, ptr %0, align 16 + // CHECK: %0 = load <4 x float>, ptr %x, align 16 + // CHECK: store <4 x float> %0, ptr %_0, align 16 transmute(x) } @@ -20,8 +19,8 @@ pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i { #[no_mangle] pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i { // CHECK-NOT: alloca - // CHECK: %1 = load <4 x i64>, ptr %x, align 16 - // CHECK: store <4 x i64> %1, ptr %0, align 32 + // CHECK: %0 = load <4 x i64>, ptr %x, align 16 + // CHECK: store <4 x i64> %0, ptr %_0, align 32 transmute(x) } @@ -29,7 +28,7 @@ pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i { #[no_mangle] pub unsafe fn check_sse_pair_from_avx(x: __m256i) -> (__m128i, __m128i) { // CHECK-NOT: alloca - // CHECK: %1 = load <4 x i64>, ptr %x, align 32 - // CHECK: store <4 x i64> %1, ptr %0, align 16 + // CHECK: %0 = load <4 x i64>, ptr %x, align 32 + // CHECK: store <4 x i64> %0, ptr %_0, align 16 transmute(x) } diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index fe4249400..e64af33ab 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -1,6 +1,5 @@ // compile-flags: -O -C no-prepopulate-passes // only-64bit (so I don't need to worry about usize) -// min-llvm-version: 15.0 # this test assumes `ptr`s #![crate_type = "lib"] #![feature(core_intrinsics)] @@ -8,8 +7,8 @@ #![feature(inline_const)] #![allow(unreachable_code)] -use std::mem::MaybeUninit; use std::intrinsics::{transmute, transmute_unchecked}; +use std::mem::MaybeUninit; // Some of these need custom MIR to not get removed by MIR optimizations. use std::intrinsics::mir::*; @@ -63,7 +62,7 @@ pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] { // CHECK-NOT: trap // CHECK: call void @llvm.trap // CHECK-NOT: trap - mir!{ + mir! { { RET = CastTransmute(x); Return() @@ -78,7 +77,7 @@ pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] { // CHECK-NOT: trap // CHECK: call void @llvm.trap // CHECK-NOT: trap - mir!{ + mir! { { RET = CastTransmute(x); Return() @@ -93,7 +92,7 @@ pub unsafe fn check_to_uninhabited(x: u16) { // CHECK-NOT: trap // CHECK: call void @llvm.trap // CHECK-NOT: trap - mir!{ + mir! { let temp: BigNever; { temp = CastTransmute(x); @@ -107,7 +106,7 @@ pub unsafe fn check_to_uninhabited(x: u16) { #[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { // CHECK: ret i16 poison - mir!{ + mir! { { RET = CastTransmute(x); Return() @@ -122,9 +121,7 @@ pub unsafe fn check_intermediate_passthrough(x: u32) -> i32 { // CHECK: %[[TMP:.+]] = add i32 1, %x // CHECK: %[[RET:.+]] = add i32 %[[TMP]], 1 // CHECK: ret i32 %[[RET]] - unsafe { - transmute::<u32, i32>(1 + x) + 1 - } + unsafe { transmute::<u32, i32>(1 + x) + 1 } } // CHECK-LABEL: @check_nop_pair( @@ -134,9 +131,7 @@ pub unsafe fn check_nop_pair(x: (u8, i8)) -> (i8, u8) { // CHECK: %0 = insertvalue { i8, i8 } poison, i8 %x.0, 0 // CHECK: %1 = insertvalue { i8, i8 } %0, i8 %x.1, 1 // CHECK: ret { i8, i8 } %1 - unsafe { - transmute(x) - } + unsafe { transmute(x) } } // CHECK-LABEL: @check_to_newtype( @@ -168,9 +163,9 @@ pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool { // CHECK-LABEL: @check_aggregate_from_bool( #[no_mangle] pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 { - // CHECK: %0 = alloca %Aggregate8, align 1 + // CHECK: %_0 = alloca %Aggregate8, align 1 // CHECK: %[[BYTE:.+]] = zext i1 %x to i8 - // CHECK: store i8 %[[BYTE]], ptr %0, align 1 + // CHECK: store i8 %[[BYTE]], ptr %_0, align 1 transmute(x) } @@ -195,8 +190,8 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 { // CHECK-LABEL: @check_to_pair( #[no_mangle] pub unsafe fn check_to_pair(x: u64) -> Option<i32> { - // CHECK: %0 = alloca { i32, i32 }, align 4 - // CHECK: store i64 %x, ptr %0, align 4 + // CHECK: %_0 = alloca { i32, i32 }, align 4 + // CHECK: store i64 %x, ptr %_0, align 4 transmute(x) } @@ -207,11 +202,11 @@ pub unsafe fn check_from_pair(x: Option<i32>) -> u64 { // immediates so we can write using the destination alloca's alignment. const { assert!(std::mem::align_of::<Option<i32>>() == 4) }; - // CHECK: %0 = alloca i64, align 8 - // CHECK: store i32 %x.0, ptr %1, align 8 - // CHECK: store i32 %x.1, ptr %2, align 4 - // CHECK: %3 = load i64, ptr %0, align 8 - // CHECK: ret i64 %3 + // CHECK: %_0 = alloca i64, align 8 + // CHECK: store i32 %x.0, ptr %0, align 8 + // CHECK: store i32 %x.1, ptr %1, align 4 + // CHECK: %2 = load i64, ptr %_0, align 8 + // CHECK: ret i64 %2 transmute(x) } @@ -219,8 +214,8 @@ pub unsafe fn check_from_pair(x: Option<i32>) -> u64 { #[no_mangle] pub unsafe fn check_to_float(x: u32) -> f32 { // CHECK-NOT: alloca - // CHECK: %0 = bitcast i32 %x to float - // CHECK: ret float %0 + // CHECK: %_0 = bitcast i32 %x to float + // CHECK: ret float %_0 transmute(x) } @@ -228,16 +223,16 @@ pub unsafe fn check_to_float(x: u32) -> f32 { #[no_mangle] pub unsafe fn check_from_float(x: f32) -> u32 { // CHECK-NOT: alloca - // CHECK: %0 = bitcast float %x to i32 - // CHECK: ret i32 %0 + // CHECK: %_0 = bitcast float %x to i32 + // CHECK: ret i32 %_0 transmute(x) } // CHECK-LABEL: @check_to_bytes( #[no_mangle] pub unsafe fn check_to_bytes(x: u32) -> [u8; 4] { - // CHECK: %0 = alloca [4 x i8], align 1 - // CHECK: store i32 %x, ptr %0, align 1 + // CHECK: %_0 = alloca [4 x i8], align 1 + // CHECK: store i32 %x, ptr %_0, align 1 transmute(x) } @@ -253,10 +248,10 @@ pub unsafe fn check_from_bytes(x: [u8; 4]) -> u32 { // CHECK-LABEL: @check_to_aggregate( #[no_mangle] pub unsafe fn check_to_aggregate(x: u64) -> Aggregate64 { - // CHECK: %0 = alloca %Aggregate64, align 4 - // CHECK: store i64 %x, ptr %0, align 4 - // CHECK: %1 = load i64, ptr %0, align 4 - // CHECK: ret i64 %1 + // CHECK: %_0 = alloca %Aggregate64, align 4 + // CHECK: store i64 %x, ptr %_0, align 4 + // CHECK: %0 = load i64, ptr %_0, align 4 + // CHECK: ret i64 %0 transmute(x) } @@ -273,7 +268,7 @@ pub unsafe fn check_from_aggregate(x: Aggregate64) -> u64 { #[no_mangle] pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] { // CHECK-NEXT: start - // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %0, ptr align 8 %x, i64 800, i1 false) + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %_0, ptr align 8 %x, i64 800, i1 false) // CHECK-NEXT: ret void transmute(x) } @@ -282,7 +277,7 @@ pub unsafe fn check_long_array_less_aligned(x: [u64; 100]) -> [u16; 400] { #[no_mangle] pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] { // CHECK-NEXT: start - // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 1 %x, i64 100, i1 false) + // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %_0, ptr align 1 %x, i64 100, i1 false) // CHECK-NEXT: ret void transmute(x) } @@ -301,8 +296,8 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { pub unsafe fn check_float_to_pointer(x: f64) -> *const () { // CHECK-NOT: alloca // CHECK: %0 = bitcast double %x to i64 - // CHECK: %1 = inttoptr i64 %0 to ptr - // CHECK: ret ptr %1 + // CHECK: %_0 = inttoptr i64 %0 to ptr + // CHECK: ret ptr %_0 transmute(x) } @@ -311,8 +306,8 @@ pub unsafe fn check_float_to_pointer(x: f64) -> *const () { pub unsafe fn check_float_from_pointer(x: *const ()) -> f64 { // CHECK-NOT: alloca // CHECK: %0 = ptrtoint ptr %x to i64 - // CHECK: %1 = bitcast i64 %0 to double - // CHECK: ret double %1 + // CHECK: %_0 = bitcast i64 %0 to double + // CHECK: ret double %_0 transmute(x) } @@ -376,10 +371,10 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option<Box<[u8]>> { // CHECK-LABEL: @check_pair_to_dst_ref( #[no_mangle] pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] { - // CHECK: %0 = inttoptr i64 %x.0 to ptr - // CHECK: %1 = insertvalue { ptr, i64 } poison, ptr %0, 0 - // CHECK: %2 = insertvalue { ptr, i64 } %1, i64 %x.1, 1 - // CHECK: ret { ptr, i64 } %2 + // CHECK: %_0.0 = inttoptr i64 %x.0 to ptr + // CHECK: %0 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0 + // CHECK: %1 = insertvalue { ptr, i64 } %0, i64 %x.1, 1 + // CHECK: ret { ptr, i64 } %1 transmute(x) } @@ -391,7 +386,7 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] { // CHECK: start // CHECK-NEXT: ret void - mir!{ + mir! { { RET = CastTransmute(x); Return() @@ -408,7 +403,7 @@ pub unsafe fn check_unit_to_never(x: ()) { // CHECK-NOT: trap // CHECK: call void @llvm.trap // CHECK-NOT: trap - mir!{ + mir! { let temp: ZstNever; { temp = CastTransmute(x); @@ -425,7 +420,7 @@ pub unsafe fn check_unit_from_never(x: ZstNever) -> () { // CHECK: start // CHECK-NEXT: ret void - mir!{ + mir! { { RET = CastTransmute(x); Return() @@ -457,10 +452,10 @@ pub struct HighAlignScalar(u8); // CHECK-LABEL: @check_to_overalign( #[no_mangle] pub unsafe fn check_to_overalign(x: u64) -> HighAlignScalar { - // CHECK: %0 = alloca %HighAlignScalar, align 8 - // CHECK: store i64 %x, ptr %0, align 8 - // CHECK: %1 = load i64, ptr %0, align 8 - // CHECK: ret i64 %1 + // CHECK: %_0 = alloca %HighAlignScalar, align 8 + // CHECK: store i64 %x, ptr %_0, align 8 + // CHECK: %0 = load i64, ptr %_0, align 8 + // CHECK: ret i64 %0 transmute(x) } diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs index 6e0eacfe4..f345c96e6 100644 --- a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs +++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs @@ -1,6 +1,5 @@ // compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes -Zmir-enable-passes=-ScalarReplacementOfAggregates // MIR SROA will decompose the closure -// min-llvm-version: 15.0 # this test uses opaque pointer notation #![feature(stmt_expr_attributes)] pub struct S([usize; 8]); @@ -16,8 +15,8 @@ pub fn outer_function(x: S, y: S) -> usize { // Check that we do not attempt to load from the spilled arg before it is assigned to // when generating debuginfo. // CHECK-LABEL: @outer_function -// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:10:23: 10:25]" -// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:10:23: 10:25]", ptr [[spill]] +// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]" +// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]] // CHECK-NOT: [[load:%.*]] = load ptr, ptr // CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]]) // CHECK: [[inner:%.*]] = getelementptr inbounds %"{{.*}}", ptr [[spill]] diff --git a/tests/codegen/issues/issue-114312.rs b/tests/codegen/issues/issue-114312.rs index 28b029a8b..e2fbcef72 100644 --- a/tests/codegen/issues/issue-114312.rs +++ b/tests/codegen/issues/issue-114312.rs @@ -1,5 +1,5 @@ // compile-flags: -O -// min-system-llvm-version: 17 +// min-llvm-version: 17 // only-x86_64-unknown-linux-gnu // We want to check that this function does not mis-optimize to loop jumping. diff --git a/tests/codegen/issues/issue-37945.rs b/tests/codegen/issues/issue-37945.rs index 4f386d335..329769940 100644 --- a/tests/codegen/issues/issue-37945.rs +++ b/tests/codegen/issues/issue-37945.rs @@ -12,11 +12,11 @@ use std::slice::Iter; pub fn is_empty_1(xs: Iter<f32>) -> bool { // CHECK-LABEL: @is_empty_1( // CHECK-NEXT: start: -// CHECK-NEXT: [[A:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null +// CHECK-NEXT: [[A:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null // CHECK-NEXT: tail call void @llvm.assume(i1 [[A]]) // The order between %xs.0 and %xs.1 on the next line doesn't matter // and different LLVM versions produce different order. -// CHECK-NEXT: [[B:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}} +// CHECK-NEXT: [[B:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} // CHECK-NEXT: ret i1 [[B:%.*]] {xs}.next().is_none() } @@ -25,11 +25,11 @@ pub fn is_empty_1(xs: Iter<f32>) -> bool { pub fn is_empty_2(xs: Iter<f32>) -> bool { // CHECK-LABEL: @is_empty_2 // CHECK-NEXT: start: -// CHECK-NEXT: [[C:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null +// CHECK-NEXT: [[C:%.*]] = icmp ne ptr {{%xs.0|%xs.1}}, null // CHECK-NEXT: tail call void @llvm.assume(i1 [[C]]) // The order between %xs.0 and %xs.1 on the next line doesn't matter // and different LLVM versions produce different order. -// CHECK-NEXT: [[D:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}} +// CHECK-NEXT: [[D:%.*]] = icmp eq ptr {{%xs.0, %xs.1|%xs.1, %xs.0}} // CHECK-NEXT: ret i1 [[D:%.*]] xs.map(|&x| x).next().is_none() } diff --git a/tests/codegen/issues/issue-56267-2.rs b/tests/codegen/issues/issue-56267-2.rs index 4dc9ebfeb..1715e9f05 100644 --- a/tests/codegen/issues/issue-56267-2.rs +++ b/tests/codegen/issues/issue-56267-2.rs @@ -11,7 +11,7 @@ pub struct Foo<T> { // The load from bar.1 should have alignment 4. Not checking // other loads here, as the alignment will be platform-dependent. -// CHECK: %{{.+}} = load i32, {{i32\*|ptr}} %{{.+}}, align 4 +// CHECK: %{{.+}} = load i32, ptr %{{.+}}, align 4 #[no_mangle] pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) { x.bar diff --git a/tests/codegen/issues/issue-56267.rs b/tests/codegen/issues/issue-56267.rs index 7bdd25779..90aa9f7ae 100644 --- a/tests/codegen/issues/issue-56267.rs +++ b/tests/codegen/issues/issue-56267.rs @@ -11,7 +11,7 @@ pub struct Foo<T> { // The store writing to bar.1 should have alignment 4. Not checking // other stores here, as the alignment will be platform-dependent. -// CHECK: store i32 [[TMP1:%.+]], {{i32\*|ptr}} [[TMP2:%.+]], align 4 +// CHECK: store i32 [[TMP1:%.+]], ptr [[TMP2:%.+]], align 4 #[no_mangle] pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> { Foo { foo: 0, bar: x } diff --git a/tests/codegen/issues/issue-56927.rs b/tests/codegen/issues/issue-56927.rs index 044d72181..1b09ce565 100644 --- a/tests/codegen/issues/issue-56927.rs +++ b/tests/codegen/issues/issue-56927.rs @@ -8,10 +8,10 @@ pub struct S { } // CHECK-LABEL: @test1 -// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 16 -// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 4 -// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 8 -// CHECK: store i32 3, {{i32\*|ptr}} %{{.+}}, align 4 +// CHECK: store i32 0, ptr %{{.+}}, align 16 +// CHECK: store i32 1, ptr %{{.+}}, align 4 +// CHECK: store i32 2, ptr %{{.+}}, align 8 +// CHECK: store i32 3, ptr %{{.+}}, align 4 #[no_mangle] pub fn test1(s: &mut S) { s.arr[0] = 0; @@ -21,7 +21,7 @@ pub fn test1(s: &mut S) { } // CHECK-LABEL: @test2 -// CHECK: store i32 4, {{i32\*|ptr}} %{{.+}}, align 4 +// CHECK: store i32 4, ptr %{{.+}}, align 4 #[allow(unconditional_panic)] #[no_mangle] pub fn test2(s: &mut S) { @@ -29,14 +29,14 @@ pub fn test2(s: &mut S) { } // CHECK-LABEL: @test3 -// CHECK: store i32 5, {{i32\*|ptr}} %{{.+}}, align 4 +// CHECK: store i32 5, ptr %{{.+}}, align 4 #[no_mangle] pub fn test3(s: &mut S, i: usize) { s.arr[i] = 5; } // CHECK-LABEL: @test4 -// CHECK: store i32 6, {{i32\*|ptr}} %{{.+}}, align 4 +// CHECK: store i32 6, ptr %{{.+}}, align 4 #[no_mangle] pub fn test4(s: &mut S) { s.arr = [6; 4]; diff --git a/tests/codegen/issues/issue-58881.rs b/tests/codegen/issues/issue-58881.rs index 00f8953d9..a1d0e8eb7 100644 --- a/tests/codegen/issues/issue-58881.rs +++ b/tests/codegen/issues/issue-58881.rs @@ -16,6 +16,6 @@ struct Bar(u64, u64, u64); // Ensure that emit arguments of the correct type. pub unsafe fn test_call_variadic() { - // CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, {{%Bar\*|ptr}} {{.*}}) + // CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, ptr {{.*}}) variadic_fn(0, Foo(0), Bar(0, 0, 0)) } diff --git a/tests/codegen/issues/issue-85872-multiple-reverse.rs b/tests/codegen/issues/issue-85872-multiple-reverse.rs index 591a1aca7..a4723a0e9 100644 --- a/tests/codegen/issues/issue-85872-multiple-reverse.rs +++ b/tests/codegen/issues/issue-85872-multiple-reverse.rs @@ -1,4 +1,3 @@ -// min-llvm-version: 15.0.0 // compile-flags: -O #![crate_type = "lib"] diff --git a/tests/codegen/issues/issue-86106.rs b/tests/codegen/issues/issue-86106.rs index be5034dcf..15aef344a 100644 --- a/tests/codegen/issues/issue-86106.rs +++ b/tests/codegen/issues/issue-86106.rs @@ -1,4 +1,3 @@ -// min-llvm-version: 15.0 // only-64bit llvm appears to use stores instead of memset on 32bit // compile-flags: -C opt-level=3 -Z merge-functions=disabled diff --git a/tests/codegen/issues/issue-96274.rs b/tests/codegen/issues/issue-96274.rs index 28bfcce0d..a44789ce3 100644 --- a/tests/codegen/issues/issue-96274.rs +++ b/tests/codegen/issues/issue-96274.rs @@ -1,4 +1,3 @@ -// min-llvm-version: 15.0 // compile-flags: -O #![crate_type = "lib"] diff --git a/tests/codegen/issues/issue-96497-slice-size-nowrap.rs b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs index 0413ed6b2..3ea6a5405 100644 --- a/tests/codegen/issues/issue-96497-slice-size-nowrap.rs +++ b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs @@ -3,7 +3,6 @@ // in some situations, see https://github.com/rust-lang/rust/issues/96497#issuecomment-1112865218 // compile-flags: -O -// min-llvm-version: 15.0 #![crate_type="lib"] diff --git a/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs b/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs index 7da29cd79..b87e43c13 100644 --- a/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs +++ b/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs @@ -1,4 +1,3 @@ -// min-llvm-version: 15.0.0 // ignore-debug: The debug assertions get in the way // compile-flags: -O diff --git a/tests/codegen/iter-repeat-n-trivial-drop.rs b/tests/codegen/iter-repeat-n-trivial-drop.rs index 24059f190..0b08e5781 100644 --- a/tests/codegen/iter-repeat-n-trivial-drop.rs +++ b/tests/codegen/iter-repeat-n-trivial-drop.rs @@ -33,7 +33,8 @@ pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCop // CHECK: [[EMPTY]]: // CHECK-NOT: br - // CHECK: phi i16 [ undef, %start ], [ %[[VAL]], %[[NOT_EMPTY]] ] + // CHECK: phi i16 + // CHECK-SAME: [ %[[VAL]], %[[NOT_EMPTY]] ] // CHECK-NOT: br // CHECK: ret diff --git a/tests/codegen/lifetime_start_end.rs b/tests/codegen/lifetime_start_end.rs index 471a0b8ce..16175dc18 100644 --- a/tests/codegen/lifetime_start_end.rs +++ b/tests/codegen/lifetime_start_end.rs @@ -8,7 +8,7 @@ pub fn test() { let a = 0u8; &a; // keep variable in an alloca -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %a) +// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %a) { let b = &Some(a); @@ -26,9 +26,9 @@ pub fn test() { let c = 1u8; &c; // keep variable in an alloca -// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %c) +// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, ptr %c) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %c) +// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %c) -// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, {{i8\*|ptr}} %a) +// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, ptr %a) } diff --git a/tests/codegen/llvm-ident.rs b/tests/codegen/llvm-ident.rs new file mode 100644 index 000000000..927f0d602 --- /dev/null +++ b/tests/codegen/llvm-ident.rs @@ -0,0 +1,15 @@ +// Verifies that the `!llvm.ident` named metadata is emitted. +// +// revisions: NONE OPT DEBUG +// +// [OPT] compile-flags: -Copt-level=2 +// [DEBUG] compile-flags: -Cdebuginfo=2 + +// The named metadata should contain a single metadata node (see +// `LLVMRustPrepareThinLTOImport` for details). +// CHECK: !llvm.ident = !{![[ID:[0-9]+]]} + +// In addition, check that the metadata node has the expected content. +// CHECK: ![[ID]] = !{!"rustc version 1.{{.*}}"} + +fn main() {} diff --git a/tests/codegen/loads.rs b/tests/codegen/loads.rs index f29a26596..4a09a1dc0 100644 --- a/tests/codegen/loads.rs +++ b/tests/codegen/loads.rs @@ -28,22 +28,22 @@ pub fn ptr_alignment_helper(x: &&()) {} // CHECK-LABEL: @load_ref #[no_mangle] pub fn load_ref<'a>(x: &&'a i32) -> &'a i32 { - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}} + // CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META:[0-9]+]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_ref_higher_alignment #[no_mangle] pub fn load_ref_higher_alignment<'a>(x: &&'a Align16) -> &'a Align16 { - // CHECK: load {{%Align16\*|i128\*|ptr}}, {{%Align16\*\*|i128\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}} + // CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META:[0-9]+]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_scalar_pair #[no_mangle] pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16) { - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}} - // CHECK: load {{i64\*|ptr}}, {{i64\*\*|ptr}} %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}} + // CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}} + // CHECK: load ptr, ptr %{{.+}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_16_META]], !noundef !{{[0-9]+}} *x } @@ -51,70 +51,70 @@ pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16 #[no_mangle] pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 { // loaded raw pointer should not have !nonnull or !align metadata - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !noundef ![[NOUNDEF:[0-9]+]]{{$}} + // CHECK: load ptr, ptr %x, align [[PTR_ALIGNMENT]], !noundef ![[NOUNDEF:[0-9]+]]{{$}} *x } // CHECK-LABEL: @load_box #[no_mangle] pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> { - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}} + // CHECK: load ptr, ptr %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_bool #[no_mangle] pub fn load_bool(x: &bool) -> bool { - // CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}} + // CHECK: load i8, ptr %x, align 1, !range ![[BOOL_RANGE:[0-9]+]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_maybeuninit_bool #[no_mangle] pub fn load_maybeuninit_bool(x: &MaybeUninit<bool>) -> MaybeUninit<bool> { - // CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}} + // CHECK: load i8, ptr %x, align 1{{$}} *x } // CHECK-LABEL: @load_enum_bool #[no_mangle] pub fn load_enum_bool(x: &MyBool) -> MyBool { - // CHECK: load i8, {{i8\*|ptr}} %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}} + // CHECK: load i8, ptr %x, align 1, !range ![[BOOL_RANGE]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_maybeuninit_enum_bool #[no_mangle] pub fn load_maybeuninit_enum_bool(x: &MaybeUninit<MyBool>) -> MaybeUninit<MyBool> { - // CHECK: load i8, {{i8\*|ptr}} %x, align 1{{$}} + // CHECK: load i8, ptr %x, align 1{{$}} *x } // CHECK-LABEL: @load_int #[no_mangle] pub fn load_int(x: &u16) -> u16 { - // CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef ![[NOUNDEF]]{{$}} + // CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}} *x } // CHECK-LABEL: @load_nonzero_int #[no_mangle] pub fn load_nonzero_int(x: &NonZeroU16) -> NonZeroU16 { - // CHECK: load i16, {{i16\*|ptr}} %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}} + // CHECK: load i16, ptr %x, align 2, !range ![[NONZEROU16_RANGE:[0-9]+]], !noundef !{{[0-9]+}} *x } // CHECK-LABEL: @load_option_nonzero_int #[no_mangle] pub fn load_option_nonzero_int(x: &Option<NonZeroU16>) -> Option<NonZeroU16> { - // CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef ![[NOUNDEF]]{{$}} + // CHECK: load i16, ptr %x, align 2, !noundef ![[NOUNDEF]]{{$}} *x } // CHECK-LABEL: @borrow #[no_mangle] pub fn borrow(x: &i32) -> &i32 { - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, !nonnull + // CHECK: load ptr, ptr %x{{.*}}, !nonnull &x; // keep variable in an alloca x } @@ -122,7 +122,7 @@ pub fn borrow(x: &i32) -> &i32 { // CHECK-LABEL: @_box #[no_mangle] pub fn _box(x: Box<i32>) -> i32 { - // CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x{{.*}}, align [[PTR_ALIGNMENT]] + // CHECK: load ptr, ptr %x{{.*}}, align [[PTR_ALIGNMENT]] *x } @@ -131,7 +131,7 @@ pub fn _box(x: Box<i32>) -> i32 { // dependent alignment #[no_mangle] pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] { - // CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1 + // CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1 // CHECK: ret i32 [[VAR]] x } @@ -141,7 +141,7 @@ pub fn small_array_alignment(x: [i8; 4]) -> [i8; 4] { // dependent alignment #[no_mangle] pub fn small_struct_alignment(x: Bytes) -> Bytes { - // CHECK: [[VAR:%[0-9]+]] = load i32, {{i32\*|ptr}} %{{.*}}, align 1 + // CHECK: [[VAR:%[0-9]+]] = load i32, ptr %{{.*}}, align 1 // CHECK: ret i32 [[VAR]] x } diff --git a/tests/codegen/i686-macosx-deployment-target.rs b/tests/codegen/macos/i686-macosx-deployment-target.rs index 17258a264..17258a264 100644 --- a/tests/codegen/i686-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-macosx-deployment-target.rs diff --git a/tests/codegen/i686-no-macosx-deployment-target.rs b/tests/codegen/macos/i686-no-macosx-deployment-target.rs index 043040a95..043040a95 100644 --- a/tests/codegen/i686-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/i686-no-macosx-deployment-target.rs diff --git a/tests/codegen/x86_64-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-macosx-deployment-target.rs index 8e673d11d..8e673d11d 100644 --- a/tests/codegen/x86_64-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-macosx-deployment-target.rs diff --git a/tests/codegen/x86_64-no-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs index 25ae6924d..25ae6924d 100644 --- a/tests/codegen/x86_64-no-macosx-deployment-target.rs +++ b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs diff --git a/tests/codegen/match-optimized.rs b/tests/codegen/match-optimized.rs index 520c46a0d..e32a5e545 100644 --- a/tests/codegen/match-optimized.rs +++ b/tests/codegen/match-optimized.rs @@ -20,13 +20,13 @@ pub fn exhaustive_match(e: E) -> u8 { // CHECK-NEXT: unreachable // // CHECK: [[A]]: -// CHECK-NEXT: store i8 0, {{i8\*|ptr}} %1, align 1 +// CHECK-NEXT: store i8 0, ptr %_0, align 1 // CHECK-NEXT: br label %[[EXIT:[a-zA-Z0-9_]+]] // CHECK: [[B]]: -// CHECK-NEXT: store i8 1, {{i8\*|ptr}} %1, align 1 +// CHECK-NEXT: store i8 1, ptr %_0, align 1 // CHECK-NEXT: br label %[[EXIT]] // CHECK: [[C]]: -// CHECK-NEXT: store i8 2, {{i8\*|ptr}} %1, align 1 +// CHECK-NEXT: store i8 2, ptr %_0, align 1 // CHECK-NEXT: br label %[[EXIT]] match e { E::A => 0, diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs index c6b920cf5..fc3e9d22b 100644 --- a/tests/codegen/mem-replace-big-type.rs +++ b/tests/codegen/mem-replace-big-type.rs @@ -25,9 +25,9 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big { // For a large type, we expect exactly three `memcpy`s // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) +// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false) +// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %dest, ptr align 8 %src, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/mem-replace-simple-type.rs b/tests/codegen/mem-replace-simple-type.rs index 751aeaa2b..be3af989e 100644 --- a/tests/codegen/mem-replace-simple-type.rs +++ b/tests/codegen/mem-replace-simple-type.rs @@ -1,5 +1,4 @@ // compile-flags: -O -C no-prepopulate-passes -// min-llvm-version: 15.0 (for opaque pointers) // only-x86_64 (to not worry about usize differing) // ignore-debug (the debug assertions get in the way) @@ -37,7 +36,7 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str { // CHECK-LABEL: @replace_short_array_3( pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { // CHECK-NOT: alloca - // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 4 %r, i64 12, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %result, ptr align 4 %r, i64 12, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false) std::mem::replace(r, v) } @@ -47,7 +46,7 @@ pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] { // CHECK-NOT: alloca // CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4 - // CHECK: store <4 x i32> %[[R]], ptr %0 + // CHECK: store <4 x i32> %[[R]], ptr %result // CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4 // CHECK: store <4 x i32> %[[V]], ptr %r std::mem::replace(r, v) diff --git a/tests/codegen/method-declaration.rs b/tests/codegen/method-declaration.rs new file mode 100644 index 000000000..4ae332b01 --- /dev/null +++ b/tests/codegen/method-declaration.rs @@ -0,0 +1,26 @@ +// compile-flags: -g -Cno-prepopulate-passes + +// Verify that we added a declaration for a method. + +// CHECK: define{{.*}}@method{{.*}} !dbg ![[METHOD_DEF_DBG:[0-9]+]] +// CHECK: define{{.*}}@function{{.*}} !dbg ![[FUNC_DEF_DBG:[0-9]+]] + +#![crate_type = "lib"] + +// CHECK-DAG: ![[FOO_DBG:[0-9]+]] = !DICompositeType(tag: {{.*}} name: "Foo", {{.*}} identifier: +pub struct Foo; + +impl Foo { + // CHECK-DAG: ![[METHOD_DEF_DBG]] = distinct !DISubprogram(name: "method"{{.*}}, scope: ![[FOO_DBG]]{{.*}}DISPFlagDefinition{{.*}}, declaration: ![[METHOD_DECL_DBG:[0-9]+]] + // CHECK-DAG: ![[METHOD_DECL_DBG]] = !DISubprogram(name: "method"{{.*}}, scope: ![[FOO_DBG]] + #[no_mangle] + pub fn method() {} +} + +// CHECK: ![[FUNC_DEF_DBG]] = distinct !DISubprogram(name: "function" +// CHECK-NOT: declaration +// CHECK-SAME: DISPFlagDefinition +// CHECK-NOT: declaration +// CHECK-SAME: ) +#[no_mangle] +pub fn function() {} diff --git a/tests/codegen/move-operands.rs b/tests/codegen/move-operands.rs index 1d8209e8e..cd87e6d81 100644 --- a/tests/codegen/move-operands.rs +++ b/tests/codegen/move-operands.rs @@ -1,4 +1,5 @@ -// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation,-CopyProp +// Verify that optimized MIR only copies `a` once. +// compile-flags: -O -C no-prepopulate-passes #![crate_type = "lib"] @@ -6,7 +7,7 @@ type T = [u8; 256]; #[no_mangle] pub fn f(a: T, b: fn(_: T, _: T)) { - // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, {{.*}} 256, i1 false) - // CHECK-NOT: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, {{.*}} 256, i1 false) + // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, {{.*}} 256, i1 false) + // CHECK-NOT: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, {{.*}} 256, i1 false) b(a, a) } diff --git a/tests/codegen/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs index e05bbc26e..e05bbc26e 100644 --- a/tests/codegen/naked-functions.rs +++ b/tests/codegen/naked-fn/naked-functions.rs diff --git a/tests/codegen/naked-nocoverage.rs b/tests/codegen/naked-fn/naked-nocoverage.rs index 3c755e49c..3c755e49c 100644 --- a/tests/codegen/naked-nocoverage.rs +++ b/tests/codegen/naked-fn/naked-nocoverage.rs diff --git a/tests/codegen/naked-noinline.rs b/tests/codegen/naked-fn/naked-noinline.rs index 5cfb500c0..5cfb500c0 100644 --- a/tests/codegen/naked-noinline.rs +++ b/tests/codegen/naked-fn/naked-noinline.rs diff --git a/tests/codegen/no_builtins-at-crate.rs b/tests/codegen/no_builtins-at-crate.rs new file mode 100644 index 000000000..02ed67090 --- /dev/null +++ b/tests/codegen/no_builtins-at-crate.rs @@ -0,0 +1,24 @@ +// compile-flags: -C opt-level=1 + +#![no_builtins] +#![crate_type = "lib"] + +// CHECK: define +// CHECK-SAME: @__aeabi_memcpy +// CHECK-SAME: #0 +#[no_mangle] +pub unsafe extern "C" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, size: usize) { + // CHECK: call + // CHECK-SAME: @memcpy( + memcpy(dest, src, size); +} + +// CHECK: declare +// CHECK-SAME: @memcpy +// CHECK-SAME: #0 +extern "C" { + pub fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; +} + +// CHECK: attributes #0 +// CHECK-SAME: "no-builtins" diff --git a/tests/codegen/option-nonzero-eq.rs b/tests/codegen/option-nonzero-eq.rs index a394695f3..ce5b6328a 100644 --- a/tests/codegen/option-nonzero-eq.rs +++ b/tests/codegen/option-nonzero-eq.rs @@ -32,7 +32,7 @@ pub fn non_zero_signed_eq(l: Option<NonZeroI64>, r: Option<NonZeroI64>) -> bool #[no_mangle] pub fn non_null_eq(l: Option<NonNull<u8>>, r: Option<NonNull<u8>>) -> bool { // CHECK: start: - // CHECK-NEXT: icmp eq {{(i8\*|ptr)}} + // CHECK-NEXT: icmp eq ptr // CHECK-NEXT: ret i1 l == r } diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs index fd63b4f0a..96cd9a42e 100644 --- a/tests/codegen/packed.rs +++ b/tests/codegen/packed.rs @@ -18,8 +18,8 @@ pub struct Packed2 { // CHECK-LABEL: @write_pkd1 #[no_mangle] pub fn write_pkd1(pkd: &mut Packed1) -> u32 { -// CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 1 -// CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 1 +// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 1 +// CHECK: store i32 42, ptr %{{.*}}, align 1 let result = pkd.data; pkd.data = 42; result @@ -28,8 +28,8 @@ pub fn write_pkd1(pkd: &mut Packed1) -> u32 { // CHECK-LABEL: @write_pkd2 #[no_mangle] pub fn write_pkd2(pkd: &mut Packed2) -> u32 { -// CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 2 -// CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 2 +// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 2 +// CHECK: store i32 42, ptr %{{.*}}, align 2 let result = pkd.data; pkd.data = 42; result @@ -52,8 +52,8 @@ pub struct BigPacked2 { #[no_mangle] pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array -// CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) +// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an // unaligned destination. @@ -64,8 +64,8 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { #[no_mangle] pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 { // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array -// CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) +// CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct // go through an alloca rather than calling the function with an // unaligned destination. @@ -73,9 +73,9 @@ pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 { } // CHECK-LABEL: @write_packed_array1 -// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 1 -// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 1 -// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 1 +// CHECK: store i32 0, ptr %{{.+}}, align 1 +// CHECK: store i32 1, ptr %{{.+}}, align 1 +// CHECK: store i32 2, ptr %{{.+}}, align 1 #[no_mangle] pub fn write_packed_array1(p: &mut BigPacked1) { p.data.0[0] = 0; @@ -84,9 +84,9 @@ pub fn write_packed_array1(p: &mut BigPacked1) { } // CHECK-LABEL: @write_packed_array2 -// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 2 -// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 2 -// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 2 +// CHECK: store i32 0, ptr %{{.+}}, align 2 +// CHECK: store i32 1, ptr %{{.+}}, align 2 +// CHECK: store i32 2, ptr %{{.+}}, align 2 #[no_mangle] pub fn write_packed_array2(p: &mut BigPacked2) { p.data.0[0] = 0; @@ -95,14 +95,14 @@ pub fn write_packed_array2(p: &mut BigPacked2) { } // CHECK-LABEL: @repeat_packed_array1 -// CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 1 +// CHECK: store i32 42, ptr %{{.+}}, align 1 #[no_mangle] pub fn repeat_packed_array1(p: &mut BigPacked1) { p.data.0 = [42; 8]; } // CHECK-LABEL: @repeat_packed_array2 -// CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 2 +// CHECK: store i32 42, ptr %{{.+}}, align 2 #[no_mangle] pub fn repeat_packed_array2(p: &mut BigPacked2) { p.data.0 = [42; 8]; @@ -119,14 +119,14 @@ pub struct Packed2Pair(u8, u32); // CHECK-LABEL: @pkd1_pair #[no_mangle] pub fn pkd1_pair(pair1: &mut Packed1Pair, pair2: &mut Packed1Pair) { -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false) *pair2 = *pair1; } // CHECK-LABEL: @pkd2_pair #[no_mangle] pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) { -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false) *pair2 = *pair1; } @@ -141,13 +141,13 @@ pub struct Packed2NestedPair((u32, u32)); // CHECK-LABEL: @pkd1_nested_pair #[no_mangle] pub fn pkd1_nested_pair(pair1: &mut Packed1NestedPair, pair2: &mut Packed1NestedPair) { -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false) *pair2 = *pair1; } // CHECK-LABEL: @pkd2_nested_pair #[no_mangle] pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2NestedPair) { -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false) +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false) *pair2 = *pair1; } diff --git a/tests/codegen/personality_lifetimes.rs b/tests/codegen/personality_lifetimes.rs index 9ff7a9b3e..47243bece 100644 --- a/tests/codegen/personality_lifetimes.rs +++ b/tests/codegen/personality_lifetimes.rs @@ -22,7 +22,7 @@ pub fn test() { let _s = S; // Check that the personality slot alloca gets a lifetime start in each cleanup block, not just // in the first one. - // CHECK: [[SLOT:%[0-9]+]] = alloca { {{i8\*|ptr}}, i32 } + // CHECK: [[SLOT:%[0-9]+]] = alloca { ptr, i32 } // CHECK-LABEL: cleanup: // CHECK: call void @llvm.lifetime.start.{{.*}}({{.*}}) // CHECK-LABEL: cleanup1: diff --git a/tests/codegen/ptr-arithmetic.rs b/tests/codegen/ptr-arithmetic.rs new file mode 100644 index 000000000..292bfdaf3 --- /dev/null +++ b/tests/codegen/ptr-arithmetic.rs @@ -0,0 +1,34 @@ +// compile-flags: -O -Z merge-functions=disabled +// ignore-debug (the extra assertions get in the way) + +#![crate_type = "lib"] + +// CHECK-LABEL: ptr @i32_add( +// CHECK-SAME: [[WORD:i[0-9]+]] noundef %n) +#[no_mangle] +pub unsafe fn i32_add(p: *const i32, n: usize) -> *const i32 { + // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %n + // CHECK: ret ptr %[[TEMP]] + p.add(n) +} + +// Ensure we tell LLVM that the negation in `sub` can't overflow. + +// CHECK-LABEL: ptr @i32_sub( +// CHECK-SAME: [[WORD:i[0-9]+]] noundef %n) +#[no_mangle] +pub unsafe fn i32_sub(p: *const i32, n: usize) -> *const i32 { + // CHECK: %[[DELTA:.+]] = sub nsw [[WORD]] 0, %n + // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %[[DELTA]] + // CHECK: ret ptr %[[TEMP]] + p.sub(n) +} + +// CHECK-LABEL: ptr @i32_offset( +// CHECK-SAME: [[WORD:i[0-9]+]] noundef %d) +#[no_mangle] +pub unsafe fn i32_offset(p: *const i32, d: isize) -> *const i32 { + // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %d + // CHECK: ret ptr %[[TEMP]] + p.offset(d) +} diff --git a/tests/codegen/refs.rs b/tests/codegen/refs.rs index a52897667..1c7746a30 100644 --- a/tests/codegen/refs.rs +++ b/tests/codegen/refs.rs @@ -13,9 +13,9 @@ pub fn helper(_: usize) { pub fn ref_dst(s: &[u8]) { // We used to generate an extra alloca and memcpy to ref the dst, so check that we copy // directly to the alloca for "x" -// CHECK: [[X0:%[0-9]+]] = getelementptr inbounds { {{\[0 x i8\]\*|ptr}}, [[USIZE]] }, {{.*}} %x, i32 0, i32 0 -// CHECK: store {{\[0 x i8\]\*|ptr}} %s.0, {{.*}} [[X0]] -// CHECK: [[X1:%[0-9]+]] = getelementptr inbounds { {{\[0 x i8\]\*|ptr}}, [[USIZE]] }, {{.*}} %x, i32 0, i32 1 +// CHECK: [[X0:%[0-9]+]] = getelementptr inbounds { ptr, [[USIZE]] }, {{.*}} %x, i32 0, i32 0 +// CHECK: store ptr %s.0, {{.*}} [[X0]] +// CHECK: [[X1:%[0-9]+]] = getelementptr inbounds { ptr, [[USIZE]] }, {{.*}} %x, i32 0, i32 1 // CHECK: store [[USIZE]] %s.1, {{.*}} [[X1]] let x = &*s; diff --git a/tests/codegen/repeat-trusted-len.rs b/tests/codegen/repeat-trusted-len.rs index 87c8fe135..bd6ff977e 100644 --- a/tests/codegen/repeat-trusted-len.rs +++ b/tests/codegen/repeat-trusted-len.rs @@ -8,13 +8,13 @@ use std::iter; // CHECK-LABEL: @repeat_take_collect #[no_mangle] pub fn repeat_take_collect() -> Vec<u8> { -// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 42, i{{[0-9]+}} 100000, i1 false) + // CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}align 1{{.*}} %{{.*}}, i8 42, i{{[0-9]+}} 100000, i1 false) iter::repeat(42).take(100000).collect() } // CHECK-LABEL: @repeat_with_take_collect #[no_mangle] pub fn repeat_with_take_collect() -> Vec<u8> { -// CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}align 1{{.*}} %{{[0-9]+}}, i8 13, i{{[0-9]+}} 12345, i1 false) + // CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}align 1{{.*}} %{{.*}}, i8 13, i{{[0-9]+}} 12345, i1 false) iter::repeat_with(|| 13).take(12345).collect() } diff --git a/tests/codegen/repr-transparent-aggregates-1.rs b/tests/codegen/repr-transparent-aggregates-1.rs deleted file mode 100644 index 9c4b0e58e..000000000 --- a/tests/codegen/repr-transparent-aggregates-1.rs +++ /dev/null @@ -1,88 +0,0 @@ -// compile-flags: -O -C no-prepopulate-passes -// - -// ignore-arm -// ignore-aarch64 -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-powerpc64 -// ignore-riscv64 see codegen/riscv-abi -// ignore-s390x -// ignore-windows -// ignore-loongarch64 -// See repr-transparent.rs - -#![feature(transparent_unions)] - -#![crate_type="lib"] - - -#[derive(Clone, Copy)] -#[repr(C)] -pub struct BigS([u32; 16]); - -#[repr(transparent)] -pub struct TsBigS(BigS); - -#[repr(transparent)] -pub union TuBigS { - field: BigS, -} - -#[repr(transparent)] -pub enum TeBigS { - Variant(BigS), -} - -// CHECK: define{{.*}}void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], {{%BigS\*|ptr}} [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) -#[no_mangle] -pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } - -// CHECK: define{{.*}}void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], {{%TsBigS\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) -#[no_mangle] -pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } - -// CHECK: define{{.*}}void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], {{%TuBigS\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) -#[no_mangle] -pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } - -// CHECK: define{{.*}}void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], {{%"TeBigS::Variant"\*|ptr}} [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) -#[no_mangle] -pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - - -#[derive(Clone, Copy)] -#[repr(C)] -pub union BigU { - foo: [u32; 16], -} - -#[repr(transparent)] -pub struct TsBigU(BigU); - -#[repr(transparent)] -pub union TuBigU { - field: BigU, -} - -#[repr(transparent)] -pub enum TeBigU { - Variant(BigU), -} - -// CHECK: define{{.*}}void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], {{%BigU\*|ptr}} [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) -#[no_mangle] -pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } - -// CHECK: define{{.*}}void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], {{%TsBigU\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) -#[no_mangle] -pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } - -// CHECK: define{{.*}}void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], {{%TuBigU\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) -#[no_mangle] -pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } - -// CHECK: define{{.*}}void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], {{%"TeBigU::Variant"\*|ptr}} [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) -#[no_mangle] -pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr-transparent-aggregates-2.rs b/tests/codegen/repr-transparent-aggregates-2.rs deleted file mode 100644 index a7bde2d05..000000000 --- a/tests/codegen/repr-transparent-aggregates-2.rs +++ /dev/null @@ -1,90 +0,0 @@ -// compile-flags: -C no-prepopulate-passes -// - -// ignore-aarch64 -// ignore-emscripten -// ignore-mips64 -// ignore-powerpc -// ignore-powerpc64 -// ignore-riscv64 see codegen/riscv-abi -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-x86 -// ignore-x86_64 -// ignore-loongarch64 -// See repr-transparent.rs - -#![feature(transparent_unions)] - -#![crate_type="lib"] - - -#[derive(Clone, Copy)] -#[repr(C)] -pub struct BigS([u32; 16]); - -#[repr(transparent)] -pub struct TsBigS(BigS); - -#[repr(transparent)] -pub union TuBigS { - field: BigS, -} - -#[repr(transparent)] -pub enum TeBigS { - Variant(BigS), -} - -// CHECK: define void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32] -#[no_mangle] -pub extern fn test_BigS(_: BigS) -> BigS { loop {} } - -// CHECK: define void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } - -// CHECK: define void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } - -// CHECK: define void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - - -#[derive(Clone, Copy)] -#[repr(C)] -pub union BigU { - foo: [u32; 16], -} - -#[repr(transparent)] -pub struct TsBigU(BigU); - -#[repr(transparent)] -pub union TuBigU { - field: BigU, -} - -#[repr(transparent)] -pub enum TeBigU { - Variant(BigU), -} - -// CHECK: define void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32] -#[no_mangle] -pub extern fn test_BigU(_: BigU) -> BigU { loop {} } - -// CHECK: define void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } - -// CHECK: define void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } - -// CHECK: define void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32] -#[no_mangle] -pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr-transparent-aggregates-3.rs b/tests/codegen/repr-transparent-aggregates-3.rs deleted file mode 100644 index 0db17e6b1..000000000 --- a/tests/codegen/repr-transparent-aggregates-3.rs +++ /dev/null @@ -1,79 +0,0 @@ -// compile-flags: -C no-prepopulate-passes -// - -// only-mips64 -// See repr-transparent.rs - -#![feature(transparent_unions)] - -#![crate_type="lib"] - - -#[derive(Clone, Copy)] -#[repr(C)] -pub struct BigS([u32; 16]); - -#[repr(transparent)] -pub struct TsBigS(BigS); - -#[repr(transparent)] -pub union TuBigS { - field: BigS, -} - -#[repr(transparent)] -pub enum TeBigS { - Variant(BigS), -} - -// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [8 x i64] -#[no_mangle] -pub extern fn test_BigS(_: BigS) -> BigS { loop {} } - -// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } - -// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } - -// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } - - -#[derive(Clone, Copy)] -#[repr(C)] -pub union BigU { - foo: [u32; 16], -} - -#[repr(transparent)] -pub struct TsBigU(BigU); - -#[repr(transparent)] -pub union TuBigU { - field: BigU, -} - -#[repr(transparent)] -pub enum TeBigU { - Variant(BigU), -} - -// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [8 x i64] -#[no_mangle] -pub extern fn test_BigU(_: BigU) -> BigU { loop {} } - -// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } - -// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } - -// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [8 x i64] -#[no_mangle] -pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr-transparent.rs b/tests/codegen/repr-transparent.rs deleted file mode 100644 index 759ddea67..000000000 --- a/tests/codegen/repr-transparent.rs +++ /dev/null @@ -1,171 +0,0 @@ -// compile-flags: -O -C no-prepopulate-passes - -// ignore-riscv64 riscv64 has an i128 type used with test_Vector -// see codegen/riscv-abi for riscv functiona call tests -// ignore-s390x s390x with default march passes vector types per reference -// ignore-loongarch64 see codegen/loongarch-abi for loongarch function call tests - -#![crate_type="lib"] -#![feature(repr_simd, transparent_unions)] - -use std::marker::PhantomData; - -#[derive(Copy, Clone)] -pub struct Zst1; -#[derive(Copy, Clone)] -pub struct Zst2(()); - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct F32(f32); - -// CHECK: define{{.*}}float @test_F32(float noundef %_1) -#[no_mangle] -pub extern "C" fn test_F32(_: F32) -> F32 { loop {} } - -#[repr(transparent)] -pub struct Ptr(*mut u8); - -// CHECK: define{{.*}}{{i8\*|ptr}} @test_Ptr({{i8\*|ptr}} noundef %_1) -#[no_mangle] -pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} } - -#[repr(transparent)] -pub struct WithZst(u64, Zst1); - -// CHECK: define{{.*}}i64 @test_WithZst(i64 noundef %_1) -#[no_mangle] -pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } - -#[repr(transparent)] -pub struct WithZeroSizedArray(*const f32, [i8; 0]); - -// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. -// CHECK: define{{.*}}{{i32\*|ptr}} @test_WithZeroSizedArray({{i32\*|ptr}} noundef %_1) -#[no_mangle] -pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } - -#[repr(transparent)] -pub struct Generic<T>(T); - -// CHECK: define{{.*}}double @test_Generic(double noundef %_1) -#[no_mangle] -pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} } - -#[repr(transparent)] -pub struct GenericPlusZst<T>(T, Zst2); - -#[repr(u8)] -pub enum Bool { True, False, FileNotFound } - -// CHECK: define{{( dso_local)?}} noundef{{( zeroext)?}} i8 @test_Gpz(i8 noundef{{( zeroext)?}} %_1) -#[no_mangle] -pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} } - -#[repr(transparent)] -pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); - -// CHECK: define{{.*}}{{i16\*|ptr}} @test_LifetimePhantom({{i16\*|ptr}} noundef %_1) -#[no_mangle] -pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} } - -// This works despite current alignment resrictions because PhantomData is always align(1) -#[repr(transparent)] -pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> } - -pub struct Px; - -// CHECK: define{{.*}}float @test_UnitPhantom(float noundef %_1) -#[no_mangle] -pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} } - -#[repr(transparent)] -pub struct TwoZsts(Zst1, i8, Zst2); - -// CHECK: define{{( dso_local)?}} noundef{{( signext)?}} i8 @test_TwoZsts(i8 noundef{{( signext)?}} %_1) -#[no_mangle] -pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } - -#[repr(transparent)] -pub struct Nested1(Zst2, Generic<f64>); - -// CHECK: define{{.*}}double @test_Nested1(double noundef %_1) -#[no_mangle] -pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} } - -#[repr(transparent)] -pub struct Nested2(Nested1, Zst1); - -// CHECK: define{{.*}}double @test_Nested2(double noundef %_1) -#[no_mangle] -pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} } - -#[repr(simd)] -struct f32x4(f32, f32, f32, f32); - -#[repr(transparent)] -pub struct Vector(f32x4); - -// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1) -#[no_mangle] -pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} } - -trait Mirror { type It: ?Sized; } -impl<T: ?Sized> Mirror for T { type It = Self; } - -#[repr(transparent)] -pub struct StructWithProjection(<f32 as Mirror>::It); - -// CHECK: define{{.*}}float @test_Projection(float noundef %_1) -#[no_mangle] -pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } - -#[repr(transparent)] -pub enum EnumF32 { - Variant(F32) -} - -// CHECK: define{{.*}}float @test_EnumF32(float noundef %_1) -#[no_mangle] -pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} } - -#[repr(transparent)] -pub enum EnumF32WithZsts { - Variant(Zst1, F32, Zst2) -} - -// CHECK: define{{.*}}float @test_EnumF32WithZsts(float noundef %_1) -#[no_mangle] -pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} } - -#[repr(transparent)] -pub union UnionF32 { - field: F32, -} - -// CHECK: define{{.*}} float @test_UnionF32(float %_1) -#[no_mangle] -pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } - -#[repr(transparent)] -pub union UnionF32WithZsts { - zst1: Zst1, - field: F32, - zst2: Zst2, -} - -// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1) -#[no_mangle] -pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} } - - -// All that remains to be tested are aggregates. They are tested in separate files called repr- -// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR -// function signatures vary so much that it's not reasonably possible to cover all of them with a -// single CHECK line. -// -// You may be wondering why we don't just compare the return types and argument types for equality -// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes -// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of -// pointee types yet, the IR function signature will be syntactically different (%Foo* vs -// %FooWrapper*). diff --git a/tests/codegen/repr/transparent-imm-array.rs b/tests/codegen/repr/transparent-imm-array.rs new file mode 100644 index 000000000..6d7127785 --- /dev/null +++ b/tests/codegen/repr/transparent-imm-array.rs @@ -0,0 +1,86 @@ +// revisions: arm mips thumb wasm32 +// compile-flags: -C no-prepopulate-passes +// +//[arm] only-arm +//[mips] only-mips +//[thumb] only-thumb +//[wasm32] only-wasm32 +// ignore-emscripten +// See ./transparent.rs +// Some platforms pass large aggregates using immediate arrays in LLVMIR +// Other platforms pass large aggregates using struct pointer in LLVMIR +// This covers the "immediate array" case. + +#![feature(transparent_unions)] + +#![crate_type="lib"] + + +#[derive(Clone, Copy)] +#[repr(C)] +pub struct BigS([u32; 16]); + +#[repr(transparent)] +pub struct TsBigS(BigS); + +#[repr(transparent)] +pub union TuBigS { + field: BigS, +} + +#[repr(transparent)] +pub enum TeBigS { + Variant(BigS), +} + +// CHECK: define void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32] +#[no_mangle] +pub extern fn test_BigS(_: BigS) -> BigS { loop {} } + +// CHECK: define void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } + +// CHECK: define void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } + +// CHECK: define void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } + + +#[derive(Clone, Copy)] +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct TsBigU(BigU); + +#[repr(transparent)] +pub union TuBigU { + field: BigU, +} + +#[repr(transparent)] +pub enum TeBigU { + Variant(BigU), +} + +// CHECK: define void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32] +#[no_mangle] +pub extern fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define void @test_TsBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } + +// CHECK: define void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } + +// CHECK: define void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32] +#[no_mangle] +pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr/transparent-mips64.rs b/tests/codegen/repr/transparent-mips64.rs new file mode 100644 index 000000000..245daf13e --- /dev/null +++ b/tests/codegen/repr/transparent-mips64.rs @@ -0,0 +1,79 @@ +// compile-flags: -C no-prepopulate-passes +// + +// only-mips64 +// See ./transparent.rs + +#![feature(transparent_unions)] + +#![crate_type="lib"] + + +#[derive(Clone, Copy)] +#[repr(C)] +pub struct BigS([u32; 16]); + +#[repr(transparent)] +pub struct TsBigS(BigS); + +#[repr(transparent)] +pub union TuBigS { + field: BigS, +} + +#[repr(transparent)] +pub enum TeBigS { + Variant(BigS), +} + +// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [8 x i64] +#[no_mangle] +pub extern fn test_BigS(_: BigS) -> BigS { loop {} } + +// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } + +// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } + +// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } + + +#[derive(Clone, Copy)] +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct TsBigU(BigU); + +#[repr(transparent)] +pub union TuBigU { + field: BigU, +} + +#[repr(transparent)] +pub enum TeBigU { + Variant(BigU), +} + +// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [8 x i64] +#[no_mangle] +pub extern fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } + +// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } + +// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [8 x i64] +#[no_mangle] +pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr/transparent-struct-ptr.rs b/tests/codegen/repr/transparent-struct-ptr.rs new file mode 100644 index 000000000..d2120f7ec --- /dev/null +++ b/tests/codegen/repr/transparent-struct-ptr.rs @@ -0,0 +1,87 @@ +// revisions: x32 x64 sparc sparc64 +// compile-flags: -O -C no-prepopulate-passes +// +//[x32] only-x86 +//[x64] only-x86_64 +//[sparc] only-sparc +//[sparc64] only-sparc64 +// ignore-windows +// See ./transparent.rs +// Some platforms pass large aggregates using immediate arrays in LLVMIR +// Other platforms pass large aggregates using struct pointer in LLVMIR +// This covers the "struct pointer" case. + + +#![feature(transparent_unions)] + +#![crate_type="lib"] + + +#[derive(Clone, Copy)] +#[repr(C)] +pub struct BigS([u32; 16]); + +#[repr(transparent)] +pub struct TsBigS(BigS); + +#[repr(transparent)] +pub union TuBigS { + field: BigS, +} + +#[repr(transparent)] +pub enum TeBigS { + Variant(BigS), +} + +// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]] byval(%BigS) [[BIGS_ARG_ATTRS2:.*]]) +#[no_mangle] +pub extern "C" fn test_BigS(_: BigS) -> BigS { loop {} } + +// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TsBigS) [[BIGS_ARG_ATTRS2:.*]]) +#[no_mangle] +pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} } + +// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%TuBigS) [[BIGS_ARG_ATTRS2:.*]]) +#[no_mangle] +pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} } + +// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]] byval(%"TeBigS::Variant") [[BIGS_ARG_ATTRS2]]) +#[no_mangle] +pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} } + + +#[derive(Clone, Copy)] +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct TsBigU(BigU); + +#[repr(transparent)] +pub union TuBigU { + field: BigU, +} + +#[repr(transparent)] +pub enum TeBigU { + Variant(BigU), +} + +// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]] byval(%BigU) [[BIGU_ARG_ATTRS2:.*]]) +#[no_mangle] +pub extern "C" fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret(%TsBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TsBigU) [[BIGU_ARG_ATTRS2]]) +#[no_mangle] +pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} } + +// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%TuBigU) [[BIGU_ARG_ATTRS2]]) +#[no_mangle] +pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} } + +// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]] byval(%"TeBigU::Variant") [[BIGU_ARG_ATTRS2]]) +#[no_mangle] +pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} } diff --git a/tests/codegen/repr-transparent-sysv64.rs b/tests/codegen/repr/transparent-sysv64.rs index 886b0dd9e..886b0dd9e 100644 --- a/tests/codegen/repr-transparent-sysv64.rs +++ b/tests/codegen/repr/transparent-sysv64.rs diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs new file mode 100644 index 000000000..b140fc719 --- /dev/null +++ b/tests/codegen/repr/transparent.rs @@ -0,0 +1,174 @@ +// compile-flags: -O -C no-prepopulate-passes +// ignore-riscv64 riscv64 has an i128 type used with test_Vector +// ignore-s390x s390x with default march passes vector types per reference +// ignore-loongarch64 see codegen/loongarch-abi for loongarch function call tests + +// This codegen test embeds assumptions about how certain "C" psABIs are handled +// so it doesn't apply to all architectures or even all OS +// For RISCV: see codegen/riscv-abi +// For LoongArch: see codegen/loongarch-abi + +#![crate_type="lib"] +#![feature(repr_simd, transparent_unions)] + +use std::marker::PhantomData; + +#[derive(Copy, Clone)] +pub struct Zst1; +#[derive(Copy, Clone)] +pub struct Zst2(()); + +#[derive(Copy, Clone)] +#[repr(transparent)] +pub struct F32(f32); + +// CHECK: define{{.*}}float @test_F32(float noundef %_1) +#[no_mangle] +pub extern "C" fn test_F32(_: F32) -> F32 { loop {} } + +#[repr(transparent)] +pub struct Ptr(*mut u8); + +// CHECK: define{{.*}}ptr @test_Ptr(ptr noundef %_1) +#[no_mangle] +pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} } + +#[repr(transparent)] +pub struct WithZst(u64, Zst1); + +// CHECK: define{{.*}}i64 @test_WithZst(i64 noundef %_1) +#[no_mangle] +pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } + +#[repr(transparent)] +pub struct WithZeroSizedArray(*const f32, [i8; 0]); + +// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. +// CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1) +#[no_mangle] +pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } + +#[repr(transparent)] +pub struct Generic<T>(T); + +// CHECK: define{{.*}}double @test_Generic(double noundef %_1) +#[no_mangle] +pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} } + +#[repr(transparent)] +pub struct GenericPlusZst<T>(T, Zst2); + +#[repr(u8)] +pub enum Bool { True, False, FileNotFound } + +// CHECK: define{{( dso_local)?}} noundef{{( zeroext)?}} i8 @test_Gpz(i8 noundef{{( zeroext)?}} %_1) +#[no_mangle] +pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} } + +#[repr(transparent)] +pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); + +// CHECK: define{{.*}}ptr @test_LifetimePhantom(ptr noundef %_1) +#[no_mangle] +pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} } + +// This works despite current alignment resrictions because PhantomData is always align(1) +#[repr(transparent)] +pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> } + +pub struct Px; + +// CHECK: define{{.*}}float @test_UnitPhantom(float noundef %_1) +#[no_mangle] +pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} } + +#[repr(transparent)] +pub struct TwoZsts(Zst1, i8, Zst2); + +// CHECK: define{{( dso_local)?}} noundef{{( signext)?}} i8 @test_TwoZsts(i8 noundef{{( signext)?}} %_1) +#[no_mangle] +pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } + +#[repr(transparent)] +pub struct Nested1(Zst2, Generic<f64>); + +// CHECK: define{{.*}}double @test_Nested1(double noundef %_1) +#[no_mangle] +pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} } + +#[repr(transparent)] +pub struct Nested2(Nested1, Zst1); + +// CHECK: define{{.*}}double @test_Nested2(double noundef %_1) +#[no_mangle] +pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} } + +#[repr(simd)] +struct f32x4(f32, f32, f32, f32); + +#[repr(transparent)] +pub struct Vector(f32x4); + +// CHECK: define{{.*}}<4 x float> @test_Vector(<4 x float> %_1) +#[no_mangle] +pub extern "C" fn test_Vector(_: Vector) -> Vector { loop {} } + +trait Mirror { type It: ?Sized; } +impl<T: ?Sized> Mirror for T { type It = Self; } + +#[repr(transparent)] +pub struct StructWithProjection(<f32 as Mirror>::It); + +// CHECK: define{{.*}}float @test_Projection(float noundef %_1) +#[no_mangle] +pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } + +#[repr(transparent)] +pub enum EnumF32 { + Variant(F32) +} + +// CHECK: define{{.*}}float @test_EnumF32(float noundef %_1) +#[no_mangle] +pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} } + +#[repr(transparent)] +pub enum EnumF32WithZsts { + Variant(Zst1, F32, Zst2) +} + +// CHECK: define{{.*}}float @test_EnumF32WithZsts(float noundef %_1) +#[no_mangle] +pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} } + +#[repr(transparent)] +pub union UnionF32 { + field: F32, +} + +// CHECK: define{{.*}} float @test_UnionF32(float %_1) +#[no_mangle] +pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } + +#[repr(transparent)] +pub union UnionF32WithZsts { + zst1: Zst1, + field: F32, + zst2: Zst2, +} + +// CHECK: define{{.*}}float @test_UnionF32WithZsts(float %_1) +#[no_mangle] +pub extern "C" fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} } + + +// All that remains to be tested are aggregates. They are tested in separate files called +// transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR +// function signatures vary so much that it's not reasonably possible to cover all of them with a +// single CHECK line. +// +// You may be wondering why we don't just compare the return types and argument types for equality +// with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes +// containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of +// pointee types yet, the IR function signature will be syntactically different (%Foo* vs +// %FooWrapper*). diff --git a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs index 045f01985..fdb9c6217 100644 --- a/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs +++ b/tests/codegen/riscv-abi/riscv64-lp64-lp64f-lp64d-abi.rs @@ -127,18 +127,18 @@ pub struct Large { d: i64, } -// CHECK: define void @f_agg_large({{%Large\*|ptr}} {{.*}}%x) +// CHECK: define void @f_agg_large(ptr {{.*}}%x) #[no_mangle] pub extern "C" fn f_agg_large(mut x: Large) { } -// CHECK: define void @f_agg_large_ret({{%Large\*|ptr}} {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j) +// CHECK: define void @f_agg_large_ret(ptr {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j) #[no_mangle] pub extern "C" fn f_agg_large_ret(i: i32, j: i8) -> Large { Large { a: 1, b: 2, c: 3, d: 4 } } -// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, {{%Large\*|ptr}} {{.*}}%d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h) +// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, ptr {{.*}}%d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h) #[no_mangle] pub extern "C" fn f_scalar_stack_1( a: Tiny, @@ -152,7 +152,7 @@ pub extern "C" fn f_scalar_stack_1( ) { } -// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %0, i64 noundef %a, i128 %1, i128 %2, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) +// CHECK: define void @f_scalar_stack_2(ptr {{.*}}sret{{.*}} %_0, i64 noundef %a, i128 %0, i128 %1, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g) #[no_mangle] pub extern "C" fn f_scalar_stack_2( a: u64, @@ -172,7 +172,7 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn f_va_caller() { - // CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, {{%Large\*|ptr}} {{.*}}) + // CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, ptr {{.*}}) f_va_callee( 1, 2i32, diff --git a/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs b/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs deleted file mode 100644 index 2b61c9078..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-checks-attr-no-sanitize.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Verifies that pointer type membership tests for indirect calls are omitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 - -#![crate_type="lib"] -#![feature(no_sanitize)] - -#[no_sanitize(cfi)] -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: sanitizer_cfi_emit_type_checks_attr_no_sanitize::foo - // CHECK: Function Attrs: {{.*}} - // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: start: - // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) - // CHECK-NEXT: ret i32 {{%.+}} - f(arg) -} diff --git a/tests/codegen/sanitizer-cfi-emit-type-checks.rs b/tests/codegen/sanitizer-cfi-emit-type-checks.rs deleted file mode 100644 index cea6aac8b..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-checks.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Verifies that pointer type membership tests for indirect calls are emitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 - -#![crate_type="lib"] - -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: start: - // CHECK: [[TT:%.+]] = call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"{{[[:print:]]+}}") - // CHECK-NEXT: br i1 [[TT]], label %type_test.pass, label %type_test.fail - // CHECK: type_test.pass: - // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) - // CHECK: type_test.fail: - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: unreachable - f(arg) -} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs deleted file mode 100644 index 63e63c5d4..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ /dev/null @@ -1,604 +0,0 @@ -// Verifies that type metadata identifiers for functions are emitted correctly. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi - -#![crate_type="lib"] -#![allow(dead_code)] -#![allow(incomplete_features)] -#![allow(unused_must_use)] -#![feature(adt_const_params, extern_types, inline_const, type_alias_impl_trait)] - -extern crate core; -use core::ffi::*; -use std::marker::PhantomData; - -// User-defined type (structure) -pub struct Struct1<T> { - member1: T, -} - -// User-defined type (enum) -pub enum Enum1<T> { - Variant1(T), -} - -// User-defined type (union) -pub union Union1<T> { - member1: std::mem::ManuallyDrop<T>, -} - -// Extern type -extern { - pub type type1; -} - -// Trait -pub trait Trait1<T> { - fn foo(&self) { } -} - -// Trait implementation -impl<T> Trait1<T> for i32 { - fn foo(&self) { } -} - -// Trait implementation -impl<T, U> Trait1<T> for Struct1<U> { - fn foo(&self) { } -} - -// impl Trait type aliases for helping with defining other types (see below) -pub type Type1 = impl Send; -pub type Type2 = impl Send; -pub type Type3 = impl Send; -pub type Type4 = impl Send; -pub type Type5 = impl Send; -pub type Type6 = impl Send; -pub type Type7 = impl Send; -pub type Type8 = impl Send; -pub type Type9 = impl Send; -pub type Type10 = impl Send; -pub type Type11 = impl Send; - -pub fn fn1<'a>() where - Type1: 'static, - Type2: 'static, - Type3: 'static, - Type4: 'static, - Type5: 'static, - Type6: 'static, - Type7: 'static, - Type8: 'static, - Type9: 'static, - Type10: 'static, - Type11: 'static, -{ - // Closure - let closure1 = || { }; - let _: Type1 = closure1; - - // Constructor - pub struct Foo(i32); - let _: Type2 = Foo; - - // Type in extern path - extern { - fn foo(); - } - let _: Type3 = foo; - - // Type in closure path - || { - pub struct Foo; - let _: Type4 = Foo; - }; - - // Type in const path - const { - pub struct Foo; - fn foo() -> Type5 { Foo } - }; - - // Type in impl path - impl<T> Struct1<T> { - fn foo(&self) { } - } - let _: Type6 = <Struct1<i32>>::foo; - - // Trait method - let _: Type7 = <dyn Trait1<i32>>::foo; - - // Trait method - let _: Type8 = <i32 as Trait1<i32>>::foo; - - // Trait method - let _: Type9 = <Struct1<i32> as Trait1<i32>>::foo; - - // Const generics - pub struct Qux<T, const N: usize>([T; N]); - let _: Type10 = Qux([0; 32]); - - // Lifetimes/regions - pub struct Quux<'a>(&'a i32); - pub struct Quuux<'a, 'b>(&'a i32, &'b Quux<'b>); - let _: Type11 = Quuux; -} - -// Helper type to make Type12 have an unique id -struct Foo(i32); - -// repr(transparent) user-defined type -#[repr(transparent)] -pub struct Type12 { - member1: (), - member2: PhantomData<i32>, - member3: Foo, -} - -// Self-referencing repr(transparent) user-defined type -#[repr(transparent)] -pub struct Type13<'a> { - member1: (), - member2: PhantomData<i32>, - member3: &'a Type13<'a>, -} - -// Helper type to make Type14 have an unique id -pub struct Bar; - -// repr(transparent) user-defined generic type -#[repr(transparent)] -pub struct Type14<T>(T); - -pub fn foo0(_: ()) { } -// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo1(_: (), _: c_void) { } -// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo2(_: (), _: c_void, _: c_void) { } -// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo3(_: *mut ()) { } -// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo4(_: *mut (), _: *mut c_void) { } -// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) { } -// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo6(_: *const ()) { } -// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo7(_: *const (), _: *const c_void) { } -// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) { } -// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo9(_: bool) { } -// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo10(_: bool, _: bool) { } -// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo11(_: bool, _: bool, _: bool) { } -// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo12(_: i8) { } -// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo13(_: i8, _: i8) { } -// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo14(_: i8, _: i8, _: i8) { } -// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo15(_: i16) { } -// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo16(_: i16, _: i16) { } -// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo17(_: i16, _: i16, _: i16) { } -// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo18(_: i32) { } -// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo19(_: i32, _: i32) { } -// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo20(_: i32, _: i32, _: i32) { } -// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo21(_: i64) { } -// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo22(_: i64, _: i64) { } -// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo23(_: i64, _: i64, _: i64) { } -// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo24(_: i128) { } -// CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo25(_: i128, _: i128) { } -// CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo26(_: i128, _: i128, _: i128) { } -// CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo27(_: isize) { } -// CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo28(_: isize, _: isize) { } -// CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo29(_: isize, _: isize, _: isize) { } -// CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo30(_: u8) { } -// CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo31(_: u8, _: u8) { } -// CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo32(_: u8, _: u8, _: u8) { } -// CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo33(_: u16) { } -// CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo34(_: u16, _: u16) { } -// CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo35(_: u16, _: u16, _: u16) { } -// CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo36(_: u32) { } -// CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo37(_: u32, _: u32) { } -// CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo38(_: u32, _: u32, _: u32) { } -// CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo39(_: u64) { } -// CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo40(_: u64, _: u64) { } -// CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo41(_: u64, _: u64, _: u64) { } -// CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo42(_: u128) { } -// CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo43(_: u128, _: u128) { } -// CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo44(_: u128, _: u128, _: u128) { } -// CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo45(_: usize) { } -// CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo46(_: usize, _: usize) { } -// CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo47(_: usize, _: usize, _: usize) { } -// CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo48(_: f32) { } -// CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo49(_: f32, _: f32) { } -// CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo50(_: f32, _: f32, _: f32) { } -// CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo51(_: f64) { } -// CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo52(_: f64, _: f64) { } -// CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo53(_: f64, _: f64, _: f64) { } -// CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo54(_: char) { } -// CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo55(_: char, _: char) { } -// CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo56(_: char, _: char, _: char) { } -// CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo57(_: &str) { } -// CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo58(_: &str, _: &str) { } -// CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo59(_: &str, _: &str, _: &str) { } -// CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo60(_: (i32, i32)) { } -// CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo61(_: (i32, i32), _: (i32, i32)) { } -// CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { } -// CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo63(_: [i32; 32]) { } -// CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo64(_: [i32; 32], _: [i32; 32]) { } -// CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { } -// CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo66(_: &[i32]) { } -// CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo67(_: &[i32], _: &[i32]) { } -// CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) { } -// CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo69(_: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo70(_: &Struct1::<i32>, _: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo71(_: &Struct1::<i32>, _: &Struct1::<i32>, _: &Struct1::<i32>) { } -// CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo72(_: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo73(_: &Enum1::<i32>, _: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo74(_: &Enum1::<i32>, _: &Enum1::<i32>, _: &Enum1::<i32>) { } -// CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo75(_: &Union1::<i32>) { } -// CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo76(_: &Union1::<i32>, _: &Union1::<i32>) { } -// CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo77(_: &Union1::<i32>, _: &Union1::<i32>, _: &Union1::<i32>) { } -// CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo78(_: *mut type1) { } -// CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo79(_: *mut type1, _: *mut type1) { } -// CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) { } -// CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo81(_: &mut i32) { } -// CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo82(_: &mut i32, _: &i32) { } -// CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo83(_: &mut i32, _: &i32, _: &i32) { } -// CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo84(_: &i32) { } -// CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo85(_: &i32, _: &mut i32) { } -// CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) { } -// CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo87(_: *mut i32) { } -// CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo88(_: *mut i32, _: *const i32) { } -// CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) { } -// CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo90(_: *const i32) { } -// CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo91(_: *const i32, _: *mut i32) { } -// CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) { } -// CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo93(_: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } -// CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo96(_: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } -// CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo99(_: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } -// CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo102(_: &dyn FnOnce(i32) -> i32) { } -// CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { } -// CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo104(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} -// CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo105(_: &dyn Send) { } -// CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo106(_: &dyn Send, _: &dyn Send) { } -// CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) { } -// CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo108(_: Type1) { } -// CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo109(_: Type1, _: Type1) { } -// CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo110(_: Type1, _: Type1, _: Type1) { } -// CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo111(_: Type2) { } -// CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo112(_: Type2, _: Type2) { } -// CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo113(_: Type2, _: Type2, _: Type2) { } -// CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo114(_: Type3) { } -// CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo115(_: Type3, _: Type3) { } -// CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo116(_: Type3, _: Type3, _: Type3) { } -// CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo117(_: Type4) { } -// CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo118(_: Type4, _: Type4) { } -// CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo119(_: Type4, _: Type4, _: Type4) { } -// CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo120(_: Type5) { } -// CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo121(_: Type5, _: Type5) { } -// CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo122(_: Type5, _: Type5, _: Type5) { } -// CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo123(_: Type6) { } -// CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo124(_: Type6, _: Type6) { } -// CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo125(_: Type6, _: Type6, _: Type6) { } -// CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo126(_: Type7) { } -// CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo127(_: Type7, _: Type7) { } -// CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo128(_: Type7, _: Type7, _: Type7) { } -// CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo129(_: Type8) { } -// CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo130(_: Type8, _: Type8) { } -// CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo131(_: Type8, _: Type8, _: Type8) { } -// CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo132(_: Type9) { } -// CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo133(_: Type9, _: Type9) { } -// CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo134(_: Type9, _: Type9, _: Type9) { } -// CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo135(_: Type10) { } -// CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo136(_: Type10, _: Type10) { } -// CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo137(_: Type10, _: Type10, _: Type10) { } -// CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo138(_: Type11) { } -// CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo139(_: Type11, _: Type11) { } -// CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo140(_: Type11, _: Type11, _: Type11) { } -// CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo141(_: Type12) { } -// CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo142(_: Type12, _: Type12) { } -// CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo143(_: Type12, _: Type12, _: Type12) { } -// CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo144(_: Type13) { } -// CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo145(_: Type13, _: Type13) { } -// CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo146(_: Type13, _: Type13, _: Type13) { } -// CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo147(_: Type14<Bar>) { } -// CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo148(_: Type14<Bar>, _: Type14<Bar>) { } -// CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { } -// CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - -// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"} -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvvE"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvvvvE"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPvE"} -// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPvS_E"} -// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvPvS_S_E"} -// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPKvE"} -// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPKvS0_E"} -// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPKvS0_S0_E"} -// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvbE"} -// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvbbE"} -// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvbbbE"} -// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu2i8E"} -// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu2i8S_E"} -// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu2i8S_S_E"} -// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3i16E"} -// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3i16S_E"} -// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3i16S_S_E"} -// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3i32E"} -// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3i32S_E"} -// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3i32S_S_E"} -// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3i64E"} -// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3i64S_E"} -// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3i64S_S_E"} -// CHECK: ![[TYPE24]] = !{i64 0, !"_ZTSFvu4i128E"} -// CHECK: ![[TYPE25]] = !{i64 0, !"_ZTSFvu4i128S_E"} -// CHECK: ![[TYPE26]] = !{i64 0, !"_ZTSFvu4i128S_S_E"} -// CHECK: ![[TYPE27]] = !{i64 0, !"_ZTSFvu5isizeE"} -// CHECK: ![[TYPE28]] = !{i64 0, !"_ZTSFvu5isizeS_E"} -// CHECK: ![[TYPE29]] = !{i64 0, !"_ZTSFvu5isizeS_S_E"} -// CHECK: ![[TYPE30]] = !{i64 0, !"_ZTSFvu2u8E"} -// CHECK: ![[TYPE31]] = !{i64 0, !"_ZTSFvu2u8S_E"} -// CHECK: ![[TYPE32]] = !{i64 0, !"_ZTSFvu2u8S_S_E"} -// CHECK: ![[TYPE33]] = !{i64 0, !"_ZTSFvu3u16E"} -// CHECK: ![[TYPE34]] = !{i64 0, !"_ZTSFvu3u16S_E"} -// CHECK: ![[TYPE35]] = !{i64 0, !"_ZTSFvu3u16S_S_E"} -// CHECK: ![[TYPE36]] = !{i64 0, !"_ZTSFvu3u32E"} -// CHECK: ![[TYPE37]] = !{i64 0, !"_ZTSFvu3u32S_E"} -// CHECK: ![[TYPE38]] = !{i64 0, !"_ZTSFvu3u32S_S_E"} -// CHECK: ![[TYPE39]] = !{i64 0, !"_ZTSFvu3u64E"} -// CHECK: ![[TYPE40]] = !{i64 0, !"_ZTSFvu3u64S_E"} -// CHECK: ![[TYPE41]] = !{i64 0, !"_ZTSFvu3u64S_S_E"} -// CHECK: ![[TYPE42]] = !{i64 0, !"_ZTSFvu4u128E"} -// CHECK: ![[TYPE43]] = !{i64 0, !"_ZTSFvu4u128S_E"} -// CHECK: ![[TYPE44]] = !{i64 0, !"_ZTSFvu4u128S_S_E"} -// CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"} -// CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"} -// CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"} -// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"} -// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"} -// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"} -// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"} -// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"} -// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"} -// CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"} -// CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"} -// CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"} -// CHECK: ![[TYPE57]] = !{i64 0, !"_ZTSFvu3refIu3strEE"} -// CHECK: ![[TYPE58]] = !{i64 0, !"_ZTSFvu3refIu3strES0_E"} -// CHECK: ![[TYPE59]] = !{i64 0, !"_ZTSFvu3refIu3strES0_S0_E"} -// CHECK: ![[TYPE60]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_EE"} -// CHECK: ![[TYPE61]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_E"} -// CHECK: ![[TYPE62]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_S0_E"} -// CHECK: ![[TYPE63]] = !{i64 0, !"_ZTSFvA32u3i32E"} -// CHECK: ![[TYPE64]] = !{i64 0, !"_ZTSFvA32u3i32S0_E"} -// CHECK: ![[TYPE65]] = !{i64 0, !"_ZTSFvA32u3i32S0_S0_E"} -// CHECK: ![[TYPE66]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EEE"} -// CHECK: ![[TYPE67]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_E"} -// CHECK: ![[TYPE68]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_S1_E"} -// CHECK: ![[TYPE69]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EEE"} -// CHECK: ![[TYPE70]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EES1_E"} -// CHECK: ![[TYPE71]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32EES1_S1_E"} -// CHECK: ![[TYPE72]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EEE"} -// CHECK: ![[TYPE73]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EES1_E"} -// CHECK: ![[TYPE74]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi5Enum1Iu3i32EES1_S1_E"} -// CHECK: ![[TYPE75]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EEE"} -// CHECK: ![[TYPE76]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EES1_E"} -// CHECK: ![[TYPE77]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Union1Iu3i32EES1_S1_E"} -// CHECK: ![[TYPE78]] = !{i64 0, !"_ZTSFvP5type1E"} -// CHECK: ![[TYPE79]] = !{i64 0, !"_ZTSFvP5type1S0_E"} -// CHECK: ![[TYPE80]] = !{i64 0, !"_ZTSFvP5type1S0_S0_E"} -// CHECK: ![[TYPE81]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32EE"} -// CHECK: ![[TYPE82]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_E"} -// CHECK: ![[TYPE83]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_S0_E"} -// CHECK: ![[TYPE84]] = !{i64 0, !"_ZTSFvu3refIu3i32EE"} -// CHECK: ![[TYPE85]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_E"} -// CHECK: ![[TYPE86]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_S1_E"} -// CHECK: ![[TYPE87]] = !{i64 0, !"_ZTSFvPu3i32E"} -// CHECK: ![[TYPE88]] = !{i64 0, !"_ZTSFvPu3i32PKS_E"} -// CHECK: ![[TYPE89]] = !{i64 0, !"_ZTSFvPu3i32PKS_S2_E"} -// CHECK: ![[TYPE90]] = !{i64 0, !"_ZTSFvPKu3i32E"} -// CHECK: ![[TYPE91]] = !{i64 0, !"_ZTSFvPKu3i32PS_E"} -// CHECK: ![[TYPE92]] = !{i64 0, !"_ZTSFvPKu3i32PS_S2_E"} -// CHECK: ![[TYPE93]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"} -// CHECK: ![[TYPE94]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"} -// CHECK: ![[TYPE95]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"} -// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEEE"} -// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_E"} -// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_S3_E"} -// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEEE"} -// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_E"} -// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_S3_E"} -// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEEE"} -// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_E"} -// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_S3_E"} -// CHECK: ![[TYPE105]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"} -// CHECK: ![[TYPE106]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"} -// CHECK: ![[TYPE107]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"} -// CHECK: ![[TYPE108]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvEE"} -// CHECK: ![[TYPE109]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_E"} -// CHECK: ![[TYPE110]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_S1_E"} -// CHECK: ![[TYPE111]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}E"} -// CHECK: ![[TYPE112]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_E"} -// CHECK: ![[TYPE113]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_S_E"} -// CHECK: ![[TYPE114]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooE"} -// CHECK: ![[TYPE115]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_E"} -// CHECK: ![[TYPE116]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_S_E"} -// CHECK: ![[TYPE117]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooE"} -// CHECK: ![[TYPE118]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_E"} -// CHECK: ![[TYPE119]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_S_E"} -// CHECK: ![[TYPE120]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooE"} -// CHECK: ![[TYPE121]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_E"} -// CHECK: ![[TYPE122]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_S_E"} -// CHECK: ![[TYPE123]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32EE"} -// CHECK: ![[TYPE124]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_E"} -// CHECK: ![[TYPE125]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_S0_E"} -// CHECK: ![[TYPE126]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32EE"} -// CHECK: ![[TYPE127]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32ES4_E"} -// CHECK: ![[TYPE128]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait1Iu5paramEu6regionEu3i32ES4_S4_E"} -// CHECK: ![[TYPE129]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_EE"} -// CHECK: ![[TYPE130]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_E"} -// CHECK: ![[TYPE131]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu3i32S_ES0_S0_E"} -// CHECK: ![[TYPE132]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_EE"} -// CHECK: ![[TYPE133]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_ES1_E"} -// CHECK: ![[TYPE134]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi7Struct1Iu3i32ES_ES1_S1_E"} -// CHECK: ![[TYPE135]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EEE"} -// CHECK: ![[TYPE136]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EES2_E"} -// CHECK: ![[TYPE137]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn13QuxIu3i32Lu5usize32EES2_S2_E"} -// CHECK: ![[TYPE138]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_EE"} -// CHECK: ![[TYPE139]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_E"} -// CHECK: ![[TYPE140]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_S0_E"} -// CHECK: ![[TYPE141]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooE"} -// CHECK: ![[TYPE142]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_E"} -// CHECK: ![[TYPE143]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3FooS_S_E"} -// CHECK: ![[TYPE144]] = !{i64 0, !"_ZTSFvu3refIvEE"} -// CHECK: ![[TYPE145]] = !{i64 0, !"_ZTSFvu3refIvES_E"} -// CHECK: ![[TYPE146]] = !{i64 0, !"_ZTSFvu3refIvES_S_E"} -// CHECK: ![[TYPE147]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarE"} -// CHECK: ![[TYPE148]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarS_E"} -// CHECK: ![[TYPE149]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_51sanitizer_cfi_emit_type_metadata_id_itanium_cxx_abi3BarS_S_E"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs deleted file mode 100644 index 78ef0c2c7..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Verifies that generalized type metadata for functions are emitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers - -#![crate_type="lib"] - -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.generalized") - f(arg) -} - -pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { - // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.generalized") - f(arg1, arg2) -} - -pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { - // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.generalized") - f(arg1, arg2, arg3) -} - -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.generalized"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.generalized"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.generalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs deleted file mode 100644 index 3b72459c4..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Verifies that normalized and generalized type metadata for functions are emitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers - -#![crate_type="lib"] - -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}![[TYPE1:[0-9]+]] - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized.generalized") - f(arg) -} - -pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { - // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}![[TYPE2:[0-9]+]] - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized.generalized") - f(arg1, arg2) -} - -pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { - // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}![[TYPE3:[0-9]+]] - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized.generalized") - f(arg1, arg2, arg3) -} - -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.normalized.generalized"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.normalized.generalized"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.normalized.generalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs deleted file mode 100644 index 9218e9947..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Verifies that normalized type metadata for functions are emitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers - -#![crate_type="lib"] - -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized") - f(arg) -} - -pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { - // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized") - f(arg1, arg2) -} - -pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { - // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized") - f(arg1, arg2, arg3) -} - -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E.normalized"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E.normalized"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E.normalized"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs deleted file mode 100644 index f9fd816de..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-itanium-cxx-abi.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Verifies that type metadata for functions are emitted. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi - -#![crate_type="lib"] - -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: define{{.*}}foo - // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_E") - f(arg) -} - -pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { - // CHECK-LABEL: define{{.*}}bar - // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E") - f(arg1, arg2) -} - -pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { - // CHECK-LABEL: define{{.*}}baz - // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E") - f(arg1, arg2, arg3) -} - -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E"} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs deleted file mode 100644 index 0f79adab7..000000000 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Verifies that type metadata identifiers for trait objects are emitted correctly. -// -// needs-sanitizer-cfi -// compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi - -#![crate_type="lib"] - -pub trait Trait1 { - fn foo(&self); -} - -#[derive(Clone, Copy)] -pub struct Type1; - -impl Trait1 for Type1 { - fn foo(&self) { - } -} - -pub trait Trait2<T> { - fn bar(&self); -} - -pub struct Type2; - -impl Trait2<i32> for Type2 { - fn bar(&self) { - } -} - -pub trait Trait3<T> { - fn baz(&self, _: &T); -} - -pub struct Type3; - -impl<T, U> Trait3<U> for T { - fn baz(&self, _: &U) { - } -} - -pub trait Trait4<'a, T> { - type Output: 'a; - fn qux(&self, _: &T) -> Self::Output; -} - -pub struct Type4; - -impl<'a, T, U> Trait4<'a, U> for T { - type Output = &'a i32; - fn qux(&self, _: &U) -> Self::Output { - &0 - } -} - -pub fn foo1(a: &dyn Trait1) { - a.foo(); - // CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]") -} - -pub fn bar1() { - let a = Type1; - let b = &a as &dyn Trait1; - b.foo(); - // CHECK-LABEL: define{{.*}}4bar1{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") -} - -pub fn foo2<T>(a: &dyn Trait2<T>) { - a.bar(); - // CHECK-LABEL: define{{.*}}4foo2{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") -} - -pub fn bar2() { - let a = Type2; - foo2(&a); - let b = &a as &dyn Trait2<i32>; - b.bar(); - // CHECK-LABEL: define{{.*}}4bar2{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") -} - -pub fn foo3(a: &dyn Trait3<Type3>) { - let b = Type3; - a.baz(&b); - // CHECK-LABEL: define{{.*}}4foo3{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]") -} - -pub fn bar3() { - let a = Type3; - foo3(&a); - let b = &a as &dyn Trait3<Type3>; - b.baz(&a); - // CHECK-LABEL: define{{.*}}4bar3{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]") -} - -pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) { - let b = Type4; - a.qux(&b); - // CHECK-LABEL: define{{.*}}4foo4{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]") -} - -pub fn bar4<'a>() { - let a = Type4; - foo4(&a); - let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>; - b.qux(&a); - // CHECK-LABEL: define{{.*}}4bar4{{.*}}!type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]") -} - -// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"} -// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE2]]"} -// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE3]]"} -// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE4]]"} diff --git a/tests/codegen/sanitizer-kasan-emits-instrumentation.rs b/tests/codegen/sanitizer-kasan-emits-instrumentation.rs deleted file mode 100644 index d6e3f2719..000000000 --- a/tests/codegen/sanitizer-kasan-emits-instrumentation.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Verifies that `-Zsanitizer=kernel-address` emits sanitizer instrumentation. - -// compile-flags: -Zsanitizer=kernel-address -// revisions: aarch64 riscv64imac riscv64gc x86_64 -//[aarch64] compile-flags: --target aarch64-unknown-none -//[aarch64] needs-llvm-components: aarch64 -//[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf -//[riscv64imac] needs-llvm-components: riscv -//[riscv64imac] min-llvm-version: 16 -//[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf -//[riscv64gc] needs-llvm-components: riscv -//[riscv64gc] min-llvm-version: 16 -//[x86_64] compile-flags: --target x86_64-unknown-none -//[x86_64] needs-llvm-components: x86 - -#![crate_type = "rlib"] -#![feature(no_core, no_sanitize, lang_items)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} - -impl Copy for u8 {} - -// CHECK-LABEL: ; sanitizer_kasan_emits_instrumentation::unsanitized -// CHECK-NEXT: ; Function Attrs: -// CHECK-NOT: sanitize_address -// CHECK: start: -// CHECK-NOT: call void @__asan_report_load -// CHECK: } -#[no_sanitize(address)] -pub fn unsanitized(b: &mut u8) -> u8 { - *b -} - -// CHECK-LABEL: ; sanitizer_kasan_emits_instrumentation::sanitized -// CHECK-NEXT: ; Function Attrs: -// CHECK: sanitize_address -// CHECK: start: -// CHECK: call void @__asan_report_load -// CHECK: } -pub fn sanitized(b: &mut u8) -> u8 { - *b -} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs deleted file mode 100644 index bb317e4a2..000000000 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Verifies that KCFI operand bundles are omitted. -// -// revisions: aarch64 x86_64 -// [aarch64] compile-flags: --target aarch64-unknown-none -// [aarch64] needs-llvm-components: aarch64 -// [x86_64] compile-flags: --target x86_64-unknown-none -// [x86_64] needs-llvm-components: -// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 - -#![crate_type="lib"] -#![feature(no_core, no_sanitize, lang_items)] -#![no_core] - -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } - -impl Copy for i32 {} - -#[no_sanitize(kcfi)] -pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { - // CHECK-LABEL: sanitizer_kcfi_emit_kcfi_operand_bundle_attr_no_sanitize::foo - // CHECK: Function Attrs: {{.*}} - // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: start: - // CHECK-NOT: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 {{[-0-9]+}}) ] - // CHECK: ret i32 {{%.+}} - f(arg) -} diff --git a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs deleted file mode 100644 index 004a67e7d..000000000 --- a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs +++ /dev/null @@ -1,144 +0,0 @@ -// Verifies that type metadata identifiers for trait objects are emitted correctly. -// -// revisions: aarch64 x86_64 -// [aarch64] compile-flags: --target aarch64-unknown-none -// [aarch64] needs-llvm-components: aarch64 -// [x86_64] compile-flags: --target x86_64-unknown-none -// [x86_64] needs-llvm-components: -// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 - -#![crate_type="lib"] -#![feature(arbitrary_self_types, no_core, lang_items)] -#![no_core] - -#[lang="sized"] -trait Sized { } -#[lang="copy"] -trait Copy { } -#[lang="receiver"] -trait Receiver { } -#[lang="dispatch_from_dyn"] -trait DispatchFromDyn<T> { } -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} -#[lang = "unsize"] -trait Unsize<T: ?Sized> { } -#[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> { } -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -#[lang="freeze"] -trait Freeze { } -#[lang="drop_in_place"] -fn drop_in_place_fn<T>() { } - -pub trait Trait1 { - fn foo(&self); -} - -pub struct Type1; - -impl Trait1 for Type1 { - fn foo(&self) { - } -} - -pub trait Trait2<T> { - fn bar(&self); -} - -pub struct Type2; - -impl Trait2<i32> for Type2 { - fn bar(&self) { - } -} - -pub trait Trait3<T> { - fn baz(&self, _: &T); -} - -pub struct Type3; - -impl<T, U> Trait3<U> for T { - fn baz(&self, _: &U) { - } -} - -pub trait Trait4<'a, T> { - type Output: 'a; - fn qux(&self, _: &T) -> Self::Output; -} - -pub struct Type4; - -impl<'a, T, U> Trait4<'a, U> for T { - type Output = &'a i32; - fn qux(&self, _: &U) -> Self::Output { - &0 - } -} - -pub fn foo1(a: &dyn Trait1) { - a.foo(); - // CHECK-LABEL: define{{.*}}4foo1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] -} - -pub fn bar1() { - let a = Type1; - let b = &a as &dyn Trait1; - b.foo(); - // CHECK-LABEL: define{{.*}}4bar1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] -} - -pub fn foo2<T>(a: &dyn Trait2<T>) { - a.bar(); - // CHECK-LABEL: define{{.*}}4foo2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ] -} - -pub fn bar2() { - let a = Type2; - foo2(&a); - let b = &a as &dyn Trait2<i32>; - b.bar(); - // CHECK-LABEL: define{{.*}}4bar2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ] -} - -pub fn foo3(a: &dyn Trait3<Type3>) { - let b = Type3; - a.baz(&b); - // CHECK-LABEL: define{{.*}}4foo3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ] -} - -pub fn bar3() { - let a = Type3; - foo3(&a); - let b = &a as &dyn Trait3<Type3>; - b.baz(&a); - // CHECK-LABEL: define{{.*}}4bar3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call void %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type3\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ] -} - -pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) { - let b = Type4; - a.qux(&b); - // CHECK-LABEL: define{{.*}}4foo4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ] -} - -pub fn bar4<'a>() { - let a = Type4; - foo4(&a); - let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>; - b.qux(&a); - // CHECK-LABEL: define{{.*}}4bar4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} - // CHECK: call align 4 {{ptr|i32\*}} %{{[0-9]}}({{\{\}\*|ptr}} align 1 {{%[a-z]\.0|%_[0-9]}}, {{\{\}\*|ptr|%Type4\*}} align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ] -} - -// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]} -// CHECK: !{{[0-9]+}} = !{i32 [[TYPE2]]} -// CHECK: !{{[0-9]+}} = !{i32 [[TYPE3]]} -// CHECK: !{{[0-9]+}} = !{i32 [[TYPE4]]} diff --git a/tests/codegen/sanitizer-no-sanitize.rs b/tests/codegen/sanitizer-no-sanitize.rs deleted file mode 100644 index fb9d249da..000000000 --- a/tests/codegen/sanitizer-no-sanitize.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Verifies that no_sanitize attribute can be used to -// selectively disable sanitizer instrumentation. -// -// needs-sanitizer-address -// compile-flags: -Zsanitizer=address - -#![crate_type="lib"] -#![feature(no_sanitize)] - -// CHECK-LABEL: ; sanitizer_no_sanitize::unsanitized -// CHECK-NEXT: ; Function Attrs: -// CHECK-NOT: sanitize_address -// CHECK: start: -// CHECK-NOT: call void @__asan_report_load -// CHECK: } -#[no_sanitize(address)] -pub fn unsanitized(b: &mut u8) -> u8 { - *b -} - -// CHECK-LABEL: ; sanitizer_no_sanitize::sanitized -// CHECK-NEXT: ; Function Attrs: -// CHECK: sanitize_address -// CHECK: start: -// CHECK: call void @__asan_report_load -// CHECK: } -pub fn sanitized(b: &mut u8) -> u8 { - *b -} diff --git a/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs b/tests/codegen/sanitizer/cfi-add-canonical-jump-tables-flag.rs index 1ee8bdfc3..1ee8bdfc3 100644 --- a/tests/codegen/sanitizer-cfi-add-canonical-jump-tables-flag.rs +++ b/tests/codegen/sanitizer/cfi-add-canonical-jump-tables-flag.rs diff --git a/tests/codegen/sanitizer-cfi-add-enable-split-lto-unit-flag.rs b/tests/codegen/sanitizer/cfi-add-enable-split-lto-unit-flag.rs index 68c91384b..68c91384b 100644 --- a/tests/codegen/sanitizer-cfi-add-enable-split-lto-unit-flag.rs +++ b/tests/codegen/sanitizer/cfi-add-enable-split-lto-unit-flag.rs diff --git a/tests/codegen/sanitizer/cfi-emit-type-checks-attr-no-sanitize.rs b/tests/codegen/sanitizer/cfi-emit-type-checks-attr-no-sanitize.rs new file mode 100644 index 000000000..a3cd16e3d --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-checks-attr-no-sanitize.rs @@ -0,0 +1,18 @@ +// Verifies that pointer type membership tests for indirect calls are omitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(no_sanitize)] + +#[no_sanitize(cfi)] +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: cfi_emit_type_checks_attr_no_sanitize::foo + // CHECK: Function Attrs: {{.*}} + // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: start: + // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) + // CHECK-NEXT: ret i32 {{%.+}} + f(arg) +} diff --git a/tests/codegen/sanitizer/cfi-emit-type-checks.rs b/tests/codegen/sanitizer/cfi-emit-type-checks.rs new file mode 100644 index 000000000..f0fe5de9f --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-checks.rs @@ -0,0 +1,19 @@ +// Verifies that pointer type membership tests for indirect calls are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: start: + // CHECK: [[TT:%.+]] = call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"{{[[:print:]]+}}") + // CHECK-NEXT: br i1 [[TT]], label %type_test.pass, label %type_test.fail + // CHECK: type_test.pass: + // CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg) + // CHECK: type_test.fail: + // CHECK-NEXT: call void @llvm.trap() + // CHECK-NEXT: unreachable + f(arg) +} diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs index 084d8bf80..084d8bf80 100644 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-attr-cfi-encoding.rs +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-attr-cfi-encoding.rs diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs new file mode 100644 index 000000000..da608e180 --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -0,0 +1,604 @@ +// Verifies that type metadata identifiers for functions are emitted correctly. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] +#![allow(dead_code)] +#![allow(incomplete_features)] +#![allow(unused_must_use)] +#![feature(adt_const_params, extern_types, inline_const, type_alias_impl_trait)] + +extern crate core; +use core::ffi::*; +use std::marker::PhantomData; + +// User-defined type (structure) +pub struct Struct1<T> { + member1: T, +} + +// User-defined type (enum) +pub enum Enum1<T> { + Variant1(T), +} + +// User-defined type (union) +pub union Union1<T> { + member1: std::mem::ManuallyDrop<T>, +} + +// Extern type +extern { + pub type type1; +} + +// Trait +pub trait Trait1<T> { + fn foo(&self) { } +} + +// Trait implementation +impl<T> Trait1<T> for i32 { + fn foo(&self) { } +} + +// Trait implementation +impl<T, U> Trait1<T> for Struct1<U> { + fn foo(&self) { } +} + +// impl Trait type aliases for helping with defining other types (see below) +pub type Type1 = impl Send; +pub type Type2 = impl Send; +pub type Type3 = impl Send; +pub type Type4 = impl Send; +pub type Type5 = impl Send; +pub type Type6 = impl Send; +pub type Type7 = impl Send; +pub type Type8 = impl Send; +pub type Type9 = impl Send; +pub type Type10 = impl Send; +pub type Type11 = impl Send; + +pub fn fn1<'a>() where + Type1: 'static, + Type2: 'static, + Type3: 'static, + Type4: 'static, + Type5: 'static, + Type6: 'static, + Type7: 'static, + Type8: 'static, + Type9: 'static, + Type10: 'static, + Type11: 'static, +{ + // Closure + let closure1 = || { }; + let _: Type1 = closure1; + + // Constructor + pub struct Foo(i32); + let _: Type2 = Foo; + + // Type in extern path + extern { + fn foo(); + } + let _: Type3 = foo; + + // Type in closure path + || { + pub struct Foo; + let _: Type4 = Foo; + }; + + // Type in const path + const { + pub struct Foo; + fn foo() -> Type5 { Foo } + }; + + // Type in impl path + impl<T> Struct1<T> { + fn foo(&self) { } + } + let _: Type6 = <Struct1<i32>>::foo; + + // Trait method + let _: Type7 = <dyn Trait1<i32>>::foo; + + // Trait method + let _: Type8 = <i32 as Trait1<i32>>::foo; + + // Trait method + let _: Type9 = <Struct1<i32> as Trait1<i32>>::foo; + + // Const generics + pub struct Qux<T, const N: usize>([T; N]); + let _: Type10 = Qux([0; 32]); + + // Lifetimes/regions + pub struct Quux<'a>(&'a i32); + pub struct Quuux<'a, 'b>(&'a i32, &'b Quux<'b>); + let _: Type11 = Quuux; +} + +// Helper type to make Type12 have an unique id +struct Foo(i32); + +// repr(transparent) user-defined type +#[repr(transparent)] +pub struct Type12 { + member1: (), + member2: PhantomData<i32>, + member3: Foo, +} + +// Self-referencing repr(transparent) user-defined type +#[repr(transparent)] +pub struct Type13<'a> { + member1: (), + member2: PhantomData<i32>, + member3: &'a Type13<'a>, +} + +// Helper type to make Type14 have an unique id +pub struct Bar; + +// repr(transparent) user-defined generic type +#[repr(transparent)] +pub struct Type14<T>(T); + +pub fn foo0(_: ()) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo1(_: (), _: c_void) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo2(_: (), _: c_void, _: c_void) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo3(_: *mut ()) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo4(_: *mut (), _: *mut c_void) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) { } +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo6(_: *const ()) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo7(_: *const (), _: *const c_void) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) { } +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo9(_: bool) { } +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo10(_: bool, _: bool) { } +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo11(_: bool, _: bool, _: bool) { } +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo12(_: i8) { } +// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo13(_: i8, _: i8) { } +// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo14(_: i8, _: i8, _: i8) { } +// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo15(_: i16) { } +// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo16(_: i16, _: i16) { } +// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo17(_: i16, _: i16, _: i16) { } +// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo18(_: i32) { } +// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo19(_: i32, _: i32) { } +// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo20(_: i32, _: i32, _: i32) { } +// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo21(_: i64) { } +// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo22(_: i64, _: i64) { } +// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo23(_: i64, _: i64, _: i64) { } +// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo24(_: i128) { } +// CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo25(_: i128, _: i128) { } +// CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo26(_: i128, _: i128, _: i128) { } +// CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo27(_: isize) { } +// CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo28(_: isize, _: isize) { } +// CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo29(_: isize, _: isize, _: isize) { } +// CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo30(_: u8) { } +// CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo31(_: u8, _: u8) { } +// CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo32(_: u8, _: u8, _: u8) { } +// CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo33(_: u16) { } +// CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo34(_: u16, _: u16) { } +// CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo35(_: u16, _: u16, _: u16) { } +// CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo36(_: u32) { } +// CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo37(_: u32, _: u32) { } +// CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo38(_: u32, _: u32, _: u32) { } +// CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo39(_: u64) { } +// CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo40(_: u64, _: u64) { } +// CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo41(_: u64, _: u64, _: u64) { } +// CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo42(_: u128) { } +// CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo43(_: u128, _: u128) { } +// CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo44(_: u128, _: u128, _: u128) { } +// CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo45(_: usize) { } +// CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo46(_: usize, _: usize) { } +// CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo47(_: usize, _: usize, _: usize) { } +// CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo48(_: f32) { } +// CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo49(_: f32, _: f32) { } +// CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo50(_: f32, _: f32, _: f32) { } +// CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo51(_: f64) { } +// CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo52(_: f64, _: f64) { } +// CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo53(_: f64, _: f64, _: f64) { } +// CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo54(_: char) { } +// CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo55(_: char, _: char) { } +// CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo56(_: char, _: char, _: char) { } +// CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo57(_: &str) { } +// CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo58(_: &str, _: &str) { } +// CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo59(_: &str, _: &str, _: &str) { } +// CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo60(_: (i32, i32)) { } +// CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo61(_: (i32, i32), _: (i32, i32)) { } +// CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { } +// CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo63(_: [i32; 32]) { } +// CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo64(_: [i32; 32], _: [i32; 32]) { } +// CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { } +// CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo66(_: &[i32]) { } +// CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo67(_: &[i32], _: &[i32]) { } +// CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) { } +// CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo69(_: &Struct1::<i32>) { } +// CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo70(_: &Struct1::<i32>, _: &Struct1::<i32>) { } +// CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo71(_: &Struct1::<i32>, _: &Struct1::<i32>, _: &Struct1::<i32>) { } +// CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo72(_: &Enum1::<i32>) { } +// CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo73(_: &Enum1::<i32>, _: &Enum1::<i32>) { } +// CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo74(_: &Enum1::<i32>, _: &Enum1::<i32>, _: &Enum1::<i32>) { } +// CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo75(_: &Union1::<i32>) { } +// CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo76(_: &Union1::<i32>, _: &Union1::<i32>) { } +// CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo77(_: &Union1::<i32>, _: &Union1::<i32>, _: &Union1::<i32>) { } +// CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo78(_: *mut type1) { } +// CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo79(_: *mut type1, _: *mut type1) { } +// CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) { } +// CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo81(_: &mut i32) { } +// CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo82(_: &mut i32, _: &i32) { } +// CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo83(_: &mut i32, _: &i32, _: &i32) { } +// CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo84(_: &i32) { } +// CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo85(_: &i32, _: &mut i32) { } +// CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) { } +// CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo87(_: *mut i32) { } +// CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo88(_: *mut i32, _: *const i32) { } +// CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) { } +// CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo90(_: *const i32) { } +// CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo91(_: *const i32, _: *mut i32) { } +// CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) { } +// CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo93(_: fn(i32) -> i32) { } +// CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) { } +// CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } +// CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo96(_: &dyn Fn(i32) -> i32) { } +// CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +// CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +// CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo99(_: &dyn FnMut(i32) -> i32) { } +// CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +// CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +// CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo102(_: &dyn FnOnce(i32) -> i32) { } +// CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { } +// CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo104(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} +// CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo105(_: &dyn Send) { } +// CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo106(_: &dyn Send, _: &dyn Send) { } +// CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) { } +// CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo108(_: Type1) { } +// CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo109(_: Type1, _: Type1) { } +// CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo110(_: Type1, _: Type1, _: Type1) { } +// CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo111(_: Type2) { } +// CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo112(_: Type2, _: Type2) { } +// CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo113(_: Type2, _: Type2, _: Type2) { } +// CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo114(_: Type3) { } +// CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo115(_: Type3, _: Type3) { } +// CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo116(_: Type3, _: Type3, _: Type3) { } +// CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo117(_: Type4) { } +// CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo118(_: Type4, _: Type4) { } +// CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo119(_: Type4, _: Type4, _: Type4) { } +// CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo120(_: Type5) { } +// CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo121(_: Type5, _: Type5) { } +// CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo122(_: Type5, _: Type5, _: Type5) { } +// CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo123(_: Type6) { } +// CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo124(_: Type6, _: Type6) { } +// CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo125(_: Type6, _: Type6, _: Type6) { } +// CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo126(_: Type7) { } +// CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo127(_: Type7, _: Type7) { } +// CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo128(_: Type7, _: Type7, _: Type7) { } +// CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo129(_: Type8) { } +// CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo130(_: Type8, _: Type8) { } +// CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo131(_: Type8, _: Type8, _: Type8) { } +// CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo132(_: Type9) { } +// CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo133(_: Type9, _: Type9) { } +// CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo134(_: Type9, _: Type9, _: Type9) { } +// CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo135(_: Type10) { } +// CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo136(_: Type10, _: Type10) { } +// CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo137(_: Type10, _: Type10, _: Type10) { } +// CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo138(_: Type11) { } +// CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo139(_: Type11, _: Type11) { } +// CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo140(_: Type11, _: Type11, _: Type11) { } +// CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo141(_: Type12) { } +// CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo142(_: Type12, _: Type12) { } +// CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo143(_: Type12, _: Type12, _: Type12) { } +// CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo144(_: Type13) { } +// CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo145(_: Type13, _: Type13) { } +// CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo146(_: Type13, _: Type13, _: Type13) { } +// CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo147(_: Type14<Bar>) { } +// CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo148(_: Type14<Bar>, _: Type14<Bar>) { } +// CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { } +// CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + +// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvvvE"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvvvvE"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPvE"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPvS_E"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvPvS_S_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPKvE"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPKvS0_E"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPKvS0_S0_E"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvbE"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvbbE"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvbbbE"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu2i8E"} +// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu2i8S_E"} +// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu2i8S_S_E"} +// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3i16E"} +// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3i16S_E"} +// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3i16S_S_E"} +// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3i32E"} +// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3i32S_E"} +// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3i32S_S_E"} +// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3i64E"} +// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3i64S_E"} +// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3i64S_S_E"} +// CHECK: ![[TYPE24]] = !{i64 0, !"_ZTSFvu4i128E"} +// CHECK: ![[TYPE25]] = !{i64 0, !"_ZTSFvu4i128S_E"} +// CHECK: ![[TYPE26]] = !{i64 0, !"_ZTSFvu4i128S_S_E"} +// CHECK: ![[TYPE27]] = !{i64 0, !"_ZTSFvu5isizeE"} +// CHECK: ![[TYPE28]] = !{i64 0, !"_ZTSFvu5isizeS_E"} +// CHECK: ![[TYPE29]] = !{i64 0, !"_ZTSFvu5isizeS_S_E"} +// CHECK: ![[TYPE30]] = !{i64 0, !"_ZTSFvu2u8E"} +// CHECK: ![[TYPE31]] = !{i64 0, !"_ZTSFvu2u8S_E"} +// CHECK: ![[TYPE32]] = !{i64 0, !"_ZTSFvu2u8S_S_E"} +// CHECK: ![[TYPE33]] = !{i64 0, !"_ZTSFvu3u16E"} +// CHECK: ![[TYPE34]] = !{i64 0, !"_ZTSFvu3u16S_E"} +// CHECK: ![[TYPE35]] = !{i64 0, !"_ZTSFvu3u16S_S_E"} +// CHECK: ![[TYPE36]] = !{i64 0, !"_ZTSFvu3u32E"} +// CHECK: ![[TYPE37]] = !{i64 0, !"_ZTSFvu3u32S_E"} +// CHECK: ![[TYPE38]] = !{i64 0, !"_ZTSFvu3u32S_S_E"} +// CHECK: ![[TYPE39]] = !{i64 0, !"_ZTSFvu3u64E"} +// CHECK: ![[TYPE40]] = !{i64 0, !"_ZTSFvu3u64S_E"} +// CHECK: ![[TYPE41]] = !{i64 0, !"_ZTSFvu3u64S_S_E"} +// CHECK: ![[TYPE42]] = !{i64 0, !"_ZTSFvu4u128E"} +// CHECK: ![[TYPE43]] = !{i64 0, !"_ZTSFvu4u128S_E"} +// CHECK: ![[TYPE44]] = !{i64 0, !"_ZTSFvu4u128S_S_E"} +// CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"} +// CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"} +// CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"} +// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"} +// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"} +// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"} +// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"} +// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"} +// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"} +// CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"} +// CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"} +// CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"} +// CHECK: ![[TYPE57]] = !{i64 0, !"_ZTSFvu3refIu3strEE"} +// CHECK: ![[TYPE58]] = !{i64 0, !"_ZTSFvu3refIu3strES0_E"} +// CHECK: ![[TYPE59]] = !{i64 0, !"_ZTSFvu3refIu3strES0_S0_E"} +// CHECK: ![[TYPE60]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_EE"} +// CHECK: ![[TYPE61]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_E"} +// CHECK: ![[TYPE62]] = !{i64 0, !"_ZTSFvu5tupleIu3i32S_ES0_S0_E"} +// CHECK: ![[TYPE63]] = !{i64 0, !"_ZTSFvA32u3i32E"} +// CHECK: ![[TYPE64]] = !{i64 0, !"_ZTSFvA32u3i32S0_E"} +// CHECK: ![[TYPE65]] = !{i64 0, !"_ZTSFvA32u3i32S0_S0_E"} +// CHECK: ![[TYPE66]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EEE"} +// CHECK: ![[TYPE67]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_E"} +// CHECK: ![[TYPE68]] = !{i64 0, !"_ZTSFvu3refIu5sliceIu3i32EES1_S1_E"} +// CHECK: ![[TYPE69]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME:[0-9]{1,2}[a-z_]{1,99}]]7Struct1Iu3i32EEE"} +// CHECK: ![[TYPE70]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]7Struct1Iu3i32EES1_E"} +// CHECK: ![[TYPE71]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]7Struct1Iu3i32EES1_S1_E"} +// CHECK: ![[TYPE72]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]5Enum1Iu3i32EEE"} +// CHECK: ![[TYPE73]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]5Enum1Iu3i32EES1_E"} +// CHECK: ![[TYPE74]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]5Enum1Iu3i32EES1_S1_E"} +// CHECK: ![[TYPE75]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Union1Iu3i32EEE"} +// CHECK: ![[TYPE76]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Union1Iu3i32EES1_E"} +// CHECK: ![[TYPE77]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Union1Iu3i32EES1_S1_E"} +// CHECK: ![[TYPE78]] = !{i64 0, !"_ZTSFvP5type1E"} +// CHECK: ![[TYPE79]] = !{i64 0, !"_ZTSFvP5type1S0_E"} +// CHECK: ![[TYPE80]] = !{i64 0, !"_ZTSFvP5type1S0_S0_E"} +// CHECK: ![[TYPE81]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32EE"} +// CHECK: ![[TYPE82]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_E"} +// CHECK: ![[TYPE83]] = !{i64 0, !"_ZTSFvU3mutu3refIu3i32ES0_S0_E"} +// CHECK: ![[TYPE84]] = !{i64 0, !"_ZTSFvu3refIu3i32EE"} +// CHECK: ![[TYPE85]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_E"} +// CHECK: ![[TYPE86]] = !{i64 0, !"_ZTSFvu3refIu3i32EU3mutS0_S1_E"} +// CHECK: ![[TYPE87]] = !{i64 0, !"_ZTSFvPu3i32E"} +// CHECK: ![[TYPE88]] = !{i64 0, !"_ZTSFvPu3i32PKS_E"} +// CHECK: ![[TYPE89]] = !{i64 0, !"_ZTSFvPu3i32PKS_S2_E"} +// CHECK: ![[TYPE90]] = !{i64 0, !"_ZTSFvPKu3i32E"} +// CHECK: ![[TYPE91]] = !{i64 0, !"_ZTSFvPKu3i32PS_E"} +// CHECK: ![[TYPE92]] = !{i64 0, !"_ZTSFvPKu3i32PS_S2_E"} +// CHECK: ![[TYPE93]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"} +// CHECK: ![[TYPE94]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"} +// CHECK: ![[TYPE95]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"} +// CHECK: ![[TYPE96]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEEE"} +// CHECK: ![[TYPE97]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_E"} +// CHECK: ![[TYPE98]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_S3_E"} +// CHECK: ![[TYPE99]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEEE"} +// CHECK: ![[TYPE100]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_E"} +// CHECK: ![[TYPE101]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_S3_E"} +// CHECK: ![[TYPE102]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEEE"} +// CHECK: ![[TYPE103]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_E"} +// CHECK: ![[TYPE104]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_S3_E"} +// CHECK: ![[TYPE105]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"} +// CHECK: ![[TYPE106]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"} +// CHECK: ![[TYPE107]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"} +// CHECK: ![[TYPE108]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvEE"} +// CHECK: ![[TYPE109]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_E"} +// CHECK: ![[TYPE110]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn111{{[{}][{}]}}closure{{[}][}]}}Iu2i8PFvvEvES1_S1_E"} +// CHECK: ![[TYPE111]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}E"} +// CHECK: ![[TYPE112]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_E"} +// CHECK: ![[TYPE113]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13Foo15{{[{}][{}]}}constructor{{[}][}]}}S_S_E"} +// CHECK: ![[TYPE114]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn110{{[{}][{}]}}extern{{[}][}]}}3fooE"} +// CHECK: ![[TYPE115]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_E"} +// CHECK: ![[TYPE116]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn110{{[{}][{}]}}extern{{[}][}]}}3fooS_S_E"} +// CHECK: ![[TYPE117]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooE"} +// CHECK: ![[TYPE118]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_E"} +// CHECK: ![[TYPE119]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn1s0_11{{[{}][{}]}}closure{{[}][}]}}3FooS_S_E"} +// CHECK: ![[TYPE120]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn112{{[{}][{}]}}constant{{[}][}]}}3FooE"} +// CHECK: ![[TYPE121]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_E"} +// CHECK: ![[TYPE122]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn112{{[{}][{}]}}constant{{[}][}]}}3FooS_S_E"} +// CHECK: ![[TYPE123]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32EE"} +// CHECK: ![[TYPE124]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_E"} +// CHECK: ![[TYPE125]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn18{{[{}][{}]}}impl{{[}][}]}}3fooIu3i32ES0_S0_E"} +// CHECK: ![[TYPE126]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait1Iu5paramEu6regionEu3i32EE"} +// CHECK: ![[TYPE127]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait1Iu5paramEu6regionEu3i32ES4_E"} +// CHECK: ![[TYPE128]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait1Iu5paramEu6regionEu3i32ES4_S4_E"} +// CHECK: ![[TYPE129]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3i32S_EE"} +// CHECK: ![[TYPE130]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3i32S_ES0_E"} +// CHECK: ![[TYPE131]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu3i32S_ES0_S0_E"} +// CHECK: ![[TYPE132]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]7Struct1Iu3i32ES_EE"} +// CHECK: ![[TYPE133]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]7Struct1Iu3i32ES_ES1_E"} +// CHECK: ![[TYPE134]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NvNtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]6Trait13fooIu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]7Struct1Iu3i32ES_ES1_S1_E"} +// CHECK: ![[TYPE135]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13QuxIu3i32Lu5usize32EEE"} +// CHECK: ![[TYPE136]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13QuxIu3i32Lu5usize32EES2_E"} +// CHECK: ![[TYPE137]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn13QuxIu3i32Lu5usize32EES2_S2_E"} +// CHECK: ![[TYPE138]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_EE"} +// CHECK: ![[TYPE139]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_E"} +// CHECK: ![[TYPE140]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NcNtNvC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3fn15Quuux15{{[{}][{}]}}constructor{{[}][}]}}Iu6regionS_ES0_S0_E"} +// CHECK: ![[TYPE141]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3FooE"} +// CHECK: ![[TYPE142]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3FooS_E"} +// CHECK: ![[TYPE143]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3FooS_S_E"} +// CHECK: ![[TYPE144]] = !{i64 0, !"_ZTSFvu3refIvEE"} +// CHECK: ![[TYPE145]] = !{i64 0, !"_ZTSFvu3refIvES_E"} +// CHECK: ![[TYPE146]] = !{i64 0, !"_ZTSFvu3refIvES_S_E"} +// CHECK: ![[TYPE147]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3BarE"} +// CHECK: ![[TYPE148]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3BarS_E"} +// CHECK: ![[TYPE149]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_[[ITANIUMED_FILENAME]]3BarS_S_E"} diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs new file mode 100644 index 000000000..d200ed979 --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-generalized.rs @@ -0,0 +1,31 @@ +// Verifies that generalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.generalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.generalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.generalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.generalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.generalized"} diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs new file mode 100644 index 000000000..cdefec17a --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs @@ -0,0 +1,31 @@ +// Verifies that normalized and generalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}![[TYPE1:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized.generalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized.generalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}![[TYPE3:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized.generalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PKvS_E.normalized.generalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PKvS_S_E.normalized.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PKvS_S_S_E.normalized.generalized"} diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs new file mode 100644 index 000000000..f360b33dd --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi-normalized.rs @@ -0,0 +1,31 @@ +// Verifies that normalized type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E.normalized") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E.normalized") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E.normalized") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E.normalized"} diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi.rs new file mode 100644 index 000000000..3cb817b21 --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-itanium-cxx-abi.rs @@ -0,0 +1,31 @@ +// Verifies that type metadata for functions are emitted. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] + +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_E") + f(arg) +} + +pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_E") + f(arg1, arg2) +} + +pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"_ZTSFu3i32S_S_S_E") + f(arg1, arg2, arg3) +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32PFS_S_ES_E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_ES_S_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i32PFS_S_S_S_ES_S_S_E"} diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-trait-objects.rs new file mode 100644 index 000000000..b69e57261 --- /dev/null +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-trait-objects.rs @@ -0,0 +1,149 @@ +// Verifies that type metadata identifiers for trait objects are emitted correctly. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] + +pub trait Trait1 { + fn foo(&self); +} + +#[derive(Clone, Copy)] +pub struct Type1; + +impl Trait1 for Type1 { + fn foo(&self) { + } +} + +pub trait Trait2<T> { + fn bar(&self); +} + +pub struct Type2; + +impl Trait2<i32> for Type2 { + fn bar(&self) { + } +} + +pub trait Trait3<T> { + fn baz(&self, _: &T); +} + +pub struct Type3; + +impl<T, U> Trait3<U> for T { + fn baz(&self, _: &U) { + } +} + +pub trait Trait4<'a, T> { + type Output: 'a; + fn qux(&self, _: &T) -> Self::Output; +} + +pub struct Type4; + +impl<'a, T, U> Trait4<'a, U> for T { + type Output = &'a i32; + fn qux(&self, _: &U) -> Self::Output { + &0 + } +} + +pub trait Trait5<T, const N: usize> { + fn quux(&self, _: &[T; N]); +} + +#[derive(Copy, Clone)] +pub struct Type5; + +impl<T, U, const N: usize> Trait5<U, N> for T { + fn quux(&self, _: &[U; N]) { + } +} + +pub fn foo1(a: &dyn Trait1) { + a.foo(); + // CHECK-LABEL: define{{.*}}4foo1{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE1:[[:print:]]+]]") +} + +pub fn bar1() { + let a = Type1; + let b = &a as &dyn Trait1; + b.foo(); + // CHECK-LABEL: define{{.*}}4bar1{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") +} + +pub fn foo2<T>(a: &dyn Trait2<T>) { + a.bar(); + // CHECK-LABEL: define{{.*}}4foo2{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") +} + +pub fn bar2() { + let a = Type2; + foo2(&a); + let b = &a as &dyn Trait2<i32>; + b.bar(); + // CHECK-LABEL: define{{.*}}4bar2{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE2:[[:print:]]+]]") +} + +pub fn foo3(a: &dyn Trait3<Type3>) { + let b = Type3; + a.baz(&b); + // CHECK-LABEL: define{{.*}}4foo3{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]") +} + +pub fn bar3() { + let a = Type3; + foo3(&a); + let b = &a as &dyn Trait3<Type3>; + b.baz(&a); + // CHECK-LABEL: define{{.*}}4bar3{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE3:[[:print:]]+]]") +} + +pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) { + let b = Type4; + a.qux(&b); + // CHECK-LABEL: define{{.*}}4foo4{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]") +} + +pub fn bar4<'a>() { + let a = Type4; + foo4(&a); + let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>; + b.qux(&a); + // CHECK-LABEL: define{{.*}}4bar4{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE4:[[:print:]]+]]") +} + +pub fn foo5(a: &dyn Trait5<Type5, 32>) { + let b = &[Type5; 32]; + a.quux(&b); + // CHECK-LABEL: define{{.*}}4foo5{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]") +} + +pub fn bar5() { + let a = &[Type5; 32]; + foo5(&a); + let b = &a as &dyn Trait5<Type5, 32>; + b.quux(&a); + // CHECK-LABEL: define{{.*}}4bar5{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test(ptr {{%f|%[0-9]}}, metadata !"[[TYPE5:[[:print:]]+]]") +} + +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"} +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE2]]"} +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE3]]"} +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE4]]"} +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE5]]"} diff --git a/tests/codegen/sanitizer-cfi-generalize-pointers.rs b/tests/codegen/sanitizer/cfi-generalize-pointers.rs index 677ebdb27..677ebdb27 100644 --- a/tests/codegen/sanitizer-cfi-generalize-pointers.rs +++ b/tests/codegen/sanitizer/cfi-generalize-pointers.rs diff --git a/tests/codegen/sanitizer-cfi-normalize-integers.rs b/tests/codegen/sanitizer/cfi-normalize-integers.rs index aa3913cb8..aa3913cb8 100644 --- a/tests/codegen/sanitizer-cfi-normalize-integers.rs +++ b/tests/codegen/sanitizer/cfi-normalize-integers.rs diff --git a/tests/codegen/sanitizer/kasan-emits-instrumentation.rs b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs new file mode 100644 index 000000000..783bc47b9 --- /dev/null +++ b/tests/codegen/sanitizer/kasan-emits-instrumentation.rs @@ -0,0 +1,47 @@ +// Verifies that `-Zsanitizer=kernel-address` emits sanitizer instrumentation. + +// compile-flags: -Zsanitizer=kernel-address +// revisions: aarch64 riscv64imac riscv64gc x86_64 +//[aarch64] compile-flags: --target aarch64-unknown-none +//[aarch64] needs-llvm-components: aarch64 +//[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf +//[riscv64imac] needs-llvm-components: riscv +//[riscv64imac] min-llvm-version: 16 +//[riscv64gc] compile-flags: --target riscv64gc-unknown-none-elf +//[riscv64gc] needs-llvm-components: riscv +//[riscv64gc] min-llvm-version: 16 +//[x86_64] compile-flags: --target x86_64-unknown-none +//[x86_64] needs-llvm-components: x86 + +#![crate_type = "rlib"] +#![feature(no_core, no_sanitize, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +impl Copy for u8 {} + +// CHECK-LABEL: ; kasan_emits_instrumentation::unsanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK-NOT: sanitize_address +// CHECK: start: +// CHECK-NOT: call void @__asan_report_load +// CHECK: } +#[no_sanitize(address)] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK-LABEL: ; kasan_emits_instrumentation::sanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK: sanitize_address +// CHECK: start: +// CHECK: call void @__asan_report_load +// CHECK: } +pub fn sanitized(b: &mut u8) -> u8 { + *b +} diff --git a/tests/codegen/sanitizer-kcfi-add-kcfi-flag.rs b/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs index c2eb852ae..c2eb852ae 100644 --- a/tests/codegen/sanitizer-kcfi-add-kcfi-flag.rs +++ b/tests/codegen/sanitizer/kcfi-add-kcfi-flag.rs diff --git a/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs new file mode 100644 index 000000000..001fc956a --- /dev/null +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-attr-no-sanitize.rs @@ -0,0 +1,30 @@ +// Verifies that KCFI operand bundles are omitted. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(no_core, no_sanitize, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } + +impl Copy for i32 {} + +#[no_sanitize(kcfi)] +pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 { + // CHECK-LABEL: kcfi_emit_kcfi_operand_bundle_attr_no_sanitize::foo + // CHECK: Function Attrs: {{.*}} + // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: start: + // CHECK-NOT: {{%.+}} = call {{(noundef )*}}i32 %f(i32 {{(noundef )*}}%arg){{.*}}[ "kcfi"(i32 {{[-0-9]+}}) ] + // CHECK: ret i32 {{%.+}} + f(arg) +} diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs index 29e4df351..29e4df351 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-generalized.rs diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs index 84d678a33..84d678a33 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized-generalized.rs diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs index 761c37a9e..761c37a9e 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi-normalized.rs diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs index 83cda0ef1..83cda0ef1 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle-itanium-cxx-abi.rs diff --git a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle.rs b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle.rs index e1d617b5e..e1d617b5e 100644 --- a/tests/codegen/sanitizer-kcfi-emit-kcfi-operand-bundle.rs +++ b/tests/codegen/sanitizer/kcfi-emit-kcfi-operand-bundle.rs diff --git a/tests/codegen/sanitizer/kcfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi-emit-type-metadata-trait-objects.rs new file mode 100644 index 000000000..7aed137f2 --- /dev/null +++ b/tests/codegen/sanitizer/kcfi-emit-type-metadata-trait-objects.rs @@ -0,0 +1,174 @@ +// Verifies that type metadata identifiers for trait objects are emitted correctly. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(arbitrary_self_types, no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } +#[lang="receiver"] +trait Receiver { } +#[lang="dispatch_from_dyn"] +trait DispatchFromDyn<T> { } +impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +#[lang = "unsize"] +trait Unsize<T: ?Sized> { } +#[lang = "coerce_unsized"] +pub trait CoerceUnsized<T: ?Sized> { } +impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +#[lang="freeze"] +trait Freeze { } +#[lang="drop_in_place"] +fn drop_in_place_fn<T>() { } + +pub trait Trait1 { + fn foo(&self); +} + +pub struct Type1; + +impl Trait1 for Type1 { + fn foo(&self) { + } +} + +pub trait Trait2<T> { + fn bar(&self); +} + +pub struct Type2; + +impl Trait2<i32> for Type2 { + fn bar(&self) { + } +} + +pub trait Trait3<T> { + fn baz(&self, _: &T); +} + +pub struct Type3; + +impl<T, U> Trait3<U> for T { + fn baz(&self, _: &U) { + } +} + +pub trait Trait4<'a, T> { + type Output: 'a; + fn qux(&self, _: &T) -> Self::Output; +} + +pub struct Type4; + +impl<'a, T, U> Trait4<'a, U> for T { + type Output = &'a i32; + fn qux(&self, _: &U) -> Self::Output { + &0 + } +} + +pub trait Trait5<T, const N: usize> { + fn quux(&self, _: &[T; N]); +} + +pub struct Type5; + +impl Copy for Type5 {} + +impl<T, U, const N: usize> Trait5<U, N> for T { + fn quux(&self, _: &[U; N]) { + } +} + +pub fn foo1(a: &dyn Trait1) { + a.foo(); + // CHECK-LABEL: define{{.*}}4foo1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] +} + +pub fn bar1() { + let a = Type1; + let b = &a as &dyn Trait1; + b.foo(); + // CHECK-LABEL: define{{.*}}4bar1{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] +} + +pub fn foo2<T>(a: &dyn Trait2<T>) { + a.bar(); + // CHECK-LABEL: define{{.*}}4foo2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ] +} + +pub fn bar2() { + let a = Type2; + foo2(&a); + let b = &a as &dyn Trait2<i32>; + b.bar(); + // CHECK-LABEL: define{{.*}}4bar2{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE2:[[:print:]]+]]) ] +} + +pub fn foo3(a: &dyn Trait3<Type3>) { + let b = Type3; + a.baz(&b); + // CHECK-LABEL: define{{.*}}4foo3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ] +} + +pub fn bar3() { + let a = Type3; + foo3(&a); + let b = &a as &dyn Trait3<Type3>; + b.baz(&a); + // CHECK-LABEL: define{{.*}}4bar3{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE3:[[:print:]]+]]) ] +} + +pub fn foo4<'a>(a: &dyn Trait4<'a, Type4, Output = &'a i32>) { + let b = Type4; + a.qux(&b); + // CHECK-LABEL: define{{.*}}4foo4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call align 4 ptr %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ] +} + +pub fn bar4<'a>() { + let a = Type4; + foo4(&a); + let b = &a as &dyn Trait4<'a, Type4, Output = &'a i32>; + b.qux(&a); + // CHECK-LABEL: define{{.*}}4bar4{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call align 4 ptr %{{[0-9]}}(ptr align 1 {{%[a-z]\.0|%_[0-9]}}, ptr align 1 {{%[a-z]\.0|%_[0-9]}}){{.*}}[ "kcfi"(i32 [[TYPE4:[[:print:]]+]]) ] +} + +pub fn foo5(a: &dyn Trait5<Type5, 32>) { + let b = &[Type5; 32]; + a.quux(&b); + // CHECK-LABEL: define{{.*}}4foo5{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, ptr align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ] +} + +pub fn bar5() { + let a = &[Type5; 32]; + foo5(&a); + let b = &a as &dyn Trait5<Type5, 32>; + b.quux(&a); + // CHECK-LABEL: define{{.*}}4bar5{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %{{[0-9]}}(ptr align 1 {{%[a-z](\.0)*|%_[0-9]+]}}, ptr align 1 {{%[a-z](\.0)*|%_[0-9]+}}){{.*}}[ "kcfi"(i32 [[TYPE5:[[:print:]]+]]) ] +} + +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]} +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE2]]} +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE3]]} +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE4]]} +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE5]]} diff --git a/tests/codegen/sanitizer-memory-track-orgins.rs b/tests/codegen/sanitizer/memory-track-origins.rs index 4bd50508d..4bd50508d 100644 --- a/tests/codegen/sanitizer-memory-track-orgins.rs +++ b/tests/codegen/sanitizer/memory-track-origins.rs diff --git a/tests/codegen/sanitizer_memtag_attr_check.rs b/tests/codegen/sanitizer/memtag-attr-check.rs index 2fd362656..2fd362656 100644 --- a/tests/codegen/sanitizer_memtag_attr_check.rs +++ b/tests/codegen/sanitizer/memtag-attr-check.rs diff --git a/tests/codegen/sanitizer-no-sanitize-inlining.rs b/tests/codegen/sanitizer/no-sanitize-inlining.rs index f4af60bae..f4af60bae 100644 --- a/tests/codegen/sanitizer-no-sanitize-inlining.rs +++ b/tests/codegen/sanitizer/no-sanitize-inlining.rs diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs new file mode 100644 index 000000000..783b568e2 --- /dev/null +++ b/tests/codegen/sanitizer/no-sanitize.rs @@ -0,0 +1,29 @@ +// Verifies that no_sanitize attribute can be used to +// selectively disable sanitizer instrumentation. +// +// needs-sanitizer-address +// compile-flags: -Zsanitizer=address + +#![crate_type="lib"] +#![feature(no_sanitize)] + +// CHECK-LABEL: ; no_sanitize::unsanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK-NOT: sanitize_address +// CHECK: start: +// CHECK-NOT: call void @__asan_report_load +// CHECK: } +#[no_sanitize(address)] +pub fn unsanitized(b: &mut u8) -> u8 { + *b +} + +// CHECK-LABEL: ; no_sanitize::sanitized +// CHECK-NEXT: ; Function Attrs: +// CHECK: sanitize_address +// CHECK: start: +// CHECK: call void @__asan_report_load +// CHECK: } +pub fn sanitized(b: &mut u8) -> u8 { + *b +} diff --git a/tests/codegen/sanitizer-safestack-attr-check.rs b/tests/codegen/sanitizer/safestack-attr-check.rs index b73ed00e7..b73ed00e7 100644 --- a/tests/codegen/sanitizer-safestack-attr-check.rs +++ b/tests/codegen/sanitizer/safestack-attr-check.rs diff --git a/tests/codegen/sanitizer-recover.rs b/tests/codegen/sanitizer/sanitizer-recover.rs index 7b00fcf8e..7b00fcf8e 100644 --- a/tests/codegen/sanitizer-recover.rs +++ b/tests/codegen/sanitizer/sanitizer-recover.rs diff --git a/tests/codegen/sanitizer_scs_attr_check.rs b/tests/codegen/sanitizer/scs-attr-check.rs index a885d9117..a885d9117 100644 --- a/tests/codegen/sanitizer_scs_attr_check.rs +++ b/tests/codegen/sanitizer/scs-attr-check.rs diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index faac7566a..0bcfacec6 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -116,150 +116,150 @@ extern "platform-intrinsic" { fn simd_saturating_sub<T>(x: T, y: T) -> T; } -// NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) +// NOTE(eddyb) `%{{x|0}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being -// a pointer to a vector, and `%1` a vector loaded from that pointer. +// a pointer to a vector, and `%0` a vector loaded from that pointer. // This is controlled by the target spec option `simd_types_indirect`. -// The same applies to `%{{y|2}}` as well. +// The same applies to `%{{y|1}}` as well. // CHECK-LABEL: @sadd_i8x2 #[no_mangle] pub unsafe fn sadd_i8x2(x: i8x2, y: i8x2) -> i8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x4 #[no_mangle] pub unsafe fn sadd_i8x4(x: i8x4, y: i8x4) -> i8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x8 #[no_mangle] pub unsafe fn sadd_i8x8(x: i8x8, y: i8x8) -> i8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x16 #[no_mangle] pub unsafe fn sadd_i8x16(x: i8x16, y: i8x16) -> i8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x32 #[no_mangle] pub unsafe fn sadd_i8x32(x: i8x32, y: i8x32) -> i8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x64 #[no_mangle] pub unsafe fn sadd_i8x64(x: i8x64, y: i8x64) -> i8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x2 #[no_mangle] pub unsafe fn sadd_i16x2(x: i16x2, y: i16x2) -> i16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x4 #[no_mangle] pub unsafe fn sadd_i16x4(x: i16x4, y: i16x4) -> i16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x8 #[no_mangle] pub unsafe fn sadd_i16x8(x: i16x8, y: i16x8) -> i16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x16 #[no_mangle] pub unsafe fn sadd_i16x16(x: i16x16, y: i16x16) -> i16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x32 #[no_mangle] pub unsafe fn sadd_i16x32(x: i16x32, y: i16x32) -> i16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x2 #[no_mangle] pub unsafe fn sadd_i32x2(x: i32x2, y: i32x2) -> i32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x4 #[no_mangle] pub unsafe fn sadd_i32x4(x: i32x4, y: i32x4) -> i32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x8 #[no_mangle] pub unsafe fn sadd_i32x8(x: i32x8, y: i32x8) -> i32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x16 #[no_mangle] pub unsafe fn sadd_i32x16(x: i32x16, y: i32x16) -> i32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x2 #[no_mangle] pub unsafe fn sadd_i64x2(x: i64x2, y: i64x2) -> i64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x4 #[no_mangle] pub unsafe fn sadd_i64x4(x: i64x4, y: i64x4) -> i64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x8 #[no_mangle] pub unsafe fn sadd_i64x8(x: i64x8, y: i64x8) -> i64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i128x2 #[no_mangle] pub unsafe fn sadd_i128x2(x: i128x2, y: i128x2) -> i128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i128x4 #[no_mangle] pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}}) simd_saturating_add(x, y) } @@ -268,140 +268,140 @@ pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 { // CHECK-LABEL: @uadd_u8x2 #[no_mangle] pub unsafe fn uadd_u8x2(x: u8x2, y: u8x2) -> u8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x4 #[no_mangle] pub unsafe fn uadd_u8x4(x: u8x4, y: u8x4) -> u8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x8 #[no_mangle] pub unsafe fn uadd_u8x8(x: u8x8, y: u8x8) -> u8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x16 #[no_mangle] pub unsafe fn uadd_u8x16(x: u8x16, y: u8x16) -> u8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x32 #[no_mangle] pub unsafe fn uadd_u8x32(x: u8x32, y: u8x32) -> u8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x64 #[no_mangle] pub unsafe fn uadd_u8x64(x: u8x64, y: u8x64) -> u8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x2 #[no_mangle] pub unsafe fn uadd_u16x2(x: u16x2, y: u16x2) -> u16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x4 #[no_mangle] pub unsafe fn uadd_u16x4(x: u16x4, y: u16x4) -> u16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x8 #[no_mangle] pub unsafe fn uadd_u16x8(x: u16x8, y: u16x8) -> u16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x16 #[no_mangle] pub unsafe fn uadd_u16x16(x: u16x16, y: u16x16) -> u16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x32 #[no_mangle] pub unsafe fn uadd_u16x32(x: u16x32, y: u16x32) -> u16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x2 #[no_mangle] pub unsafe fn uadd_u32x2(x: u32x2, y: u32x2) -> u32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x4 #[no_mangle] pub unsafe fn uadd_u32x4(x: u32x4, y: u32x4) -> u32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x8 #[no_mangle] pub unsafe fn uadd_u32x8(x: u32x8, y: u32x8) -> u32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x16 #[no_mangle] pub unsafe fn uadd_u32x16(x: u32x16, y: u32x16) -> u32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x2 #[no_mangle] pub unsafe fn uadd_u64x2(x: u64x2, y: u64x2) -> u64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x4 #[no_mangle] pub unsafe fn uadd_u64x4(x: u64x4, y: u64x4) -> u64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x8 #[no_mangle] pub unsafe fn uadd_u64x8(x: u64x8, y: u64x8) -> u64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u128x2 #[no_mangle] pub unsafe fn uadd_u128x2(x: u128x2, y: u128x2) -> u128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u128x4 #[no_mangle] pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}}) simd_saturating_add(x, y) } @@ -412,140 +412,140 @@ pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 { // CHECK-LABEL: @ssub_i8x2 #[no_mangle] pub unsafe fn ssub_i8x2(x: i8x2, y: i8x2) -> i8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x4 #[no_mangle] pub unsafe fn ssub_i8x4(x: i8x4, y: i8x4) -> i8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x8 #[no_mangle] pub unsafe fn ssub_i8x8(x: i8x8, y: i8x8) -> i8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x16 #[no_mangle] pub unsafe fn ssub_i8x16(x: i8x16, y: i8x16) -> i8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x32 #[no_mangle] pub unsafe fn ssub_i8x32(x: i8x32, y: i8x32) -> i8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x64 #[no_mangle] pub unsafe fn ssub_i8x64(x: i8x64, y: i8x64) -> i8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x2 #[no_mangle] pub unsafe fn ssub_i16x2(x: i16x2, y: i16x2) -> i16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x4 #[no_mangle] pub unsafe fn ssub_i16x4(x: i16x4, y: i16x4) -> i16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x8 #[no_mangle] pub unsafe fn ssub_i16x8(x: i16x8, y: i16x8) -> i16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x16 #[no_mangle] pub unsafe fn ssub_i16x16(x: i16x16, y: i16x16) -> i16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x32 #[no_mangle] pub unsafe fn ssub_i16x32(x: i16x32, y: i16x32) -> i16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x2 #[no_mangle] pub unsafe fn ssub_i32x2(x: i32x2, y: i32x2) -> i32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x4 #[no_mangle] pub unsafe fn ssub_i32x4(x: i32x4, y: i32x4) -> i32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x8 #[no_mangle] pub unsafe fn ssub_i32x8(x: i32x8, y: i32x8) -> i32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x16 #[no_mangle] pub unsafe fn ssub_i32x16(x: i32x16, y: i32x16) -> i32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x2 #[no_mangle] pub unsafe fn ssub_i64x2(x: i64x2, y: i64x2) -> i64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x4 #[no_mangle] pub unsafe fn ssub_i64x4(x: i64x4, y: i64x4) -> i64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x8 #[no_mangle] pub unsafe fn ssub_i64x8(x: i64x8, y: i64x8) -> i64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i128x2 #[no_mangle] pub unsafe fn ssub_i128x2(x: i128x2, y: i128x2) -> i128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i128x4 #[no_mangle] pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}}) simd_saturating_sub(x, y) } @@ -554,139 +554,139 @@ pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 { // CHECK-LABEL: @usub_u8x2 #[no_mangle] pub unsafe fn usub_u8x2(x: u8x2, y: u8x2) -> u8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|0}}, <2 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x4 #[no_mangle] pub unsafe fn usub_u8x4(x: u8x4, y: u8x4) -> u8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|0}}, <4 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x8 #[no_mangle] pub unsafe fn usub_u8x8(x: u8x8, y: u8x8) -> u8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|0}}, <8 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x16 #[no_mangle] pub unsafe fn usub_u8x16(x: u8x16, y: u8x16) -> u8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|0}}, <16 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x32 #[no_mangle] pub unsafe fn usub_u8x32(x: u8x32, y: u8x32) -> u8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|0}}, <32 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x64 #[no_mangle] pub unsafe fn usub_u8x64(x: u8x64, y: u8x64) -> u8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|0}}, <64 x i8> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x2 #[no_mangle] pub unsafe fn usub_u16x2(x: u16x2, y: u16x2) -> u16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|0}}, <2 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x4 #[no_mangle] pub unsafe fn usub_u16x4(x: u16x4, y: u16x4) -> u16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|0}}, <4 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x8 #[no_mangle] pub unsafe fn usub_u16x8(x: u16x8, y: u16x8) -> u16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|0}}, <8 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x16 #[no_mangle] pub unsafe fn usub_u16x16(x: u16x16, y: u16x16) -> u16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|0}}, <16 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x32 #[no_mangle] pub unsafe fn usub_u16x32(x: u16x32, y: u16x32) -> u16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|0}}, <32 x i16> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x2 #[no_mangle] pub unsafe fn usub_u32x2(x: u32x2, y: u32x2) -> u32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|0}}, <2 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x4 #[no_mangle] pub unsafe fn usub_u32x4(x: u32x4, y: u32x4) -> u32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|0}}, <4 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x8 #[no_mangle] pub unsafe fn usub_u32x8(x: u32x8, y: u32x8) -> u32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|0}}, <8 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x16 #[no_mangle] pub unsafe fn usub_u32x16(x: u32x16, y: u32x16) -> u32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|0}}, <16 x i32> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x2 #[no_mangle] pub unsafe fn usub_u64x2(x: u64x2, y: u64x2) -> u64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|0}}, <2 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x4 #[no_mangle] pub unsafe fn usub_u64x4(x: u64x4, y: u64x4) -> u64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|0}}, <4 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x8 #[no_mangle] pub unsafe fn usub_u64x8(x: u64x8, y: u64x8) -> u64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|0}}, <8 x i64> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u128x2 #[no_mangle] pub unsafe fn usub_u128x2(x: u128x2, y: u128x2) -> u128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|0}}, <2 x i128> %{{y|1}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u128x4 #[no_mangle] pub unsafe fn usub_u128x4(x: u128x4, y: u128x4) -> u128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|0}}, <4 x i128> %{{y|1}}) simd_saturating_sub(x, y) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs index 80583dec1..a5d2509d0 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs @@ -35,13 +35,13 @@ pub unsafe fn extract_s(v: S<4>, i: u32) -> f32 { // CHECK-LABEL: @insert_m #[no_mangle] pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M { - // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i simd_insert(v, i, j) } // CHECK-LABEL: @insert_s #[no_mangle] pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4> { - // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|0|1}}, float %j, i32 %i simd_insert(v, i, j) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs index cacc32f2f..0bb210196 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -23,7 +23,7 @@ extern "platform-intrinsic" { #[no_mangle] pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2<i32>, values: Vec2<f32>) -> Vec2<f32> { - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.{{.+}}(<2 x {{float\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}}) + // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -31,6 +31,6 @@ pub unsafe fn gather_f32x2(pointers: Vec2<*const f32>, mask: Vec2<i32>, #[no_mangle] pub unsafe fn gather_pf32x2(pointers: Vec2<*const *const f32>, mask: Vec2<i32>, values: Vec2<*const f32>) -> Vec2<*const f32> { - // CHECK: call <2 x {{float\*|ptr}}> @llvm.masked.gather.{{.+}}(<2 x {{float\*\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x {{float\*|ptr}}> {{.*}}) + // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}, <2 x ptr> {{.*}}) simd_gather(values, pointers, mask) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 94ecaf609..51953560b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -23,7 +23,7 @@ extern "platform-intrinsic" { #[no_mangle] pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2<i32>, values: Vec2<f32>) { - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0{{.*}}(<2 x float> {{.*}}, <2 x {{float\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) + // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) simd_scatter(values, pointers, mask) } @@ -32,6 +32,6 @@ pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2<i32>, #[no_mangle] pub unsafe fn scatter_pf32x2(pointers: Vec2<*mut *const f32>, mask: Vec2<i32>, values: Vec2<*const f32>) { - // CHECK: call void @llvm.masked.scatter.v2p0{{.*}}.v2p0{{.*}}(<2 x {{float\*|ptr}}> {{.*}}, <2 x {{float\*\*|ptr}}> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) + // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> {{.*}}) simd_scatter(values, pointers, mask) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index fd488a14b..eb4ce307e 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -2,7 +2,6 @@ // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] - #![allow(non_camel_case_types)] #![feature(repr_simd, platform_intrinsics)] #![feature(inline_const)] @@ -43,8 +42,8 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> { // CHECK-LABEL: @build_array_transmute_s #[no_mangle] pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> { - // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]] - // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]] + // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] + // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } @@ -58,8 +57,8 @@ pub fn build_array_t(x: [f32; 4]) -> T { // CHECK-LABEL: @build_array_transmute_t #[no_mangle] pub fn build_array_transmute_t(x: [f32; 4]) -> T { - // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]] - // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]] + // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] + // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } @@ -77,7 +76,7 @@ pub fn build_array_u(x: [f32; 4]) -> U { // CHECK-LABEL: @build_array_transmute_u #[no_mangle] pub fn build_array_transmute_u(x: [f32; 4]) -> U { - // CHECK: %[[VAL:.+]] = load <4 x float>, {{ptr %x|.+>\* %.+}}, align [[ARRAY_ALIGN]] - // CHECK: store <4 x float> %[[VAL:.+]], {{ptr %0|.+>\* %.+}}, align [[VECTOR_ALIGN]] + // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] + // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } diff --git a/tests/codegen/simd-wide-sum.rs b/tests/codegen/simd/simd-wide-sum.rs index db2aa20bd..3116f9597 100644 --- a/tests/codegen/simd-wide-sum.rs +++ b/tests/codegen/simd/simd-wide-sum.rs @@ -1,6 +1,11 @@ +// revisions: llvm mir-opt3 // compile-flags: -C opt-level=3 -Z merge-functions=disabled --edition=2021 // only-x86_64 // ignore-debug: the debug assertions get in the way +// [mir-opt3]compile-flags: -Zmir-opt-level=3 +// [mir-opt3]build-pass + +// mir-opt3 is a regression test for https://github.com/rust-lang/rust/issues/98016 #![crate_type = "lib"] #![feature(portable_simd)] @@ -47,9 +52,8 @@ pub fn wider_reduce_iter(x: Simd<u8, N>) -> u16 { #[no_mangle] // CHECK-LABEL: @wider_reduce_into_iter pub fn wider_reduce_into_iter(x: Simd<u8, N>) -> u16 { - // FIXME MIR inlining messes up LLVM optimizations. - // WOULD-CHECK: zext <8 x i8> - // WOULD-CHECK-SAME: to <8 x i16> - // WOULD-CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> + // CHECK: zext <8 x i8> + // CHECK-SAME: to <8 x i16> + // CHECK: call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> x.to_array().into_iter().map(u16::from).sum() } diff --git a/tests/codegen/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs index f23337773..1ee73de11 100644 --- a/tests/codegen/simd_arith_offset.rs +++ b/tests/codegen/simd/simd_arith_offset.rs @@ -21,6 +21,6 @@ pub struct Simd<T, const LANES: usize>([T; LANES]); // CHECK-LABEL: smoke #[no_mangle] pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> { - // CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %1, <8 x i64> %2 + // CHECK: getelementptr i8, <8 x ptr> %0, <8 x i64> %1 unsafe { simd_arith_offset(ptrs, offsets) } } diff --git a/tests/codegen/swap-simd-types.rs b/tests/codegen/simd/swap-simd-types.rs index 3472a42b0..3472a42b0 100644 --- a/tests/codegen/swap-simd-types.rs +++ b/tests/codegen/simd/swap-simd-types.rs diff --git a/tests/codegen/unpadded-simd.rs b/tests/codegen/simd/unpadded-simd.rs index eb44dbd93..eb44dbd93 100644 --- a/tests/codegen/unpadded-simd.rs +++ b/tests/codegen/simd/unpadded-simd.rs diff --git a/tests/codegen/slice-init.rs b/tests/codegen/slice-init.rs index 794b773a7..c0bf1a041 100644 --- a/tests/codegen/slice-init.rs +++ b/tests/codegen/slice-init.rs @@ -8,7 +8,7 @@ pub fn zero_sized_elem() { // CHECK-NOT: br label %repeat_loop_header{{.*}} // CHECK-NOT: call void @llvm.memset.p0 let x = [(); 4]; - drop(&x); + opaque(&x); } // CHECK-LABEL: @zero_len_array @@ -17,16 +17,16 @@ pub fn zero_len_array() { // CHECK-NOT: br label %repeat_loop_header{{.*}} // CHECK-NOT: call void @llvm.memset.p0 let x = [4; 0]; - drop(&x); + opaque(&x); } // CHECK-LABEL: @byte_array #[no_mangle] pub fn byte_array() { - // CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 7, i{{[0-9]+}} 4 + // CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 7, i{{[0-9]+}} 4 // CHECK-NOT: br label %repeat_loop_header{{.*}} let x = [7u8; 4]; - drop(&x); + opaque(&x); } #[allow(dead_code)] @@ -39,19 +39,19 @@ enum Init { // CHECK-LABEL: @byte_enum_array #[no_mangle] pub fn byte_enum_array() { - // CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 {{.*}}, i{{[0-9]+}} 4 + // CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 {{.*}}, i{{[0-9]+}} 4 // CHECK-NOT: br label %repeat_loop_header{{.*}} let x = [Init::Memset; 4]; - drop(&x); + opaque(&x); } // CHECK-LABEL: @zeroed_integer_array #[no_mangle] pub fn zeroed_integer_array() { - // CHECK: call void @llvm.memset.{{.+}}({{i8\*|ptr}} {{.*}}, i8 0, i{{[0-9]+}} 16 + // CHECK: call void @llvm.memset.{{.+}}(ptr {{.*}}, i8 0, i{{[0-9]+}} 16 // CHECK-NOT: br label %repeat_loop_header{{.*}} let x = [0u32; 4]; - drop(&x); + opaque(&x); } // CHECK-LABEL: @nonzero_integer_array @@ -60,5 +60,9 @@ pub fn nonzero_integer_array() { // CHECK: br label %repeat_loop_header{{.*}} // CHECK-NOT: call void @llvm.memset.p0 let x = [0x1a_2b_3c_4d_u32; 4]; - drop(&x); + opaque(&x); } + +// Use an opaque function to prevent rustc from removing useless drops. +#[inline(never)] +pub fn opaque(_: impl Sized) {} diff --git a/tests/codegen/slice-iter-len-eq-zero.rs b/tests/codegen/slice-iter-len-eq-zero.rs index 894b0ec3d..c7515ce35 100644 --- a/tests/codegen/slice-iter-len-eq-zero.rs +++ b/tests/codegen/slice-iter-len-eq-zero.rs @@ -9,8 +9,8 @@ type Demo = [u8; 3]; #[no_mangle] pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool { // CHECK-NOT: sub - // CHECK: %2 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}} - // CHECK: ret i1 %2 + // CHECK: %[[RET:.+]] = icmp eq ptr {{%1|%0}}, {{%1|%0}} + // CHECK: ret i1 %[[RET]] y.len() == 0 } @@ -22,7 +22,7 @@ pub fn array_into_iter_len_eq_zero(y: std::array::IntoIter<Demo, 123>) -> bool { // CHECK-NOT: icmp // CHECK-NOT: sub - // CHECK: %1 = icmp eq {{i16|i32|i64}} - // CHECK: ret i1 %1 + // CHECK: %_0 = icmp eq {{i16|i32|i64}} + // CHECK: ret i1 %_0 y.len() == 0 } diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index 997bdaf56..f7d164bc8 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -2,11 +2,16 @@ // compile-flags: -O // ignore-debug (these add extra checks that make it hard to verify) #![crate_type = "lib"] +#![feature(exact_size_is_empty)] // The slice iterator used to `assume` that the `start` pointer was non-null. // That ought to be unneeded, though, since the type is `NonNull`, so this test // confirms that the appropriate metadata is included to denote that. +// It also used to `assume` the `end` pointer was non-null, but that's no longer +// needed as the code changed to read it as a `NonNull`, and thus gets the +// appropriate `!nonnull` annotations naturally. + // CHECK-LABEL: @slice_iter_next( #[no_mangle] pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { @@ -75,3 +80,37 @@ pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { // CHECK: } slice.iter_mut() } + +// CHECK-LABEL: @slice_iter_is_empty +#[no_mangle] +pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { + // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + + // CHECK: %[[RET:.+]] = icmp eq ptr %[[START]], %[[END]] + // CHECK: ret i1 %[[RET]] + it.is_empty() +} + +// CHECK-LABEL: @slice_iter_len +#[no_mangle] +pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize { + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + + // CHECK: ptrtoint + // CHECK: ptrtoint + // CHECK: sub nuw + // CHECK: lshr exact + it.len() +} diff --git a/tests/codegen/slice-ref-equality.rs b/tests/codegen/slice-ref-equality.rs index 8f0adab35..afbdf66ce 100644 --- a/tests/codegen/slice-ref-equality.rs +++ b/tests/codegen/slice-ref-equality.rs @@ -25,7 +25,7 @@ pub fn is_zero_slice_long(data: &[u8; 456]) -> bool { // CHECK-LABEL: @is_zero_slice_short #[no_mangle] pub fn is_zero_slice_short(data: &[u8; 4]) -> bool { - // CHECK: %[[LOAD:.+]] = load i32, {{i32\*|ptr}} %{{.+}}, align 1 + // CHECK: %[[LOAD:.+]] = load i32, ptr %{{.+}}, align 1 // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[LOAD]], 0 // CHECK-NEXT: ret i1 %[[EQ]] &data[..] == [0; 4] @@ -34,7 +34,7 @@ pub fn is_zero_slice_short(data: &[u8; 4]) -> bool { // CHECK-LABEL: @is_zero_array #[no_mangle] pub fn is_zero_array(data: &[u8; 4]) -> bool { - // CHECK: %[[LOAD:.+]] = load i32, {{i32\*|ptr}} %{{.+}}, align 1 + // CHECK: %[[LOAD:.+]] = load i32, ptr %{{.+}}, align 1 // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[LOAD]], 0 // CHECK-NEXT: ret i1 %[[EQ]] *data == [0; 4] @@ -50,7 +50,7 @@ pub fn is_zero_array(data: &[u8; 4]) -> bool { fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool { // CHECK: icmp eq [[USIZE]] %1, %3 // CHECK: %[[BYTES:.+]] = mul nsw [[USIZE]] %1, 3 - // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i8\*|ptr}} + // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr // CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]]) x == y } @@ -62,7 +62,7 @@ fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool { fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool { // CHECK: icmp eq [[USIZE]] %1, %3 // CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 2 - // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i32\*|ptr}} + // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr // CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]]) x == y } @@ -74,7 +74,7 @@ fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool { fn eq_slice_of_nonzero(x: &[NonZeroU32], y: &[NonZeroU32]) -> bool { // CHECK: icmp eq [[USIZE]] %1, %3 // CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 2 - // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i32\*|ptr}} + // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr // CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]]) x == y } @@ -86,7 +86,7 @@ fn eq_slice_of_nonzero(x: &[NonZeroU32], y: &[NonZeroU32]) -> bool { fn eq_slice_of_option_of_nonzero(x: &[Option<NonZeroI16>], y: &[Option<NonZeroI16>]) -> bool { // CHECK: icmp eq [[USIZE]] %1, %3 // CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 1 - // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}({{i16\*|ptr}} + // CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr // CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]]) x == y } diff --git a/tests/codegen/slice_as_from_ptr_range.rs b/tests/codegen/slice_as_from_ptr_range.rs index 0e3fefd97..3d8ab0a4b 100644 --- a/tests/codegen/slice_as_from_ptr_range.rs +++ b/tests/codegen/slice_as_from_ptr_range.rs @@ -1,7 +1,6 @@ // compile-flags: -O // only-64bit (because we're using [ui]size) // ignore-debug (because the assertions get in the way) -// min-llvm-version: 15.0 (because this is a relatively new instcombine) #![crate_type = "lib"] #![feature(slice_from_ptr_range)] diff --git a/tests/codegen/sroa-fragment-debuginfo.rs b/tests/codegen/sroa-fragment-debuginfo.rs new file mode 100644 index 000000000..fb10f63be --- /dev/null +++ b/tests/codegen/sroa-fragment-debuginfo.rs @@ -0,0 +1,46 @@ +// compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates +// compile-flags: -Cno-prepopulate-passes +// +// Tested offsets are only correct for x86_64. +// only-x86_64 + +#![crate_type = "lib"] + +pub struct ExtraSlice<'input> { + slice: &'input [u8], + extra: u32, +} + +#[no_mangle] +pub fn extra(s: &[u8]) { +// CHECK: void @extra( +// CHECK: %slice.dbg.spill1 = alloca i32, +// CHECK: %slice.dbg.spill = alloca { ptr, i64 }, +// CHECK: %s.dbg.spill = alloca { ptr, i64 }, +// CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()), +// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)), +// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)), + let slice = ExtraSlice { slice: s, extra: s.len() as u32 }; +} + +struct Zst; + +pub struct ZstSlice<'input> { + slice: &'input [u8], + extra: Zst, +} + +#[no_mangle] +pub fn zst(s: &[u8]) { + // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole + // variable, so is not a fragment. In that case, the variable must have no fragment. + +// CHECK: void @zst( +// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata !{}, metadata !DIExpression(DW_OP_LLVM_fragment, +// CHECK: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST:.*]], metadata !DIExpression()), +// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST]], + let slice = ZstSlice { slice: s, extra: Zst }; +} + +// CHECK: ![[S_EXTRA]] = !DILocalVariable(name: "s", +// CHECK: ![[SLICE_EXTRA]] = !DILocalVariable(name: "slice", diff --git a/tests/codegen/stores.rs b/tests/codegen/stores.rs index 837256e53..a8e155c4c 100644 --- a/tests/codegen/stores.rs +++ b/tests/codegen/stores.rs @@ -17,8 +17,8 @@ pub struct Bytes { pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { // CHECK: [[TMP:%.+]] = alloca i32 // CHECK: %y = alloca [4 x i8] -// CHECK: store i32 %0, {{i32\*|ptr}} [[TMP]] -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 {{.+}}, {{i8\*|ptr}} align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) +// CHECK: store i32 %0, ptr [[TMP]] +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; } @@ -29,7 +29,7 @@ pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) { // CHECK: [[TMP:%.+]] = alloca i32 // CHECK: %y = alloca %Bytes -// CHECK: store i32 %0, {{i32\*|ptr}} [[TMP]] -// CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 {{.+}}, {{i8\*|ptr}} align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) +// CHECK: store i32 %0, ptr [[TMP]] +// CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; } diff --git a/tests/codegen/swap-large-types.rs b/tests/codegen/swap-large-types.rs index 4a6840357..7b6611f3d 100644 --- a/tests/codegen/swap-large-types.rs +++ b/tests/codegen/swap-large-types.rs @@ -83,9 +83,9 @@ pub struct BigButHighlyAligned([u8; 64 * 3]); #[no_mangle] pub fn swap_big_aligned(x: &mut BigButHighlyAligned, y: &mut BigButHighlyAligned) { // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192) -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192) -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} noundef nonnull align 64 dereferenceable(192) +// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) +// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) +// CHECK: call void @llvm.memcpy.{{.+}}(ptr noundef nonnull align 64 dereferenceable(192) // CHECK-NOT: call void @llvm.memcpy swap(x, y) } diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs new file mode 100644 index 000000000..d07570617 --- /dev/null +++ b/tests/codegen/target-feature-inline-closure.rs @@ -0,0 +1,33 @@ +// only-x86_64 +// compile-flags: -Copt-level=3 + +#![crate_type = "lib"] +#![feature(target_feature_11)] + +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +// CHECK-LABEL: @with_avx +#[no_mangle] +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx")] +fn with_avx(x: __m256) -> __m256 { + // CHECK: fadd + let add = { + #[inline(always)] + |x, y| unsafe { _mm256_add_ps(x, y) } + }; + add(x, x) +} + +// CHECK-LABEL: @without_avx +#[no_mangle] +#[cfg(target_arch = "x86_64")] +unsafe fn without_avx(x: __m256) -> __m256 { + // CHECK-NOT: fadd + let add = { + #[inline(always)] + |x, y| unsafe { _mm256_add_ps(x, y) } + }; + add(x, x) +} diff --git a/tests/codegen/trailing_zeros.rs b/tests/codegen/trailing_zeros.rs new file mode 100644 index 000000000..2ea0e447a --- /dev/null +++ b/tests/codegen/trailing_zeros.rs @@ -0,0 +1,22 @@ +// compile-flags: -O +// min-llvm-version: 17 + +#![crate_type = "lib"] + +// CHECK-LABEL: @trailing_zeros_ge +#[no_mangle] +pub fn trailing_zeros_ge(val: u32) -> bool { + // CHECK: %[[AND:.*]] = and i32 %val, 7 + // CHECK: %[[ICMP:.*]] = icmp eq i32 %[[AND]], 0 + // CHECK: ret i1 %[[ICMP]] + val.trailing_zeros() >= 3 +} + +// CHECK-LABEL: @trailing_zeros_gt +#[no_mangle] +pub fn trailing_zeros_gt(val: u64) -> bool { + // CHECK: %[[AND:.*]] = and i64 %val, 15 + // CHECK: %[[ICMP:.*]] = icmp eq i64 %[[AND]], 0 + // CHECK: ret i1 %[[ICMP]] + val.trailing_zeros() > 3 +} diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs index 461dd550c..b8c51b084 100644 --- a/tests/codegen/transmute-optimized.rs +++ b/tests/codegen/transmute-optimized.rs @@ -1,5 +1,4 @@ // compile-flags: -O -Z merge-functions=disabled -// min-llvm-version: 15.0 # this test uses `ptr`s // ignore-debug #![crate_type = "lib"] diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index a0894a505..39126b024 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -1,5 +1,4 @@ // compile-flags: -C opt-level=0 -C no-prepopulate-passes -// min-llvm-version: 15.0 # this test assumes `ptr`s and thus no `pointercast`s #![crate_type = "lib"] @@ -11,24 +10,24 @@ // that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`. // CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x) -// CHECK: %0 = bitcast float %x to i32 -// CHECK-NEXT: ret i32 %0 +// CHECK: %_0 = bitcast float %x to i32 +// CHECK-NEXT: ret i32 %_0 #[no_mangle] pub fn f32_to_bits(x: f32) -> u32 { unsafe { std::mem::transmute(x) } } // CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b) -// CHECK: %0 = zext i1 %b to i8 -// CHECK-NEXT: ret i8 %0 +// CHECK: %_0 = zext i1 %b to i8 +// CHECK-NEXT: ret i8 %_0 #[no_mangle] pub fn bool_to_byte(b: bool) -> u8 { unsafe { std::mem::transmute(b) } } // CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte) -// CHECK: %0 = trunc i8 %byte to i1 -// CHECK-NEXT: ret i1 %0 +// CHECK: %_0 = trunc i8 %byte to i1 +// CHECK-NEXT: ret i1 %_0 #[no_mangle] pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) @@ -42,16 +41,16 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { } // CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p) -// CHECK: %0 = ptrtoint ptr %p to [[USIZE]] -// CHECK-NEXT: ret [[USIZE]] %0 +// CHECK: %_0 = ptrtoint ptr %p to [[USIZE]] +// CHECK-NEXT: ret [[USIZE]] %_0 #[no_mangle] pub fn ptr_to_int(p: *mut u16) -> usize { unsafe { std::mem::transmute(p) } } // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) -// CHECK: %0 = inttoptr [[USIZE]] %i to ptr -// CHECK-NEXT: ret ptr %0 +// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr +// CHECK-NEXT: ret ptr %_0 #[no_mangle] pub fn int_to_ptr(i: usize) -> *mut u16 { unsafe { std::mem::transmute(i) } diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index d23938776..9d34155bd 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -1,4 +1,3 @@ -// min-llvm-version: 15.0 // compile-flags: -O -Z merge-functions=disabled --edition=2021 // only-x86_64 diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs index 0924dda08..d5f53bedd 100644 --- a/tests/codegen/unchecked_shifts.rs +++ b/tests/codegen/unchecked_shifts.rs @@ -1,5 +1,4 @@ // compile-flags: -O -// min-llvm-version: 15.0 (LLVM 13 in CI does this differently from submodule LLVM) // ignore-debug (because unchecked is checked in debug) #![crate_type = "lib"] diff --git a/tests/codegen/uninit-consts.rs b/tests/codegen/uninit-consts.rs index 54e9a9e9b..1313e6763 100644 --- a/tests/codegen/uninit-consts.rs +++ b/tests/codegen/uninit-consts.rs @@ -8,7 +8,7 @@ use std::mem::MaybeUninit; pub struct PartiallyUninit { x: u32, - y: MaybeUninit<[u8; 10]> + y: MaybeUninit<[u8; 10]>, } // CHECK: [[FULLY_UNINIT:@[0-9]+]] = private unnamed_addr constant <{ [10 x i8] }> undef @@ -25,7 +25,7 @@ pub struct PartiallyUninit { #[no_mangle] pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> { const M: MaybeUninit<[u8; 10]> = MaybeUninit::uninit(); - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{[0-9]+}}, {{i8\*|ptr}} align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 1 %_0, ptr align 1 {{.*}}[[FULLY_UNINIT]]{{.*}}, i{{(32|64)}} 10, i1 false) M } @@ -33,7 +33,7 @@ pub const fn fully_uninit() -> MaybeUninit<[u8; 10]> { #[no_mangle] pub const fn partially_uninit() -> PartiallyUninit { const X: PartiallyUninit = PartiallyUninit { x: 0xdeadbeef, y: MaybeUninit::uninit() }; - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[PARTIALLY_UNINIT]]{{.*}}, i{{(32|64)}} 16, i1 false) X } @@ -41,7 +41,7 @@ pub const fn partially_uninit() -> PartiallyUninit { #[no_mangle] pub const fn uninit_padding_huge() -> [(u32, u8); 4096] { const X: [(u32, u8); 4096] = [(123, 45); 4096]; - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[UNINIT_PADDING_HUGE]]{{.*}}, i{{(32|64)}} 32768, i1 false) X } @@ -49,6 +49,6 @@ pub const fn uninit_padding_huge() -> [(u32, u8); 4096] { #[no_mangle] pub const fn fully_uninit_huge() -> MaybeUninit<[u32; 4096]> { const F: MaybeUninit<[u32; 4096]> = MaybeUninit::uninit(); - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 4 %{{[0-9]+}}, {{i8\*|ptr}} align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false) + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align 4 %_0, ptr align 4 {{.*}}[[FULLY_UNINIT_HUGE]]{{.*}}, i{{(32|64)}} 16384, i1 false) F } diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs index 8481ca8cc..4878ae5c3 100644 --- a/tests/codegen/union-abi.rs +++ b/tests/codegen/union-abi.rs @@ -17,25 +17,25 @@ pub struct i64x4(i64, i64, i64, i64); #[derive(Copy, Clone)] pub union UnionI64x4{ a:(), b: i64x4 } -// CHECK: define {{(dso_local )?}}void @test_UnionI64x4({{<4 x i64>\*|ptr}} {{.*}} %_1) +// CHECK: define {{(dso_local )?}}void @test_UnionI64x4(ptr {{.*}} %_1) #[no_mangle] pub fn test_UnionI64x4(_: UnionI64x4) { loop {} } pub union UnionI64x4_{ a: i64x4, b: (), c:i64x4, d: Unhab, e: ((),()), f: UnionI64x4 } -// CHECK: define {{(dso_local )?}}void @test_UnionI64x4_({{<4 x i64>\*|ptr}} {{.*}} %_1) +// CHECK: define {{(dso_local )?}}void @test_UnionI64x4_(ptr {{.*}} %_1) #[no_mangle] pub fn test_UnionI64x4_(_: UnionI64x4_) { loop {} } pub union UnionI64x4I64{ a: i64x4, b: i64 } -// CHECK: define {{(dso_local )?}}void @test_UnionI64x4I64({{%UnionI64x4I64\*|ptr}} {{.*}} %_1) +// CHECK: define {{(dso_local )?}}void @test_UnionI64x4I64(ptr {{.*}} %_1) #[no_mangle] pub fn test_UnionI64x4I64(_: UnionI64x4I64) { loop {} } pub union UnionI64x4Tuple{ a: i64x4, b: (i64, i64, i64, i64) } -// CHECK: define {{(dso_local )?}}void @test_UnionI64x4Tuple({{%UnionI64x4Tuple\*|ptr}} {{.*}} %_1) +// CHECK: define {{(dso_local )?}}void @test_UnionI64x4Tuple(ptr {{.*}} %_1) #[no_mangle] pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { loop {} } @@ -65,7 +65,7 @@ pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} } #[repr(C)] pub union CUnionU128{a:u128} -// CHECK: define {{(dso_local )?}}void @test_CUnionU128({{%CUnionU128\*|ptr}} {{.*}} %_1) +// CHECK: define {{(dso_local )?}}void @test_CUnionU128(ptr {{.*}} %_1) #[no_mangle] pub fn test_CUnionU128(_: CUnionU128) { loop {} } @@ -73,4 +73,4 @@ pub union UnionBool { b:bool } // CHECK: define {{(dso_local )?}}noundef zeroext i1 @test_UnionBool(i8 %b) #[no_mangle] pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } } -// CHECK: %0 = trunc i8 %b to i1 +// CHECK: %_0 = trunc i8 %b to i1 diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index 7e81367fc..0a02755a2 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -1,7 +1,7 @@ // needs-llvm-components: x86 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, c_unwind, abi_thiscall)] +#![feature(no_core, lang_items, c_unwind)] #[lang="sized"] trait Sized { } diff --git a/tests/codegen/var-names.rs b/tests/codegen/var-names.rs index 53841df32..d4715efad 100644 --- a/tests/codegen/var-names.rs +++ b/tests/codegen/var-names.rs @@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 { // CHECK: %c = add i32 %a, %b let d = c; let e = d * a; - // CHECK-NEXT: %0 = mul i32 %c, %a + // CHECK-NEXT: %e = mul i32 %c, %a e - // CHECK-NEXT: ret i32 %0 + // CHECK-NEXT: ret i32 %e } diff --git a/tests/codegen/vec-as-ptr.rs b/tests/codegen/vec-as-ptr.rs index 8ff7ba9cb..76098bc08 100644 --- a/tests/codegen/vec-as-ptr.rs +++ b/tests/codegen/vec-as-ptr.rs @@ -4,7 +4,7 @@ // Test that even though we return a *const u8 not a &[u8] or a NonNull<u8>, LLVM knows that this // pointer is nonnull. -// CHECK: nonnull {{i8\*|ptr}} @vec_as_ptr +// CHECK: nonnull ptr @vec_as_ptr #[no_mangle] pub fn vec_as_ptr(v: &Vec<u8>) -> *const u8 { v.as_ptr() @@ -12,7 +12,7 @@ pub fn vec_as_ptr(v: &Vec<u8>) -> *const u8 { // Test that even though we return a *const u8 not a &[u8] or a NonNull<u8>, LLVM knows that this // pointer is nonnull. -// CHECK: nonnull {{i8\*|ptr}} @vec_as_mut_ptr +// CHECK: nonnull ptr @vec_as_mut_ptr #[no_mangle] pub fn vec_as_mut_ptr(v: &mut Vec<u8>) -> *mut u8 { v.as_mut_ptr() diff --git a/tests/codegen/vec-calloc-llvm14.rs b/tests/codegen/vec-calloc-llvm14.rs deleted file mode 100644 index 08302796c..000000000 --- a/tests/codegen/vec-calloc-llvm14.rs +++ /dev/null @@ -1,144 +0,0 @@ -// compile-flags: -O -// only-x86_64 -// ignore-debug - -#![crate_type = "lib"] - -// CHECK-LABEL: @vec_zero_bytes -#[no_mangle] -pub fn vec_zero_bytes(n: usize) -> Vec<u8> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - // CHECK-NOT: call {{.*}}llvm.memset - - // CHECK: call {{.*}}__rust_alloc_zeroed( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - // CHECK-NOT: call {{.*}}llvm.memset - - // CHECK: ret void - vec![0; n] -} - -// CHECK-LABEL: @vec_one_bytes -#[no_mangle] -pub fn vec_one_bytes(n: usize) -> Vec<u8> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: call {{.*}}__rust_alloc( - // CHECK: call {{.*}}llvm.memset - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: ret void - vec![1; n] -} - -// CHECK-LABEL: @vec_zero_scalar -#[no_mangle] -pub fn vec_zero_scalar(n: usize) -> Vec<i32> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: call {{.*}}__rust_alloc_zeroed( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: ret void - vec![0; n] -} - -// CHECK-LABEL: @vec_one_scalar -#[no_mangle] -pub fn vec_one_scalar(n: usize) -> Vec<i32> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: call {{.*}}__rust_alloc( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: ret void - vec![1; n] -} - -// CHECK-LABEL: @vec_zero_rgb48 -#[no_mangle] -pub fn vec_zero_rgb48(n: usize) -> Vec<[u16; 3]> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: call {{.*}}__rust_alloc_zeroed( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: ret void - vec![[0, 0, 0]; n] -} - -// CHECK-LABEL: @vec_zero_array_16 -#[no_mangle] -pub fn vec_zero_array_16(n: usize) -> Vec<[i64; 16]> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: call {{.*}}__rust_alloc_zeroed( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: ret void - vec![[0_i64; 16]; n] -} - -// CHECK-LABEL: @vec_zero_tuple -#[no_mangle] -pub fn vec_zero_tuple(n: usize) -> Vec<(i16, u8, char)> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: call {{.*}}__rust_alloc_zeroed( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc( - - // CHECK: ret void - vec![(0, 0, '\0'); n] -} - -// CHECK-LABEL: @vec_non_zero_tuple -#[no_mangle] -pub fn vec_non_zero_tuple(n: usize) -> Vec<(i16, u8, char)> { - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: call {{.*}}__rust_alloc( - - // CHECK-NOT: call {{.*}}alloc::vec::from_elem - // CHECK-NOT: call {{.*}}reserve - // CHECK-NOT: call {{.*}}__rust_alloc_zeroed( - - // CHECK: ret void - vec![(0, 0, 'A'); n] -} diff --git a/tests/codegen/vec-calloc.rs b/tests/codegen/vec-calloc.rs index 4481a9d1e..a5fda7b24 100644 --- a/tests/codegen/vec-calloc.rs +++ b/tests/codegen/vec-calloc.rs @@ -1,7 +1,6 @@ // compile-flags: -O -Z merge-functions=disabled // only-x86_64 // ignore-debug -// min-llvm-version: 15.0 #![crate_type = "lib"] diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs new file mode 100644 index 000000000..2b2359f5b --- /dev/null +++ b/tests/codegen/wasm_exceptions.rs @@ -0,0 +1,51 @@ +// only-wasm32-bare +// compile-flags: -C panic=unwind + +#![crate_type = "lib"] +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +extern { + fn may_panic(); + + #[rustc_nounwind] + fn log_number(number: usize); +} + +struct LogOnDrop; + +impl Drop for LogOnDrop { + fn drop(&mut self) { + unsafe { log_number(0); } + } +} + +// CHECK-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 +#[no_mangle] +pub fn test_cleanup() { + let _log_on_drop = LogOnDrop; + unsafe { may_panic(); } + + // CHECK-NOT: call + // CHECK: invoke void @may_panic() + // CHECK: %cleanuppad = cleanuppad within none [] +} + +// CHECK-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 +#[no_mangle] +pub fn test_rtry() { + unsafe { + core::intrinsics::r#try(|_| { + may_panic(); + }, core::ptr::null_mut(), |data, exception| { + log_number(data as usize); + log_number(exception as usize); + }); + } + + // CHECK-NOT: call + // CHECK: invoke void @may_panic() + // CHECK: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller + // CHECK: {{.*}} = catchpad within {{.*}} [ptr null] + // CHECK: catchret +} |