about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-11-27 20:51:52 +0100
committerRalf Jung <post@ralfj.de>2022-11-27 20:51:52 +0100
commit7c12ed1d5dc6059972b06fb7257a239f3a33ec88 (patch)
treefd57c555e715f92ec17d90a702860a6740d32ce8 /src/test/codegen
parent187ba6778174717b9d793aec363e836c947b55a5 (diff)
parent454784afba5bf35b5ff14ada0e31265ad1d75e73 (diff)
downloadrust-7c12ed1d5dc6059972b06fb7257a239f3a33ec88.tar.gz
rust-7c12ed1d5dc6059972b06fb7257a239f3a33ec88.zip
Merge from rustc
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/async-fn-debug-awaitee-field.rs8
-rw-r--r--src/test/codegen/issue-37945.rs4
-rw-r--r--src/test/codegen/iter-repeat-n-trivial-drop.rs56
-rw-r--r--src/test/codegen/mem-replace-direct-memcpy.rs4
-rw-r--r--src/test/codegen/option-nonzero-eq.rs34
-rw-r--r--src/test/codegen/repeat-trusted-len.rs7
-rw-r--r--src/test/codegen/slice-iter-len-eq-zero.rs2
7 files changed, 107 insertions, 8 deletions
diff --git a/src/test/codegen/async-fn-debug-awaitee-field.rs b/src/test/codegen/async-fn-debug-awaitee-field.rs
index 909cd0062a6..bc268615814 100644
--- a/src/test/codegen/async-fn-debug-awaitee-field.rs
+++ b/src/test/codegen/async-fn-debug-awaitee-field.rs
@@ -11,12 +11,14 @@ async fn async_fn_test() {
     foo().await;
 }
 
-// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}",
+// NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[GEN_SCOPE:![0-9]*]],
 // MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
+// NONMSVC: [[GEN_SCOPE:!.*]] = !DINamespace(name: "async_fn_test",
 // CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
-// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
+// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[AWAITEE_SCOPE:![0-9]*]],
+// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
+// NONMSVC: [[AWAITEE_SCOPE]] = !DINamespace(name: "foo",
 
 fn main() {
     let _fn = async_fn_test();
diff --git a/src/test/codegen/issue-37945.rs b/src/test/codegen/issue-37945.rs
index 12fa1e9e56b..fe54375bbf6 100644
--- a/src/test/codegen/issue-37945.rs
+++ b/src/test/codegen/issue-37945.rs
@@ -15,7 +15,7 @@ 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.1, null
+// CHECK-NEXT:    [[A:%.*]] = icmp ne {{i32\*|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.
@@ -28,7 +28,7 @@ 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.1, null
+// CHECK-NEXT:    [[C:%.*]] = icmp ne {{i32\*|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.
diff --git a/src/test/codegen/iter-repeat-n-trivial-drop.rs b/src/test/codegen/iter-repeat-n-trivial-drop.rs
new file mode 100644
index 00000000000..20e1d9b4d59
--- /dev/null
+++ b/src/test/codegen/iter-repeat-n-trivial-drop.rs
@@ -0,0 +1,56 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+#![feature(iter_repeat_n)]
+
+#[derive(Clone)]
+pub struct NotCopy(u16);
+
+impl Drop for NotCopy {
+    fn drop(&mut self) {}
+}
+
+// For a type where `Drop::drop` doesn't do anything observable and a clone is the
+// same as a move, make sure that the extra case for the last item disappears.
+
+#[no_mangle]
+// CHECK-LABEL: @iter_repeat_n_next
+pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCopy> {
+    // CHECK-NEXT: start:
+    // CHECK-NOT: br
+    // CHECK: %[[COUNT:.+]] = load i64
+    // CHECK-NEXT: %[[COUNT_ZERO:.+]] = icmp eq i64 %[[COUNT]], 0
+    // CHECK-NEXT: br i1 %[[COUNT_ZERO]], label %[[EMPTY:.+]], label %[[NOT_EMPTY:.+]]
+
+    // CHECK: [[NOT_EMPTY]]:
+    // CHECK-NEXT: %[[DEC:.+]] = add i64 %[[COUNT]], -1
+    // CHECK-NEXT: store i64 %[[DEC]]
+    // CHECK-NOT: br
+    // CHECK: %[[VAL:.+]] = load i16
+    // CHECK-NEXT: br label %[[EMPTY]]
+
+    // CHECK: [[EMPTY]]:
+    // CHECK-NOT: br
+    // CHECK: phi i16 [ undef, %start ], [ %[[VAL]], %[[NOT_EMPTY]] ]
+    // CHECK-NOT: br
+    // CHECK: ret
+
+    it.next()
+}
+
+// And as a result, using the iterator can optimize without special cases for
+// the last iteration, like `memset`ing all the items in one call.
+
+#[no_mangle]
+// CHECK-LABEL: @vec_extend_via_iter_repeat_n
+pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
+    // CHECK: %[[ADDR:.+]] = tail call dereferenceable_or_null(1234) ptr @__rust_alloc(i64 1234, i64 1)
+    // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234,
+
+    let n = 1234_usize;
+    let mut v = Vec::with_capacity(n);
+    v.extend(std::iter::repeat_n(42_u8, n));
+    v
+}
diff --git a/src/test/codegen/mem-replace-direct-memcpy.rs b/src/test/codegen/mem-replace-direct-memcpy.rs
index 4318e926e47..e8bbf0e1bbd 100644
--- a/src/test/codegen/mem-replace-direct-memcpy.rs
+++ b/src/test/codegen/mem-replace-direct-memcpy.rs
@@ -18,7 +18,7 @@ pub fn replace_byte(dst: &mut u8, src: u8) -> u8 {
 // CHECK-NOT: call void @llvm.memcpy
 // CHECK: ; core::mem::replace
 // CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %dest, i{{.*}} 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
-// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %dest, {{i8\*|ptr}} align 1 %src{{.*}}, i{{.*}} 1, i1 false)
+// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{.*}} 1, i1 false)
 // CHECK-NOT: call void @llvm.memcpy
diff --git a/src/test/codegen/option-nonzero-eq.rs b/src/test/codegen/option-nonzero-eq.rs
new file mode 100644
index 00000000000..598dcc19b49
--- /dev/null
+++ b/src/test/codegen/option-nonzero-eq.rs
@@ -0,0 +1,34 @@
+// compile-flags: -O -Zmerge-functions=disabled
+
+#![crate_type = "lib"]
+
+extern crate core;
+use core::num::{NonZeroU32, NonZeroI64};
+use core::ptr::NonNull;
+
+// CHECK-lABEL: @non_zero_eq
+#[no_mangle]
+pub fn non_zero_eq(l: Option<NonZeroU32>, r: Option<NonZeroU32>) -> bool {
+    // CHECK: start:
+    // CHECK-NEXT: icmp eq i32
+    // CHECK-NEXT: ret i1
+    l == r
+}
+
+// CHECK-lABEL: @non_zero_signed_eq
+#[no_mangle]
+pub fn non_zero_signed_eq(l: Option<NonZeroI64>, r: Option<NonZeroI64>) -> bool {
+    // CHECK: start:
+    // CHECK-NEXT: icmp eq i64
+    // CHECK-NEXT: ret i1
+    l == r
+}
+
+// CHECK-lABEL: @non_null_eq
+#[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: ret i1
+    l == r
+}
diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs
index 7aebd3ec7df..87c8fe1354d 100644
--- a/src/test/codegen/repeat-trusted-len.rs
+++ b/src/test/codegen/repeat-trusted-len.rs
@@ -11,3 +11,10 @@ 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)
     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)
+    iter::repeat_with(|| 13).take(12345).collect()
+}
diff --git a/src/test/codegen/slice-iter-len-eq-zero.rs b/src/test/codegen/slice-iter-len-eq-zero.rs
index 1124028253d..894b0ec3de4 100644
--- a/src/test/codegen/slice-iter-len-eq-zero.rs
+++ b/src/test/codegen/slice-iter-len-eq-zero.rs
@@ -9,7 +9,7 @@ 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
+    // CHECK: %2 = icmp eq {{i8\*|ptr}} {{%1|%0}}, {{%1|%0}}
     // CHECK: ret i1 %2
     y.len() == 0
 }