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/issues/issue-86106.rs28
-rw-r--r--tests/codegen/overaligned-constant.rs36
2 files changed, 56 insertions, 8 deletions
diff --git a/tests/codegen/issues/issue-86106.rs b/tests/codegen/issues/issue-86106.rs
index 15aef344ac0..5f71d46fb20 100644
--- a/tests/codegen/issues/issue-86106.rs
+++ b/tests/codegen/issues/issue-86106.rs
@@ -9,9 +9,12 @@
 // CHECK-LABEL: define {{(dso_local )?}}void @string_new
 #[no_mangle]
 pub fn string_new() -> String {
-    // CHECK: store ptr inttoptr
+    // CHECK-NOT: load i8
+    // CHECK: store i{{32|64}}
     // CHECK-NEXT: getelementptr
-    // CHECK-NEXT: call void @llvm.memset
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
     // CHECK-NEXT: ret void
     String::new()
 }
@@ -19,9 +22,12 @@ pub fn string_new() -> String {
 // CHECK-LABEL: define {{(dso_local )?}}void @empty_to_string
 #[no_mangle]
 pub fn empty_to_string() -> String {
-    // CHECK: store ptr inttoptr
+    // CHECK-NOT: load i8
+    // CHECK: store i{{32|64}}
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
     // CHECK-NEXT: getelementptr
-    // CHECK-NEXT: call void @llvm.memset
+    // CHECK-NEXT: store i{{32|64}}
     // CHECK-NEXT: ret void
     "".to_string()
 }
@@ -32,9 +38,12 @@ pub fn empty_to_string() -> String {
 // CHECK-LABEL: @empty_vec
 #[no_mangle]
 pub fn empty_vec() -> Vec<u8> {
-    // CHECK: store ptr inttoptr
+    // CHECK: store i{{32|64}}
+    // CHECK-NOT: load i8
     // CHECK-NEXT: getelementptr
-    // CHECK-NEXT: call void @llvm.memset
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
     // CHECK-NEXT: ret void
     vec![]
 }
@@ -42,9 +51,12 @@ pub fn empty_vec() -> Vec<u8> {
 // CHECK-LABEL: @empty_vec_clone
 #[no_mangle]
 pub fn empty_vec_clone() -> Vec<u8> {
-    // CHECK: store ptr inttoptr
+    // CHECK: store i{{32|64}}
+    // CHECK-NOT: load i8
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
     // CHECK-NEXT: getelementptr
-    // CHECK-NEXT: call void @llvm.memset
+    // CHECK-NEXT: store i{{32|64}}
     // CHECK-NEXT: ret void
     vec![].clone()
 }
diff --git a/tests/codegen/overaligned-constant.rs b/tests/codegen/overaligned-constant.rs
new file mode 100644
index 00000000000..c94dfd85e7d
--- /dev/null
+++ b/tests/codegen/overaligned-constant.rs
@@ -0,0 +1,36 @@
+// GVN may create indirect constants with higher alignment than their type requires. Verify that we
+// do not ICE during codegen, and that the LLVM constant has the higher alignment.
+//
+// compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN
+// compile-flags: -Cno-prepopulate-passes
+// only-64bit
+
+struct S(i32);
+
+struct SmallStruct(f32, Option<S>, &'static [f32]);
+
+// CHECK: @0 = private unnamed_addr constant
+// CHECK-SAME: , align 8
+
+fn main() {
+    // CHECK-LABEL: @_ZN20overaligned_constant4main
+    // CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8
+    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false)
+    // CHECK: %b.0 = load i32, ptr @0, align 4,
+    // CHECK: %b.1 = load i32, ptr getelementptr inbounds ({ i32, i32 }, ptr @0, i32 0, i32 1), align 4
+    let mut s = S(1);
+
+    s.0 = 3;
+
+    // SMALL_VAL corresponds to a MIR allocation with alignment 8.
+    const SMALL_VAL: SmallStruct = SmallStruct(4., Some(S(1)), &[]);
+
+    // In pre-codegen MIR:
+    // `a` is a scalar 4.
+    // `b` is an indirect constant at `SMALL_VAL`'s alloc with 0 offset.
+    // `c` is the empty slice.
+    //
+    // As a consequence, during codegen, we create a LLVM allocation for `SMALL_VAL`, with
+    // alignment 8, but only use the `Option<S>` field, at offset 0 with alignment 4.
+    let SmallStruct(a, b, c) = SMALL_VAL;
+}