diff options
Diffstat (limited to 'tests/codegen-llvm')
40 files changed, 924 insertions, 103 deletions
diff --git a/tests/codegen-llvm/asm/powerpc-clobbers.rs b/tests/codegen-llvm/asm/powerpc-clobbers.rs index f7fc7eea5d5..10d7ae4dba4 100644 --- a/tests/codegen-llvm/asm/powerpc-clobbers.rs +++ b/tests/codegen-llvm/asm/powerpc-clobbers.rs @@ -58,10 +58,10 @@ pub unsafe fn v0_clobber() { // Output format depends on the availability of altivec. // CHECK-LABEL: @clobber_abi -// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() #[no_mangle] pub unsafe fn clobber_abi() { asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); diff --git a/tests/codegen-llvm/asm/readonly-not-pure.rs b/tests/codegen-llvm/asm/readonly-not-pure.rs new file mode 100644 index 00000000000..a3c0e276c7f --- /dev/null +++ b/tests/codegen-llvm/asm/readonly-not-pure.rs @@ -0,0 +1,48 @@ +//@ add-core-stubs +//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 + +#![crate_type = "rlib"] +#![feature(no_core)] +#![no_core] + +// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed +// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes, +// but it may have side-effects. + +extern crate minicore; +use minicore::*; + +pub static mut VAR: i32 = 0; + +// CHECK-LABEL: @no_options +// CHECK: call i32 asm +#[no_mangle] +pub unsafe fn no_options() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored); + VAR +} + +// CHECK-LABEL: @readonly_pure +// CHECK-NOT: call i32 asm +#[no_mangle] +pub unsafe fn readonly_pure() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly)); + VAR +} + +// CHECK-LABEL: @readonly_not_pure +// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]] +#[no_mangle] +pub unsafe fn readonly_not_pure() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored, options(readonly)); + VAR +} + +// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) } diff --git a/tests/codegen-llvm/asm/riscv-clobbers.rs b/tests/codegen-llvm/asm/riscv-clobbers.rs index e55b6731098..0f235ddcdcc 100644 --- a/tests/codegen-llvm/asm/riscv-clobbers.rs +++ b/tests/codegen-llvm/asm/riscv-clobbers.rs @@ -17,7 +17,7 @@ extern crate minicore; use minicore::*; // CHECK-LABEL: @flags_clobber -// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"() +// CHECK: call void asm sideeffect "", "~{fflags},~{vtype},~{vl},~{vxsat},~{vxrm}"() #[no_mangle] pub unsafe fn flags_clobber() { asm!("", options(nostack, nomem)); diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs new file mode 100644 index 00000000000..454ec698b91 --- /dev/null +++ b/tests/codegen-llvm/autodiff/abi_handling.rs @@ -0,0 +1,210 @@ +//@ revisions: debug release + +//@[debug] compile-flags: -Zautodiff=Enable -C opt-level=0 -Clto=fat +//@[release] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// This test checks that Rust types are lowered to LLVM-IR types in a way +// we expect and Enzyme can handle. We explicitly check release mode to +// ensure that LLVM's O3 pipeline doesn't rewrite function signatures +// into forms that Enzyme can't process correctly. + +#![feature(autodiff)] + +use std::autodiff::{autodiff_forward, autodiff_reverse}; + +#[derive(Copy, Clone)] +struct Input { + x: f32, + y: f32, +} + +#[derive(Copy, Clone)] +struct Wrapper { + z: f32, +} + +#[derive(Copy, Clone)] +struct NestedInput { + x: f32, + y: Wrapper, +} + +fn square(x: f32) -> f32 { + x * x +} + +// CHECK-LABEL: ; abi_handling::df1 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0) +// release-NEXT: define internal fastcc float +// release-SAME: (float %x.0.val, float %x.4.val) + +// CHECK-LABEL: ; abi_handling::f1 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.val, float %x.4.val) +#[autodiff_forward(df1, Dual, Dual)] +#[inline(never)] +fn f1(x: &[f32; 2]) -> f32 { + x[0] + x[1] +} + +// CHECK-LABEL: ; abi_handling::df2 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr %f, float %x, float %dret) +// release-NEXT: define internal fastcc float +// release-SAME: (float noundef %x) + +// CHECK-LABEL: ; abi_handling::f2 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr %f, float %x) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %x) +#[autodiff_reverse(df2, Const, Active, Active)] +#[inline(never)] +fn f2(f: fn(f32) -> f32, x: f32) -> f32 { + f(x) +} + +// CHECK-LABEL: ; abi_handling::df3 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float %x.0.val) + +// CHECK-LABEL: ; abi_handling::f3 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x, ptr align 4 %y) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.val) +#[autodiff_forward(df3, Dual, Dual, Dual)] +#[inline(never)] +fn f3<'a>(x: &'a f32, y: &'a f32) -> f32 { + *x * *y +} + +// CHECK-LABEL: ; abi_handling::df4 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %x.0, float %x.1, float %bx_0.0, float %bx_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float noundef %x.0, float noundef %x.1) + +// CHECK-LABEL: ; abi_handling::f4 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %x.0, float %x.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %x.0, float noundef %x.1) +#[autodiff_forward(df4, Dual, Dual)] +#[inline(never)] +fn f4(x: (f32, f32)) -> f32 { + x.0 * x.1 +} + +// CHECK-LABEL: ; abi_handling::df5 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float noundef %i.0, float noundef %i.1) + +// CHECK-LABEL: ; abi_handling::f5 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %i.0, float %i.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %i.0, float noundef %i.1) +#[autodiff_forward(df5, Dual, Dual)] +#[inline(never)] +fn f5(i: Input) -> f32 { + i.x + i.y +} + +// CHECK-LABEL: ; abi_handling::df6 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: float noundef %i.0, float noundef %i.1 +// release-SAME: float noundef %bi_0.0, float noundef %bi_0.1 + +// CHECK-LABEL: ; abi_handling::f6 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %i.0, float %i.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %i.0, float noundef %i.1) +#[autodiff_forward(df6, Dual, Dual)] +#[inline(never)] +fn f6(i: NestedInput) -> f32 { + i.x + i.y.z * i.y.z +} + +// CHECK-LABEL: ; abi_handling::df7 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1, ptr align 4 %bx_0.0, ptr align 4 %bx_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float %x.0.0.val, float %x.1.0.val) + +// CHECK-LABEL: ; abi_handling::f7 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.0.val, float %x.1.0.val) +#[autodiff_forward(df7, Dual, Dual)] +#[inline(never)] +fn f7(x: (&f32, &f32)) -> f32 { + x.0 * x.1 +} + +fn main() { + let x = std::hint::black_box(2.0); + let y = std::hint::black_box(3.0); + let z = std::hint::black_box(4.0); + static Y: f32 = std::hint::black_box(3.2); + + let in_f1 = [x, y]; + dbg!(f1(&in_f1)); + let res_f1 = df1(&in_f1, &[1.0, 0.0]); + dbg!(res_f1); + + dbg!(f2(square, x)); + let res_f2 = df2(square, x, 1.0); + dbg!(res_f2); + + dbg!(f3(&x, &Y)); + let res_f3 = df3(&x, &Y, &1.0, &0.0); + dbg!(res_f3); + + let in_f4 = (x, y); + dbg!(f4(in_f4)); + let res_f4 = df4(in_f4, (1.0, 0.0)); + dbg!(res_f4); + + let in_f5 = Input { x, y }; + dbg!(f5(in_f5)); + let res_f5 = df5(in_f5, Input { x: 1.0, y: 0.0 }); + dbg!(res_f5); + + let in_f6 = NestedInput { x, y: Wrapper { z: y } }; + dbg!(f6(in_f6)); + let res_f6 = df6(in_f6, NestedInput { x, y: Wrapper { z } }); + dbg!(res_f6); + + let in_f7 = (&x, &y); + dbg!(f7(in_f7)); + let res_f7 = df7(in_f7, (&1.0, &0.0)); + dbg!(res_f7); +} diff --git a/tests/codegen-llvm/autodiff/typetree.rs b/tests/codegen-llvm/autodiff/typetree.rs new file mode 100644 index 00000000000..1cb0c2fb68b --- /dev/null +++ b/tests/codegen-llvm/autodiff/typetree.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// Test that basic autodiff still works with our TypeTree infrastructure +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_simple, Duplicated, Active)] +#[no_mangle] +#[inline(never)] +fn simple(x: &f64) -> f64 { + 2.0 * x +} + +// CHECK-LABEL: @simple +// CHECK: fmul double + +// The derivative function should be generated normally +// CHECK-LABEL: diffesimple +// CHECK: fadd fast double + +fn main() { + let x = std::hint::black_box(3.0); + let output = simple(&x); + assert_eq!(6.0, output); + + let mut df_dx = 0.0; + let output_ = d_simple(&x, &mut df_dx, 1.0); + assert_eq!(output, output_); + assert_eq!(2.0, df_dx); +} diff --git a/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs new file mode 100644 index 00000000000..3c35d003c8a --- /dev/null +++ b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs @@ -0,0 +1,27 @@ +#![crate_type = "lib"] +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +#[link(name = "Foundation", kind = "framework")] +unsafe extern "C" {} + +#[inline(always)] +pub fn inline_get_object_class() -> objc::Class { + objc::class!("NSObject") +} + +#[inline(always)] +pub fn inline_get_alloc_selector() -> objc::SEL { + objc::selector!("alloc") +} + +#[inline(never)] +pub fn never_inline_get_string_class() -> objc::Class { + objc::class!("NSString") +} + +#[inline(never)] +pub fn never_inline_get_init_selector() -> objc::SEL { + objc::selector!("init") +} diff --git a/tests/codegen-llvm/branch-protection.rs b/tests/codegen-llvm/branch-protection.rs index d67e494cc0d..f92259c941c 100644 --- a/tests/codegen-llvm/branch-protection.rs +++ b/tests/codegen-llvm/branch-protection.rs @@ -1,9 +1,10 @@ // Test that the correct module flags are emitted with different branch protection flags. //@ add-core-stubs -//@ revisions: BTI PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE +//@ revisions: BTI GCS PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE //@ needs-llvm-components: aarch64 //@ [BTI] compile-flags: -Z branch-protection=bti +//@ [GCS] compile-flags: -Z branch-protection=gcs //@ [PACRET] compile-flags: -Z branch-protection=pac-ret //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key @@ -32,6 +33,9 @@ pub fn test() {} // BTI: !"sign-return-address-all", i32 0 // BTI: !"sign-return-address-with-bkey", i32 0 +// GCS: attributes [[ATTR]] = {{.*}} "guarded-control-stack" +// GCS: !"guarded-control-stack", i32 1 + // PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" // PACRET-SAME: "sign-return-address-key"="a_key" // PACRET: !"branch-target-enforcement", i32 0 diff --git a/tests/codegen-llvm/c-variadic-lifetime.rs b/tests/codegen-llvm/c-variadic-lifetime.rs index 5b2f8af18c8..c6d3602ef51 100644 --- a/tests/codegen-llvm/c-variadic-lifetime.rs +++ b/tests/codegen-llvm/c-variadic-lifetime.rs @@ -8,7 +8,7 @@ #[unsafe(no_mangle)] unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { - // CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args) + // CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args) // CHECK: call void @llvm.va_start.p0(ptr nonnull %args) let b = args.arg::<f64>(); @@ -17,5 +17,5 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { a + b + c // CHECK: call void @llvm.va_end.p0(ptr nonnull %args) - // CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args) + // CHECK: call void @llvm.lifetime.end.p0({{(i64 [0-9]+, )?}}ptr nonnull %args) } diff --git a/tests/codegen-llvm/cffi/c-variadic-inline.rs b/tests/codegen-llvm/cffi/c-variadic-inline.rs new file mode 100644 index 00000000000..369b7e571ca --- /dev/null +++ b/tests/codegen-llvm/cffi/c-variadic-inline.rs @@ -0,0 +1,47 @@ +//@ compile-flags: -C opt-level=3 +#![feature(c_variadic)] + +// Test that the inline attributes are accepted on C-variadic functions. +// +// Currently LLVM is unable to inline C-variadic functions, but that is valid because despite +// the name even `#[inline(always)]` is just a hint. + +#[inline(always)] +unsafe extern "C" fn inline_always(mut ap: ...) -> u32 { + ap.arg::<u32>() +} + +#[inline] +unsafe extern "C" fn inline(mut ap: ...) -> u32 { + ap.arg::<u32>() +} + +#[inline(never)] +unsafe extern "C" fn inline_never(mut ap: ...) -> u32 { + ap.arg::<u32>() +} + +#[cold] +unsafe extern "C" fn cold(mut ap: ...) -> u32 { + ap.arg::<u32>() +} + +#[unsafe(no_mangle)] +#[inline(never)] +fn helper() { + // CHECK-LABEL: helper + // CHECK-LABEL: call c_variadic_inline::inline_always + // CHECK-LABEL: call c_variadic_inline::inline + // CHECK-LABEL: call c_variadic_inline::inline_never + // CHECK-LABEL: call c_variadic_inline::cold + unsafe { + inline_always(1); + inline(2); + inline_never(3); + cold(4); + } +} + +fn main() { + helper() +} diff --git a/tests/codegen-llvm/comparison-operators-2-struct.rs b/tests/codegen-llvm/comparison-operators-2-struct.rs index e179066ebfd..d44f92f511b 100644 --- a/tests/codegen-llvm/comparison-operators-2-struct.rs +++ b/tests/codegen-llvm/comparison-operators-2-struct.rs @@ -1,5 +1,4 @@ //@ compile-flags: -C opt-level=1 -//@ min-llvm-version: 20 // The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`. // This double-checks that the `Option<Ordering>` intermediate values used diff --git a/tests/codegen-llvm/comparison-operators-2-tuple.rs b/tests/codegen-llvm/comparison-operators-2-tuple.rs index 6a7e489c82d..37a7c5dfdaf 100644 --- a/tests/codegen-llvm/comparison-operators-2-tuple.rs +++ b/tests/codegen-llvm/comparison-operators-2-tuple.rs @@ -1,5 +1,4 @@ //@ compile-flags: -C opt-level=1 -Z merge-functions=disabled -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/darwin-no-objc.rs b/tests/codegen-llvm/darwin-no-objc.rs new file mode 100644 index 00000000000..fda3671fb6d --- /dev/null +++ b/tests/codegen-llvm/darwin-no-objc.rs @@ -0,0 +1,52 @@ +// Test that we don't generate Objective-C definitions or image info unnecessarily. + +//@ add-core-stubs +//@ revisions: i686_apple_darwin +//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin +//@ [i686_apple_darwin] needs-llvm-components: x86 +//@ revisions: x86_64_macos +//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin +//@ [x86_64_macos] needs-llvm-components: x86 +//@ revisions: aarch64_macos +//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin +//@ [aarch64_macos] needs-llvm-components: aarch64 +//@ revisions: i386_ios +//@ [i386_ios] compile-flags: --target i386-apple-ios +//@ [i386_ios] needs-llvm-components: x86 +//@ revisions: x86_64_ios +//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios +//@ [x86_64_ios] needs-llvm-components: x86 +//@ revisions: armv7s_ios +//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios +//@ [armv7s_ios] needs-llvm-components: arm +//@ revisions: aarch64_ios +//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios +//@ [aarch64_ios] needs-llvm-components: aarch64 +//@ revisions: aarch64_ios_sim +//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim +//@ [aarch64_ios_sim] needs-llvm-components: aarch64 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn foo() {} + +// CHECK-NOT: %struct._class_t +// CHECK-NOT: %struct._objc_module +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @"OBJC_CLASS_$_{{[0-9A-Z_a-z]+}}" +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ +// CHECK-NOT: @OBJC_MODULES + +// CHECK-NOT: !"Objective-C Version" +// CHECK-NOT: !"Objective-C Image Info Version" +// CHECK-NOT: !"Objective-C Image Info Section" +// CHECK-NOT: !"Objective-C Is Simulated" +// CHECK-NOT: !"Objective-C Class Properties" diff --git a/tests/codegen-llvm/darwin-objc-abi-v1.rs b/tests/codegen-llvm/darwin-objc-abi-v1.rs new file mode 100644 index 00000000000..0fc1de9332a --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-abi-v1.rs @@ -0,0 +1,100 @@ +// ignore-tidy-linelength +//@ add-core-stubs +//@ revisions: i686_apple_darwin +//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin +//@ [i686_apple_darwin] needs-llvm-components: x86 + +#![crate_type = "lib"] +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn get_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_class_again() -> *mut () { + // Codegen should de-duplicate this class with the one from get_class above. + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector_again() -> *mut () { + // Codegen should de-duplicate this selector with the one from get_selector above. + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "OtherClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "otherMethod"] + safe static VAL: *mut (); + } + VAL +} + +// CHECK: %struct._objc_module = type { i32, i32, ptr, ptr } + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [8 x i8] c"MyClass\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4 +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @OBJC_CLASS_REFERENCES_ + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [11 x i8] c"OtherClass\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_MODULES = private global %struct._objc_module { i32 7, i32 16, ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, ptr null }, section "__OBJC,__module_info,regular,no_dead_strip", align 4 + +// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"} +// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/darwin-objc-abi-v2.rs b/tests/codegen-llvm/darwin-objc-abi-v2.rs new file mode 100644 index 00000000000..f142371d582 --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-abi-v2.rs @@ -0,0 +1,185 @@ +// ignore-tidy-linelength +//@ add-core-stubs +//@ revisions: x86_64_macos +//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin +//@ [x86_64_macos] needs-llvm-components: x86 +//@ revisions: aarch64_macos +//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin +//@ [aarch64_macos] needs-llvm-components: aarch64 +//@ revisions: i386_ios +//@ [i386_ios] compile-flags: --target i386-apple-ios +//@ [i386_ios] needs-llvm-components: x86 +//@ revisions: x86_64_ios +//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios +//@ [x86_64_ios] needs-llvm-components: x86 +//@ revisions: armv7s_ios +//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios +//@ [armv7s_ios] needs-llvm-components: arm +//@ revisions: aarch64_ios +//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios +//@ [aarch64_ios] needs-llvm-components: aarch64 +//@ revisions: aarch64_ios_sim +//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim +//@ [aarch64_ios_sim] needs-llvm-components: aarch64 + +#![crate_type = "lib"] +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn get_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_class_again() -> *mut () { + // Codegen should de-duplicate this class with the one from get_class above. + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector_again() -> *mut () { + // Codegen should de-duplicate this selector with the one from get_selector above. + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "OtherClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "otherMethod"] + safe static VAL: *mut (); + } + VAL +} + +// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr } + +// CHECK: @"OBJC_CLASS_$_MyClass" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 +// CHECK-NOT: @"OBJC_CLASS_$_MyClass" +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_ + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ + +// CHECK: @"OBJC_CLASS_$_OtherClass" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_OtherClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @OBJC_MODULES + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} + +// x86_64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// i386_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// x86_64_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// armv7s_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_ios_sim: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/darwin-objc-cross-crate.rs b/tests/codegen-llvm/darwin-objc-cross-crate.rs new file mode 100644 index 00000000000..74ad9a27346 --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-cross-crate.rs @@ -0,0 +1,58 @@ +// Test that Objective-C class and selector references inlined across crates +// get defined in this CGU but non-inline references don't. + +// ignore-tidy-linelength +//@ aux-build: darwin_objc_aux.rs +//@ revisions: x86_64_macos aarch64_macos +//@ [x86_64_macos] only-x86_64-apple-darwin +//@ [aarch64_macos] only-aarch64-apple-darwin + +#![crate_type = "lib"] +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +extern crate darwin_objc_aux as aux; + +#[no_mangle] +pub fn get_object_class() -> objc::Class { + aux::inline_get_object_class() +} + +#[no_mangle] +pub fn get_alloc_selector() -> objc::SEL { + aux::inline_get_alloc_selector() +} + +#[no_mangle] +pub fn get_string_class() -> objc::Class { + aux::never_inline_get_string_class() +} + +#[no_mangle] +pub fn get_init_selector() -> objc::SEL { + aux::never_inline_get_init_selector() +} + +// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr } + +// CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSObject", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [6 x i8] c"alloc\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 + +// CHECK-NOT: @"OBJC_CLASS_$_NSString" = external global %struct._class_t +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSString" + +// CHECK-NOT: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [5 x i8] c"init\00" +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}} + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", align 8 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 8 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} +// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs index f58d7ef12b6..7d450a89e2e 100644 --- a/tests/codegen-llvm/enum/enum-aggregate.rs +++ b/tests/codegen-llvm/enum/enum-aggregate.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -//@ min-llvm-version: 19 //@ only-64bit #![crate_type = "lib"] diff --git a/tests/codegen-llvm/enum/enum-discriminant-eq.rs b/tests/codegen-llvm/enum/enum-discriminant-eq.rs index a1ab5e5c6e2..68cd58643e8 100644 --- a/tests/codegen-llvm/enum/enum-discriminant-eq.rs +++ b/tests/codegen-llvm/enum/enum-discriminant-eq.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled -//@ min-llvm-version: 20 //@ only-64bit //@ revisions: LLVM20 LLVM21 //@ [LLVM21] min-llvm-version: 21 diff --git a/tests/codegen-llvm/global-allocator-attributes.rs b/tests/codegen-llvm/global-allocator-attributes.rs new file mode 100644 index 00000000000..472ca772075 --- /dev/null +++ b/tests/codegen-llvm/global-allocator-attributes.rs @@ -0,0 +1,41 @@ +//@ compile-flags: -C opt-level=3 +#![crate_type = "lib"] + +mod foobar { + use std::alloc::{GlobalAlloc, Layout}; + + struct Allocator; + + unsafe impl GlobalAlloc for Allocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_alloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,uninitialized,aligned") allocsize(0){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc(i[[SIZE:[0-9]+]] {{.*}}%size, i[[SIZE]] allocalign{{.*}} %align) + panic!() + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + // CHECK-LABEL: ; __rustc::__rust_dealloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("free"){{.*}} + // CHECK-NEXT: define{{.*}} void @{{.*}}__rust_dealloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] {{.*}} %align) + panic!() + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_realloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("realloc,aligned") allocsize(3){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_realloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align, i[[SIZE]] {{.*}} %new_size) + panic!() + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_alloc_zeroed + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,zeroed,aligned") allocsize(0){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc_zeroed(i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align) + panic!() + } + } + + #[global_allocator] + static GLOBAL: Allocator = Allocator; +} diff --git a/tests/codegen-llvm/integer-cmp.rs b/tests/codegen-llvm/integer-cmp.rs index 812fa8e4a42..2233a575f8e 100644 --- a/tests/codegen-llvm/integer-cmp.rs +++ b/tests/codegen-llvm/integer-cmp.rs @@ -1,9 +1,6 @@ // This is test for more optimal Ord implementation for integers. // See <https://github.com/rust-lang/rust/issues/63758> for more info. -//@ revisions: llvm-pre-20 llvm-20 -//@ [llvm-20] min-llvm-version: 20 -//@ [llvm-pre-20] max-llvm-major-version: 19 //@ compile-flags: -C opt-level=3 -Zmerge-functions=disabled #![crate_type = "lib"] @@ -13,50 +10,29 @@ use std::cmp::Ordering; // CHECK-LABEL: @cmp_signed #[no_mangle] pub fn cmp_signed(a: i64, b: i64) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.scmp.i8.i64 - // llvm-pre-20: icmp slt - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.scmp.i8.i64 a.cmp(&b) } // CHECK-LABEL: @cmp_unsigned #[no_mangle] pub fn cmp_unsigned(a: u32, b: u32) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32 a.cmp(&b) } // CHECK-LABEL: @cmp_char #[no_mangle] pub fn cmp_char(a: char, b: char) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32 a.cmp(&b) } // CHECK-LABEL: @cmp_tuple #[no_mangle] pub fn cmp_tuple(a: (i16, u16), b: (i16, u16)) -> Ordering { - // llvm-20-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16 - // llvm-20-DAG: call{{.*}} i8 @llvm.scmp.i8.i16 - // llvm-20: ret i8 - // llvm-pre-20: icmp slt - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 - // llvm-pre-20: select i1 + // CHECK-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16 + // CHECK-DAG: call{{.*}} i8 @llvm.scmp.i8.i16 + // CHECK: ret i8 a.cmp(&b) } diff --git a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs index 4bec579831d..255f20e6ff6 100644 --- a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs +++ b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs @@ -7,7 +7,5 @@ use std::intrinsics::sqrtf32; // CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}} fn main() { - unsafe { - sqrtf32(0.0f32); - } + sqrtf32(0.0f32); } diff --git a/tests/codegen-llvm/intrinsics/three_way_compare.rs b/tests/codegen-llvm/intrinsics/three_way_compare.rs index 95fcb636f7c..89bf69561e9 100644 --- a/tests/codegen-llvm/intrinsics/three_way_compare.rs +++ b/tests/codegen-llvm/intrinsics/three_way_compare.rs @@ -2,7 +2,6 @@ //@ [DEBUG] compile-flags: -C opt-level=0 //@ [OPTIM] compile-flags: -C opt-level=3 //@ compile-flags: -C no-prepopulate-passes -//@ min-llvm-version: 20 #![crate_type = "lib"] #![feature(core_intrinsics)] diff --git a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs index bdf021092fd..fc4b0341a31 100644 --- a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs +++ b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs new file mode 100644 index 00000000000..b97729fa146 --- /dev/null +++ b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 +//@ needs-deterministic-layouts + +// Currently Vec<T> and &[T] have layouts that start with (pointer, len) +// which makes the conversion branchless. +// A nice-to-have property, not guaranteed. +#![crate_type = "cdylib"] + +// CHECK-LABEL: @branchless_cow_slices +#[no_mangle] +pub fn branchless_cow_slices<'a>(cow: &'a std::borrow::Cow<'a, [u8]>) -> &'a [u8] { + // CHECK-NOT: br + // CHECK-NOT: select + // CHECK-NOT: icmp + // CHECK: ret { ptr, {{i32|i64}} } + &*cow +} diff --git a/tests/codegen-llvm/issues/issue-101082.rs b/tests/codegen-llvm/issues/issue-101082.rs index 8d15921ddb4..0c1f90f951a 100644 --- a/tests/codegen-llvm/issues/issue-101082.rs +++ b/tests/codegen-llvm/issues/issue-101082.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Copt-level=3 //@ revisions: host x86-64 x86-64-v3 -//@ min-llvm-version: 20 //@[host] ignore-x86_64 diff --git a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs index 853a1ff36b1..a0b453fac8e 100644 --- a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs +++ b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -22,8 +25,8 @@ pub unsafe fn update(s: *mut State) { // CHECK-NOT: memcpy // CHECK-NOT: 75{{3|4}} - // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1 - // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1 + // old: %[[TAG:.+]] = load i8, ptr %s, align 1 + // old-NEXT: trunc nuw i8 %[[TAG]] to i1 // CHECK-NOT: load // CHECK-NOT: store diff --git a/tests/codegen-llvm/issues/issue-129795.rs b/tests/codegen-llvm/issues/issue-129795.rs index dc64ee35c97..7a928389fab 100644 --- a/tests/codegen-llvm/issues/issue-129795.rs +++ b/tests/codegen-llvm/issues/issue-129795.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] // Ensure that a modulo operation with an operand that is known to be diff --git a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs index 4d3fa4993ef..4c4eebeabb5 100644 --- a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs +++ b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs @@ -3,7 +3,6 @@ // use a larger value to prevent unrolling. //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs index 35acf765d69..b686f8c4b3a 100644 --- a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs +++ b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] /// Ensure the function is properly optimized diff --git a/tests/codegen-llvm/option-niche-eq.rs b/tests/codegen-llvm/option-niche-eq.rs index 3900cb79aa2..e9c3fa2407e 100644 --- a/tests/codegen-llvm/option-niche-eq.rs +++ b/tests/codegen-llvm/option-niche-eq.rs @@ -1,5 +1,4 @@ //@ revisions: REGULAR LLVM21 -//@ min-llvm-version: 20 //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled //@ [LLVM21] min-llvm-version: 21 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/pattern_type_symbols.rs b/tests/codegen-llvm/pattern_type_symbols.rs index e86a9ef27de..a90262ff12d 100644 --- a/tests/codegen-llvm/pattern_type_symbols.rs +++ b/tests/codegen-llvm/pattern_type_symbols.rs @@ -16,7 +16,7 @@ pub fn bar() { // CHECK: call pattern_type_symbols::foo::<u32> // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_ foo::<u32>(); - // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999])> - // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_EEB2_ + // CHECK: call pattern_type_symbols::foo::<u32 is 0..=999999999> + // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooWmRm0_m3b9ac9ff_EB2_ foo::<NanoU32>(); } diff --git a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs index 561f081c700..ffff4b35994 100644 --- a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs +++ b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs @@ -1,15 +1,19 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes //@ revisions: riscv64 loongarch64 -//@[riscv64] only-riscv64 //@[riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu //@[riscv64] needs-llvm-components: riscv -//@[loongarch64] only-loongarch64 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch #![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; #[no_mangle] // riscv64: define noundef i8 @arg_attr_u8(i8 noundef zeroext %x) diff --git a/tests/codegen-llvm/slice-last-elements-optimization.rs b/tests/codegen-llvm/slice-last-elements-optimization.rs index d982cda709d..77fc1d21cd9 100644 --- a/tests/codegen-llvm/slice-last-elements-optimization.rs +++ b/tests/codegen-llvm/slice-last-elements-optimization.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] // This test verifies that LLVM 20 properly optimizes the bounds check diff --git a/tests/codegen-llvm/swap-small-types.rs b/tests/codegen-llvm/swap-small-types.rs index 7aa613ae9c2..0799ff76331 100644 --- a/tests/codegen-llvm/swap-small-types.rs +++ b/tests/codegen-llvm/swap-small-types.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled //@ only-x86_64 -//@ min-llvm-version: 20 //@ ignore-std-debug-assertions (`ptr::swap_nonoverlapping` has one which blocks some optimizations) #![crate_type = "lib"] diff --git a/tests/codegen-llvm/try_question_mark_nop.rs b/tests/codegen-llvm/try_question_mark_nop.rs index 398c9a580bc..a09fa0a4901 100644 --- a/tests/codegen-llvm/try_question_mark_nop.rs +++ b/tests/codegen-llvm/try_question_mark_nop.rs @@ -1,9 +1,6 @@ //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled //@ edition: 2021 //@ only-x86_64 -//@ revisions: NINETEEN TWENTY -//@[NINETEEN] exact-llvm-major-version: 19 -//@[TWENTY] min-llvm-version: 20 #![crate_type = "lib"] #![feature(try_blocks)] @@ -17,13 +14,9 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { // CHECK: start: // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 - // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %0, i32 0 - // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 [[SELECT]], 0 - // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 %1, 1 - - // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef - // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 - // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1 + // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 + // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1 // CHECK-NEXT: ret { i32, i32 } [[REG3]] match x { @@ -36,8 +29,8 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { #[no_mangle] pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> { // CHECK: start: - // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef + // CHECK-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // CHECK-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } @@ -96,13 +89,9 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> { // CHECK: start: // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i64 %0 to i1 - // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %0, i64 0 - // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 [[SELECT]], 0 - // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 %1, 1 - - // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef - // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0 - // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1 + // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0 + // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1 // CHECK-NEXT: ret { i64, i64 } [[REG3]] match x { @@ -115,8 +104,8 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> { #[no_mangle] pub fn option_nop_traits_64(x: Option<u64>) -> Option<u64> { // CHECK: start: - // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 - // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 + // CHECK-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: ret { i64, i64 } diff --git a/tests/codegen-llvm/union-aggregate.rs b/tests/codegen-llvm/union-aggregate.rs index aac66c5dcdd..7faa66804fe 100644 --- a/tests/codegen-llvm/union-aggregate.rs +++ b/tests/codegen-llvm/union-aggregate.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -//@ min-llvm-version: 19 //@ only-64bit #![crate_type = "lib"] diff --git a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs index 8d2745ba2f7..2ce1d1b2e00 100644 --- a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs +++ b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs @@ -1,4 +1,9 @@ //@ compile-flags: -C panic=abort +//@ revisions: NONWASM WASM WASMEXN +//@ [NONWASM] ignore-wasm32 +//@ [WASM] only-wasm32 +//@ [WASMEXN] only-wasm32 +//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling // Test that `nounwind` attributes are also applied to extern `C-unwind` Rust functions // when the code is compiled with `panic=abort`. @@ -9,7 +14,9 @@ #[no_mangle] pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() { // Handle both legacy and v0 symbol mangling. - // CHECK: call void @{{.*core9panicking19panic_cannot_unwind}} + // NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}} + // WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}} + // WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}} may_unwind(); } diff --git a/tests/codegen-llvm/unwind-and-panic-abort.rs b/tests/codegen-llvm/unwind-and-panic-abort.rs index 8efa140058a..c2838be00af 100644 --- a/tests/codegen-llvm/unwind-and-panic-abort.rs +++ b/tests/codegen-llvm/unwind-and-panic-abort.rs @@ -1,4 +1,9 @@ //@ compile-flags: -C panic=abort +//@ revisions: NONWASM WASM WASMEXN +//@ [NONWASM] ignore-wasm32 +//@ [WASM] only-wasm32 +//@ [WASMEXN] only-wasm32 +//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling #![crate_type = "lib"] @@ -9,7 +14,9 @@ extern "C-unwind" { // CHECK: Function Attrs:{{.*}}nounwind // CHECK-NEXT: define{{.*}}void @foo // Handle both legacy and v0 symbol mangling. -// CHECK: call void @{{.*core9panicking19panic_cannot_unwind}} +// NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}} +// WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}} +// WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}} #[no_mangle] pub unsafe extern "C" fn foo() { bar(); diff --git a/tests/codegen-llvm/vec_pop_push_noop.rs b/tests/codegen-llvm/vec_pop_push_noop.rs index 3e375219fe0..977c220b3ba 100644 --- a/tests/codegen-llvm/vec_pop_push_noop.rs +++ b/tests/codegen-llvm/vec_pop_push_noop.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -7,7 +10,7 @@ pub fn noop(v: &mut Vec<u8>) { // CHECK-NOT: grow_one // CHECK-NOT: call - // CHECK: tail call void @llvm.assume + // old: tail call void @llvm.assume // CHECK-NOT: grow_one // CHECK-NOT: call // CHECK: {{ret|[}]}} diff --git a/tests/codegen-llvm/vecdeque_pop_push.rs b/tests/codegen-llvm/vecdeque_pop_push.rs index 5afa1b2248b..6f9ad6674d6 100644 --- a/tests/codegen-llvm/vecdeque_pop_push.rs +++ b/tests/codegen-llvm/vecdeque_pop_push.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -8,7 +11,7 @@ use std::collections::VecDeque; // CHECK-LABEL: @noop_back( pub fn noop_back(v: &mut VecDeque<u8>) { // CHECK-NOT: grow - // CHECK: tail call void @llvm.assume + // old: tail call void @llvm.assume // CHECK-NOT: grow // CHECK: ret if let Some(x) = v.pop_back() { diff --git a/tests/codegen-llvm/wasm_exceptions.rs b/tests/codegen-llvm/wasm_exceptions.rs index 796b69b722b..e718f599a3c 100644 --- a/tests/codegen-llvm/wasm_exceptions.rs +++ b/tests/codegen-llvm/wasm_exceptions.rs @@ -1,8 +1,9 @@ //@ only-wasm32 -//@ compile-flags: -C panic=unwind -Z emscripten-wasm-eh +//@ revisions: WASM WASMEXN +//@ [WASMEXN] compile-flags: -C panic=unwind -Z emscripten-wasm-eh #![crate_type = "lib"] -#![feature(core_intrinsics, wasm_exception_handling_intrinsics)] +#![feature(core_intrinsics, wasm_exception_handling_intrinsics, link_llvm_intrinsics)] extern "C-unwind" { fn may_panic(); @@ -22,7 +23,8 @@ impl Drop for LogOnDrop { } } -// CHECK-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 +// WASM-LABEL: @test_cleanup() {{.*}} +// WASMEXN-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] pub fn test_cleanup() { let _log_on_drop = LogOnDrop; @@ -30,12 +32,16 @@ pub fn test_cleanup() { may_panic(); } - // CHECK-NOT: call - // CHECK: invoke void @may_panic() - // CHECK: %cleanuppad = cleanuppad within none [] + // WASMEXN-NOT: call + // WASMEXN: invoke void @may_panic() + // WASMEXN: %cleanuppad = cleanuppad within none [] + // + // WASM: call void @may_panic() + // WASM-NOT: invoke void @may_panic() } -// CHECK-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 +// WASM-LABEL: @test_rtry() {{.*}} +// WASMEXN-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] pub fn test_rtry() { unsafe { @@ -51,23 +57,40 @@ pub fn test_rtry() { ); } - // CHECK-NOT: call - // CHECK: invoke void @may_panic() - // CHECK: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller - // CHECK: {{.*}} = catchpad within {{.*}} [ptr null] - // CHECK: catchret + // WASMEXN-NOT: call + // WASMEXN: invoke void @may_panic() + // WASMEXN: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller + // WASMEXN: {{.*}} = catchpad within {{.*}} [ptr null] + // WASMEXN: catchret + + // WASM: call void @may_panic() + // WASM-NOT: invoke void @may_panic() + // WASM-NOT: catchswitch + // WASM-NOT: catchpad + // WASM-NOT: catchret } // Make sure the intrinsic is not inferred as nounwind. This is a regression test for #132416. -// CHECK-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0 +// +// Note that this test uses the raw `wasm_throw` intrinsic because the one from +// libstd was built with `-Cpanic=abort` and it's technically not valid to use +// when this crate is compiled with `-Cpanic=unwind`. +// +// WASMEXN-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] +#[cfg(wasmexn)] pub fn test_intrinsic() { let _log_on_drop = LogOnDrop; + + unsafe extern "C-unwind" { + #[link_name = "llvm.wasm.throw"] + fn wasm_throw(tag: i32, ptr: *mut u8) -> !; + } unsafe { - core::arch::wasm32::throw::<0>(core::ptr::null_mut()); + wasm_throw(0, core::ptr::null_mut()); } - // CHECK-NOT: call - // CHECK: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null) - // CHECK: %cleanuppad = cleanuppad within none [] + // WASMEXN-NOT: call + // WASMEXN: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null) + // WASMEXN: %cleanuppad = cleanuppad within none [] } |
