about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/arg-return-value-in-reg.rs (renamed from src/test/codegen/return-value-in-reg.rs)4
-rw-r--r--src/test/codegen/dllimports/main.rs1
-rw-r--r--src/test/codegen/enum-discriminant-value.rs8
-rw-r--r--src/test/codegen/fewer-names.rs20
-rw-r--r--src/test/codegen/inline-hint.rs31
-rw-r--r--src/test/codegen/issue-56927.rs1
-rw-r--r--src/test/codegen/naked-functions.rs54
-rw-r--r--src/test/codegen/naked-noinline.rs30
-rw-r--r--src/test/codegen/panic-abort-windows.rs1
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs47
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs44
-rw-r--r--src/test/codegen/to_vec.rs10
-rw-r--r--src/test/codegen/transmute-scalar.rs85
-rw-r--r--src/test/codegen/union-abi.rs11
14 files changed, 286 insertions, 61 deletions
diff --git a/src/test/codegen/return-value-in-reg.rs b/src/test/codegen/arg-return-value-in-reg.rs
index 4bc0136c5e3..a69291d4782 100644
--- a/src/test/codegen/return-value-in-reg.rs
+++ b/src/test/codegen/arg-return-value-in-reg.rs
@@ -1,4 +1,4 @@
-//! This test checks that types of up to 128 bits are returned by-value instead of via out-pointer.
+//! Check that types of up to 128 bits are passed and returned by-value instead of via pointer.
 
 // compile-flags: -C no-prepopulate-passes -O
 // only-x86_64
@@ -11,7 +11,7 @@ pub struct S {
     c: u32,
 }
 
-// CHECK: define i128 @modify(%S* noalias nocapture dereferenceable(16) %s)
+// CHECK: define i128 @modify(i128{{( %0)?}})
 #[no_mangle]
 pub fn modify(s: S) -> S {
     S { a: s.a + s.a, b: s.b + s.b, c: s.c + s.c }
diff --git a/src/test/codegen/dllimports/main.rs b/src/test/codegen/dllimports/main.rs
index 73631b92c1f..bb3134e81c9 100644
--- a/src/test/codegen/dllimports/main.rs
+++ b/src/test/codegen/dllimports/main.rs
@@ -1,6 +1,5 @@
 // This test is for *-windows-msvc only.
 // ignore-android
-// ignore-cloudabi
 // ignore-dragonfly
 // ignore-emscripten
 // ignore-freebsd
diff --git a/src/test/codegen/enum-discriminant-value.rs b/src/test/codegen/enum-discriminant-value.rs
index f9da987765f..cc14c212002 100644
--- a/src/test/codegen/enum-discriminant-value.rs
+++ b/src/test/codegen/enum-discriminant-value.rs
@@ -4,14 +4,14 @@
 
 #[repr(i64)]
 pub enum I64 {
-    I64Min = std::i64::MIN,
-    I64Max = std::i64::MAX,
+    I64Min = i64::MIN,
+    I64Max = i64::MAX,
 }
 
 #[repr(u64)]
 pub enum U64 {
-    U64Min = std::u64::MIN,
-    U64Max = std::u64::MAX,
+    U64Min = u64::MIN,
+    U64Max = u64::MAX,
 }
 
 fn main() {
diff --git a/src/test/codegen/fewer-names.rs b/src/test/codegen/fewer-names.rs
new file mode 100644
index 00000000000..53a926d49ef
--- /dev/null
+++ b/src/test/codegen/fewer-names.rs
@@ -0,0 +1,20 @@
+// no-system-llvm
+// compile-flags: -Coverflow-checks=no -O
+// revisions: YES NO
+// [YES]compile-flags: -Zfewer-names=yes
+// [NO] compile-flags: -Zfewer-names=no
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn sum(x: u32, y: u32) -> u32 {
+// YES-LABEL: define i32 @sum(i32 %0, i32 %1)
+// YES-NEXT:    %3 = add i32 %1, %0
+// YES-NEXT:    ret i32 %3
+
+// NO-LABEL: define i32 @sum(i32 %x, i32 %y)
+// NO-NEXT:  start:
+// NO-NEXT:    %z = add i32 %y, %x
+// NO-NEXT:    ret i32 %z
+    let z = x + y;
+    z
+}
diff --git a/src/test/codegen/inline-hint.rs b/src/test/codegen/inline-hint.rs
new file mode 100644
index 00000000000..a2571c2e532
--- /dev/null
+++ b/src/test/codegen/inline-hint.rs
@@ -0,0 +1,31 @@
+// Checks that closures, constructors, and shims except
+// for a drop glue receive inline hint by default.
+//
+// compile-flags: -Cno-prepopulate-passes -Zsymbol-mangling-version=v0
+#![crate_type = "lib"]
+
+pub fn f() {
+    let a = A;
+    let b = (0i32, 1i32, 2i32, 3i32);
+    let c = || {};
+
+    a(String::new(), String::new());
+    b.clone();
+    c();
+}
+
+struct A(String, String);
+
+// CHECK:      ; core::ptr::drop_in_place::<inline_hint::A>
+// CHECK-NEXT: ; Function Attrs:
+// CHECK-NOT:  inlinehint
+// CHECK-SAME: {{$}}
+
+// CHECK:      ; <(i32, i32, i32, i32) as core::clone::Clone>::clone
+// CHECK-NEXT: ; Function Attrs: inlinehint
+
+// CHECK:      ; inline_hint::f::{closure#0}
+// CHECK-NEXT: ; Function Attrs: inlinehint
+
+// CHECK:      ; inline_hint::A
+// CHECK-NEXT: ; Function Attrs: inlinehint
diff --git a/src/test/codegen/issue-56927.rs b/src/test/codegen/issue-56927.rs
index d502673e2f8..2c84015d5e2 100644
--- a/src/test/codegen/issue-56927.rs
+++ b/src/test/codegen/issue-56927.rs
@@ -1,7 +1,6 @@
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type="rlib"]
-use std::usize;
 
 #[repr(align(16))]
 pub struct S {
diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs
index 5e76f1d67e6..43a6be465bc 100644
--- a/src/test/codegen/naked-functions.rs
+++ b/src/test/codegen/naked-functions.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0
+// compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
 #![feature(naked_functions)]
@@ -15,11 +15,9 @@ pub fn naked_empty() {
 // CHECK: Function Attrs: naked
 #[no_mangle]
 #[naked]
-// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %0)?}})
+// CHECK-NEXT: define void @naked_with_args(i{{[0-9]+( %a)?}})
 pub fn naked_with_args(a: isize) {
     // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: %a = alloca i{{[0-9]+}}
-    &a; // keep variable in an alloca
     // CHECK: ret void
 }
 
@@ -34,53 +32,11 @@ pub fn naked_with_return() -> isize {
 }
 
 // CHECK: Function Attrs: naked
-// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %0)?}})
+// CHECK-NEXT: define i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}})
 #[no_mangle]
 #[naked]
 pub fn naked_with_args_and_return(a: isize) -> isize {
     // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: %a = alloca i{{[0-9]+}}
-    &a; // keep variable in an alloca
-    // CHECK: ret i{{[0-9]+}} %{{[0-9]+}}
-    a
-}
-
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define void @naked_recursive()
-#[no_mangle]
-#[naked]
-pub fn naked_recursive() {
-    // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: call void @naked_empty()
-
-    // FIXME(#39685) Avoid one block per call.
-    // CHECK-NEXT: br label %bb1
-    // CHECK: bb1:
-
-    naked_empty();
-
-    // CHECK-NEXT: %_4 = call i{{[0-9]+}} @naked_with_return()
-
-    // FIXME(#39685) Avoid one block per call.
-    // CHECK-NEXT: br label %bb2
-    // CHECK: bb2:
-
-    // CHECK-NEXT: %_3 = call i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+}} %_4)
-
-    // FIXME(#39685) Avoid one block per call.
-    // CHECK-NEXT: br label %bb3
-    // CHECK: bb3:
-
-    // CHECK-NEXT: call void @naked_with_args(i{{[0-9]+}} %_3)
-
-    // FIXME(#39685) Avoid one block per call.
-    // CHECK-NEXT: br label %bb4
-    // CHECK: bb4:
-
-    naked_with_args(
-        naked_with_args_and_return(
-            naked_with_return()
-        )
-    );
-    // CHECK-NEXT: ret void
+    // CHECK: ret i{{[0-9]+}} 0
+    0
 }
diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs
new file mode 100644
index 00000000000..2a2208d4fce
--- /dev/null
+++ b/src/test/codegen/naked-noinline.rs
@@ -0,0 +1,30 @@
+// Checks that naked functions are never inlined.
+// compile-flags: -O -Zmir-opt-level=2
+// ignore-wasm32
+#![crate_type = "lib"]
+#![feature(asm)]
+#![feature(naked_functions)]
+
+#[inline(always)]
+#[naked]
+#[no_mangle]
+pub unsafe extern "C" fn f() {
+// Check that f has naked and noinline attributes.
+//
+// CHECK:       define void @f() unnamed_addr [[ATTR:#[0-9]+]]
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    call void asm
+    asm!("", options(noreturn));
+}
+
+#[no_mangle]
+pub unsafe fn g() {
+// Check that call to f is not inlined.
+//
+// CHECK-LABEL: define void @g()
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    call void @f()
+    f();
+}
+
+// CHECK: attributes [[ATTR]] = { naked noinline{{.*}} }
diff --git a/src/test/codegen/panic-abort-windows.rs b/src/test/codegen/panic-abort-windows.rs
index 8e38245267d..9ee4bfc4711 100644
--- a/src/test/codegen/panic-abort-windows.rs
+++ b/src/test/codegen/panic-abort-windows.rs
@@ -1,6 +1,5 @@
 // This test is for *-windows-msvc only.
 // ignore-android
-// ignore-cloudabi
 // ignore-dragonfly
 // ignore-emscripten
 // ignore-freebsd
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs
new file mode 100644
index 00000000000..b5b0b1330a6
--- /dev/null
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs
@@ -0,0 +1,47 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct M(pub f32, pub f32, pub f32, pub f32);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct S<const N: usize>([f32; N]);
+
+extern "platform-intrinsic" {
+    fn simd_extract<T, U>(x: T, idx: u32) -> U;
+    fn simd_insert<T, U>(x: T, idx: u32, b: U) -> T;
+}
+
+// CHECK-LABEL: @extract_m
+#[no_mangle]
+pub unsafe fn extract_m(v: M, i: u32) -> f32  {
+    // CHECK: extractelement <4 x float> %{{v|_3}}, i32 %i
+    simd_extract(v, i)
+}
+
+// CHECK-LABEL: @extract_s
+#[no_mangle]
+pub unsafe fn extract_s(v: S<4>, i: u32) -> f32  {
+    // CHECK: extractelement <4 x float> %{{v|_3}}, i32 %i
+    simd_extract(v, i)
+}
+
+// CHECK-LABEL: @insert_m
+#[no_mangle]
+pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M  {
+    // CHECK: insertelement <4 x float> %{{v|_4}}, 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|_4}}, float %j, i32 %i
+    simd_insert(v, i, j)
+}
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
new file mode 100644
index 00000000000..56466a78d5a
--- /dev/null
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
@@ -0,0 +1,44 @@
+// ignore-tidy-linelength
+// compile-flags: -C no-prepopulate-passes
+// min-llvm-version 8.0
+
+#![crate_type = "lib"]
+
+#![allow(non_camel_case_types)]
+#![feature(repr_simd, platform_intrinsics, min_const_generics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct S<const N: usize>([f32; N]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct T([f32; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct U(f32, f32, f32, f32);
+
+// CHECK-LABEL: @build_array_s
+#[no_mangle]
+pub fn build_array_s(x: [f32; 4]) -> S<4> {
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    S::<4>(x)
+}
+
+// CHECK-LABEL: @build_array_t
+#[no_mangle]
+pub fn build_array_t(x: [f32; 4]) -> T {
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    T(x)
+}
+
+// CHECK-LABEL: @build_array_u
+#[no_mangle]
+pub fn build_array_u(x: [f32; 4]) -> U {
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{[0-9]+}}(i8* {{.*}} %{{[0-9]+}}, i8* {{.*}} %{{[0-9]+}}, i{{[0-9]+}} 16, i1 false)
+    unsafe { std::mem::transmute(x) }
+}
diff --git a/src/test/codegen/to_vec.rs b/src/test/codegen/to_vec.rs
new file mode 100644
index 00000000000..60dc4efcb62
--- /dev/null
+++ b/src/test/codegen/to_vec.rs
@@ -0,0 +1,10 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @copy_to_vec
+#[no_mangle]
+fn copy_to_vec(s: &[u64]) -> Vec<u64> {
+  s.to_vec()
+  // CHECK: call void @llvm.memcpy
+}
diff --git a/src/test/codegen/transmute-scalar.rs b/src/test/codegen/transmute-scalar.rs
new file mode 100644
index 00000000000..78b4aa3fb88
--- /dev/null
+++ b/src/test/codegen/transmute-scalar.rs
@@ -0,0 +1,85 @@
+// compile-flags: -O -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+// FIXME(eddyb) all of these tests show memory stores and loads, even after a
+// scalar `bitcast`, more special-casing is required to remove `alloca` usage.
+
+// CHECK: define i32 @f32_to_bits(float %x)
+// CHECK: %2 = bitcast float %x to i32
+// CHECK-NEXT: store i32 %2, i32* %0
+// CHECK-NEXT: %3 = load i32, i32* %0
+// CHECK: ret i32 %3
+#[no_mangle]
+pub fn f32_to_bits(x: f32) -> u32 {
+    unsafe { std::mem::transmute(x) }
+}
+
+// CHECK: define i8 @bool_to_byte(i1 zeroext %b)
+// CHECK: %1 = zext i1 %b to i8
+// CHECK-NEXT: store i8 %1, i8* %0
+// CHECK-NEXT: %2 = load i8, i8* %0
+// CHECK: ret i8 %2
+#[no_mangle]
+pub fn bool_to_byte(b: bool) -> u8 {
+    unsafe { std::mem::transmute(b) }
+}
+
+// CHECK: define zeroext i1 @byte_to_bool(i8 %byte)
+// CHECK: %1 = trunc i8 %byte to i1
+// CHECK-NEXT: %2 = zext i1 %1 to i8
+// CHECK-NEXT: store i8 %2, i8* %0
+// CHECK-NEXT: %3 = load i8, i8* %0
+// CHECK-NEXT: %4 = trunc i8 %3 to i1
+// CHECK: ret i1 %4
+#[no_mangle]
+pub unsafe fn byte_to_bool(byte: u8) -> bool {
+    std::mem::transmute(byte)
+}
+
+// CHECK: define i8* @ptr_to_ptr(i16* %p)
+// CHECK: %2 = bitcast i16* %p to i8*
+// CHECK-NEXT: store i8* %2, i8** %0
+// CHECK-NEXT: %3 = load i8*, i8** %0
+// CHECK: ret i8* %3
+#[no_mangle]
+pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
+    unsafe { std::mem::transmute(p) }
+}
+
+// HACK(eddyb) scalar `transmute`s between pointers and non-pointers are
+// currently not special-cased like other scalar `transmute`s, because
+// LLVM requires specifically `ptrtoint`/`inttoptr` instead of `bitcast`.
+//
+// Tests below show the non-special-cased behavior (with the possible
+// future special-cased instructions in the "NOTE(eddyb)" comments).
+
+// CHECK: define [[USIZE:i[0-9]+]] @ptr_to_int(i16* %p)
+
+// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
+//        %2 = ptrtoint i16* %p to [[USIZE]]
+//             store [[USIZE]] %2, [[USIZE]]* %0
+// CHECK: %2 = bitcast [[USIZE]]* %0 to i16**
+// CHECK-NEXT: store i16* %p, i16** %2
+
+// CHECK-NEXT: %3 = load [[USIZE]], [[USIZE]]* %0
+// CHECK: ret [[USIZE]] %3
+#[no_mangle]
+pub fn ptr_to_int(p: *mut u16) -> usize {
+    unsafe { std::mem::transmute(p) }
+}
+
+// CHECK: define i16* @int_to_ptr([[USIZE]] %i)
+
+// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
+//        %2 = inttoptr [[USIZE]] %i to i16*
+//             store i16* %2, i16** %0
+// CHECK: %2 = bitcast i16** %0 to [[USIZE]]*
+// CHECK-NEXT: store [[USIZE]] %i, [[USIZE]]* %2
+
+// CHECK-NEXT: %3 = load i16*, i16** %0
+// CHECK: ret i16* %3
+#[no_mangle]
+pub fn int_to_ptr(i: usize) -> *mut u16 {
+    unsafe { std::mem::transmute(i) }
+}
diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs
index afea01e9a2d..f282fd23705 100644
--- a/src/test/codegen/union-abi.rs
+++ b/src/test/codegen/union-abi.rs
@@ -63,11 +63,16 @@ pub union UnionU128{a:u128}
 #[no_mangle]
 pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} }
 
+pub union UnionU128x2{a:(u128, u128)}
+// CHECK: define void @test_UnionU128x2(i128 %_1.0, i128 %_1.1)
+#[no_mangle]
+pub fn test_UnionU128x2(_: UnionU128x2) { loop {} }
+
 #[repr(C)]
-pub union CUnionU128{a:u128}
-// CHECK: define void @test_CUnionU128(%CUnionU128* {{.*}} %_1)
+pub union CUnionU128x2{a:(u128, u128)}
+// CHECK: define void @test_CUnionU128x2(%CUnionU128x2* {{.*}} %_1)
 #[no_mangle]
-pub fn test_CUnionU128(_: CUnionU128) { loop {} }
+pub fn test_CUnionU128x2(_: CUnionU128x2) { loop {} }
 
 pub union UnionBool { b:bool }
 // CHECK: define zeroext i1 @test_UnionBool(i8 %b)