about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/align-fn.rs82
-rw-r--r--tests/codegen/function-arguments.rs9
-rw-r--r--tests/codegen/transmute-scalar.rs55
3 files changed, 110 insertions, 36 deletions
diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs
index 267da060240..90073ff3081 100644
--- a/tests/codegen/align-fn.rs
+++ b/tests/codegen/align-fn.rs
@@ -1,10 +1,10 @@
-//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
+//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Clink-dead-code
 
 #![crate_type = "lib"]
 #![feature(fn_align)]
 
 // CHECK: align 16
-#[no_mangle]
+#[unsafe(no_mangle)]
 #[align(16)]
 pub fn fn_align() {}
 
@@ -12,12 +12,12 @@ pub struct A;
 
 impl A {
     // CHECK: align 16
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     #[align(16)]
     pub fn method_align(self) {}
 
     // CHECK: align 16
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     #[align(16)]
     pub fn associated_fn() {}
 }
@@ -25,46 +25,94 @@ impl A {
 trait T: Sized {
     fn trait_fn() {}
 
-    // CHECK: align 32
-    #[align(32)]
     fn trait_method(self) {}
+
+    #[align(8)]
+    fn trait_method_inherit_low(self);
+
+    #[align(32)]
+    fn trait_method_inherit_high(self);
+
+    #[align(32)]
+    fn trait_method_inherit_default(self) {}
+
+    #[align(4)]
+    #[align(128)]
+    #[align(8)]
+    fn inherit_highest(self) {}
 }
 
 impl T for A {
-    // CHECK: align 16
-    #[no_mangle]
+    // CHECK-LABEL: trait_fn
+    // CHECK-SAME: align 16
+    #[unsafe(no_mangle)]
     #[align(16)]
     fn trait_fn() {}
 
-    // CHECK: align 16
-    #[no_mangle]
+    // CHECK-LABEL: trait_method
+    // CHECK-SAME: align 16
+    #[unsafe(no_mangle)]
     #[align(16)]
     fn trait_method(self) {}
-}
 
-impl T for () {}
+    // The prototype's align is ignored because the align here is higher.
+    // CHECK-LABEL: trait_method_inherit_low
+    // CHECK-SAME: align 16
+    #[unsafe(no_mangle)]
+    #[align(16)]
+    fn trait_method_inherit_low(self) {}
+
+    // The prototype's align is used because it is higher.
+    // CHECK-LABEL: trait_method_inherit_high
+    // CHECK-SAME: align 32
+    #[unsafe(no_mangle)]
+    #[align(16)]
+    fn trait_method_inherit_high(self) {}
+
+    // The prototype's align inherited.
+    // CHECK-LABEL: trait_method_inherit_default
+    // CHECK-SAME: align 32
+    #[unsafe(no_mangle)]
+    fn trait_method_inherit_default(self) {}
+
+    // The prototype's highest align inherited.
+    // CHECK-LABEL: inherit_highest
+    // CHECK-SAME: align 128
+    #[unsafe(no_mangle)]
+    #[align(32)]
+    #[align(64)]
+    fn inherit_highest(self) {}
+}
 
-pub fn foo() {
-    ().trait_method();
+trait HasDefaultImpl: Sized {
+    // CHECK-LABEL: inherit_from_default_method
+    // CHECK-LABEL: inherit_from_default_method
+    // CHECK-SAME: align 32
+    #[align(32)]
+    fn inherit_from_default_method(self) {}
 }
 
+pub struct InstantiateDefaultMethods;
+
+impl HasDefaultImpl for InstantiateDefaultMethods {}
+
 // CHECK-LABEL: align_specified_twice_1
 // CHECK-SAME: align 64
-#[no_mangle]
+#[unsafe(no_mangle)]
 #[align(32)]
 #[align(64)]
 pub fn align_specified_twice_1() {}
 
 // CHECK-LABEL: align_specified_twice_2
 // CHECK-SAME: align 128
-#[no_mangle]
+#[unsafe(no_mangle)]
 #[align(128)]
 #[align(32)]
 pub fn align_specified_twice_2() {}
 
 // CHECK-LABEL: align_specified_twice_3
 // CHECK-SAME: align 256
-#[no_mangle]
+#[unsafe(no_mangle)]
 #[align(32)]
 #[align(256)]
 pub fn align_specified_twice_3() {}
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index f0708a7a109..c8cd8526ae5 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
 #![crate_type = "lib"]
 #![feature(rustc_attrs)]
-#![feature(dyn_star)]
 #![feature(allocator_api)]
 
 use std::marker::PhantomPinned;
@@ -277,11 +276,3 @@ pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
 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)
-// 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]
-pub fn dyn_star(x: dyn* Drop) -> dyn* Drop {
-    x
-}
diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs
index c57ade58c30..3ac6ba3beb1 100644
--- a/tests/codegen/transmute-scalar.rs
+++ b/tests/codegen/transmute-scalar.rs
@@ -1,6 +1,12 @@
+//@ add-core-stubs
 //@ compile-flags: -C opt-level=0 -C no-prepopulate-passes
 
 #![crate_type = "lib"]
+#![feature(no_core, repr_simd, arm_target_feature, mips_target_feature, s390x_target_feature)]
+#![no_core]
+extern crate minicore;
+
+use minicore::*;
 
 // With opaque ptrs in LLVM, `transmute` can load/store any `alloca` as any type,
 // without needing to pointercast, and SRoA will turn that into a `bitcast`.
@@ -14,7 +20,7 @@
 // CHECK-NEXT: ret i32 %_0
 #[no_mangle]
 pub fn f32_to_bits(x: f32) -> u32 {
-    unsafe { std::mem::transmute(x) }
+    unsafe { mem::transmute(x) }
 }
 
 // CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b)
@@ -22,7 +28,7 @@ pub fn f32_to_bits(x: f32) -> u32 {
 // CHECK-NEXT: ret i8 %_0
 #[no_mangle]
 pub fn bool_to_byte(b: bool) -> u8 {
-    unsafe { std::mem::transmute(b) }
+    unsafe { mem::transmute(b) }
 }
 
 // CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8{{.*}} %byte)
@@ -30,14 +36,14 @@ pub fn bool_to_byte(b: bool) -> u8 {
 // CHECK-NEXT: ret i1 %_0
 #[no_mangle]
 pub unsafe fn byte_to_bool(byte: u8) -> bool {
-    std::mem::transmute(byte)
+    mem::transmute(byte)
 }
 
 // CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr %p)
 // CHECK: ret ptr %p
 #[no_mangle]
 pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
-    unsafe { std::mem::transmute(p) }
+    unsafe { mem::transmute(p) }
 }
 
 // CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p)
@@ -45,7 +51,7 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
 // CHECK-NEXT: ret [[USIZE]] %_0
 #[no_mangle]
 pub fn ptr_to_int(p: *mut u16) -> usize {
-    unsafe { std::mem::transmute(p) }
+    unsafe { mem::transmute(p) }
 }
 
 // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i)
@@ -53,7 +59,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize {
 // CHECK-NEXT: ret ptr %_0
 #[no_mangle]
 pub fn int_to_ptr(i: usize) -> *mut u16 {
-    unsafe { std::mem::transmute(i) }
+    unsafe { mem::transmute(i) }
 }
 
 // This is the one case where signedness matters to transmuting:
@@ -70,7 +76,7 @@ pub enum FakeBoolSigned {
 // CHECK-NEXT: ret i8 %_0
 #[no_mangle]
 pub fn bool_to_fake_bool_signed(b: bool) -> FakeBoolSigned {
-    unsafe { std::mem::transmute(b) }
+    unsafe { mem::transmute(b) }
 }
 
 // CHECK-LABEL: define{{.*}}i1 @fake_bool_signed_to_bool(i8 %b)
@@ -78,7 +84,7 @@ pub fn bool_to_fake_bool_signed(b: bool) -> FakeBoolSigned {
 // CHECK-NEXT: ret i1 %_0
 #[no_mangle]
 pub fn fake_bool_signed_to_bool(b: FakeBoolSigned) -> bool {
-    unsafe { std::mem::transmute(b) }
+    unsafe { mem::transmute(b) }
 }
 
 #[repr(u8)]
@@ -91,12 +97,41 @@ pub enum FakeBoolUnsigned {
 // CHECK: ret i1 %b
 #[no_mangle]
 pub fn bool_to_fake_bool_unsigned(b: bool) -> FakeBoolUnsigned {
-    unsafe { std::mem::transmute(b) }
+    unsafe { mem::transmute(b) }
 }
 
 // CHECK-LABEL: define{{.*}}i1 @fake_bool_unsigned_to_bool(i1 zeroext %b)
 // CHECK: ret i1 %b
 #[no_mangle]
 pub fn fake_bool_unsigned_to_bool(b: FakeBoolUnsigned) -> bool {
-    unsafe { std::mem::transmute(b) }
+    unsafe { mem::transmute(b) }
+}
+
+#[repr(simd)]
+struct S([i64; 1]);
+
+// CHECK-LABEL: define{{.*}}i64 @single_element_simd_to_scalar(<1 x i64> %b)
+// CHECK: bitcast <1 x i64> %b to i64
+// CHECK: ret i64
+#[no_mangle]
+#[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
+#[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
+#[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+pub extern "C" fn single_element_simd_to_scalar(b: S) -> i64 {
+    unsafe { mem::transmute(b) }
+}
+
+// CHECK-LABEL: define{{.*}}<1 x i64> @scalar_to_single_element_simd(i64 %b)
+// CHECK: bitcast i64 %b to <1 x i64>
+// CHECK: ret <1 x i64>
+#[no_mangle]
+#[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
+#[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
+#[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
+#[cfg_attr(target_arch = "s390x", target_feature(enable = "vector"))]
+pub extern "C" fn scalar_to_single_element_simd(b: i64) -> S {
+    unsafe { mem::transmute(b) }
 }