2 // compile-flags: -O -C no-prepopulate-passes
18 // CHECK-LABEL: @write_pkd1
20 pub fn write_pkd1(pkd
: &mut Packed1
) -> u32 {
21 // CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 1
22 // CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 1
23 let result
= pkd
.data
;
28 // CHECK-LABEL: @write_pkd2
30 pub fn write_pkd2(pkd
: &mut Packed2
) -> u32 {
31 // CHECK: %{{.*}} = load i32, {{i32\*|ptr}} %{{.*}}, align 2
32 // CHECK: store i32 42, {{i32\*|ptr}} %{{.*}}, align 2
33 let result
= pkd
.data
;
38 pub struct Array([i32; 8]);
40 pub struct BigPacked1
{
46 pub struct BigPacked2
{
51 // CHECK-LABEL: @call_pkd1
53 pub fn call_pkd1(f
: fn() -> Array
) -> BigPacked1
{
54 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
55 // CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
56 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
57 // check that calls whose destination is a field of a packed struct
58 // go through an alloca rather than calling the function with an
59 // unaligned destination.
60 BigPacked1 { dealign: 0, data: f() }
63 // CHECK-LABEL: @call_pkd2
65 pub fn call_pkd2(f
: fn() -> Array
) -> BigPacked2
{
66 // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
67 // CHECK: call void %{{.*}}({{%Array\*|ptr}} noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]])
68 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false)
69 // check that calls whose destination is a field of a packed struct
70 // go through an alloca rather than calling the function with an
71 // unaligned destination.
72 BigPacked2 { dealign: 0, data: f() }
75 // CHECK-LABEL: @write_packed_array1
76 // CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 1
77 // CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 1
78 // CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 1
80 pub fn write_packed_array1(p
: &mut BigPacked1
) {
86 // CHECK-LABEL: @write_packed_array2
87 // CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 2
88 // CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 2
89 // CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 2
91 pub fn write_packed_array2(p
: &mut BigPacked2
) {
97 // CHECK-LABEL: @repeat_packed_array1
98 // CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 1
100 pub fn repeat_packed_array1(p
: &mut BigPacked1
) {
104 // CHECK-LABEL: @repeat_packed_array2
105 // CHECK: store i32 42, {{i32\*|ptr}} %{{.+}}, align 2
107 pub fn repeat_packed_array2(p
: &mut BigPacked2
) {
112 #[derive(Copy, Clone)]
113 pub struct Packed1Pair(u8, u32);
116 #[derive(Copy, Clone)]
117 pub struct Packed2Pair(u8, u32);
119 // CHECK-LABEL: @pkd1_pair
121 pub fn pkd1_pair(pair1
: &mut Packed1Pair
, pair2
: &mut Packed1Pair
) {
122 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 5, i1 false)
126 // CHECK-LABEL: @pkd2_pair
128 pub fn pkd2_pair(pair1
: &mut Packed2Pair
, pair2
: &mut Packed2Pair
) {
129 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 6, i1 false)
134 #[derive(Copy, Clone)]
135 pub struct Packed1NestedPair((u32, u32));
138 #[derive(Copy, Clone)]
139 pub struct Packed2NestedPair((u32, u32));
141 // CHECK-LABEL: @pkd1_nested_pair
143 pub fn pkd1_nested_pair(pair1
: &mut Packed1NestedPair
, pair2
: &mut Packed1NestedPair
) {
144 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 1 %{{.*}}, {{i8\*|ptr}} align 1 %{{.*}}, i{{[0-9]+}} 8, i1 false)
148 // CHECK-LABEL: @pkd2_nested_pair
150 pub fn pkd2_nested_pair(pair1
: &mut Packed2NestedPair
, pair2
: &mut Packed2NestedPair
) {
151 // CHECK: call void @llvm.memcpy.{{.*}}({{i8\*|ptr}} align 2 %{{.*}}, {{i8\*|ptr}} align 2 %{{.*}}, i{{[0-9]+}} 8, i1 false)