1; RUN: llc -mtriple=x86_64-unknown-unknown -force-split-store < %s | FileCheck %s
2
3; CHECK-LABEL: int32_float_pair
4; CHECK-DAG: movl %edi, (%rsi)
5; CHECK-DAG: movss %xmm0, 4(%rsi)
6define void @int32_float_pair(i32 %tmp1, float %tmp2, i64* %ref.tmp) {
7entry:
8  %t0 = bitcast float %tmp2 to i32
9  %t1 = zext i32 %t0 to i64
10  %t2 = shl nuw i64 %t1, 32
11  %t3 = zext i32 %tmp1 to i64
12  %t4 = or i64 %t2, %t3
13  store i64 %t4, i64* %ref.tmp, align 8
14  ret void
15}
16
17; CHECK-LABEL: float_int32_pair
18; CHECK-DAG: movss %xmm0, (%rsi)
19; CHECK-DAG: movl %edi, 4(%rsi)
20define void @float_int32_pair(float %tmp1, i32 %tmp2, i64* %ref.tmp) {
21entry:
22  %t0 = bitcast float %tmp1 to i32
23  %t1 = zext i32 %tmp2 to i64
24  %t2 = shl nuw i64 %t1, 32
25  %t3 = zext i32 %t0 to i64
26  %t4 = or i64 %t2, %t3
27  store i64 %t4, i64* %ref.tmp, align 8
28  ret void
29}
30
31; CHECK-LABEL: int16_float_pair
32; CHECK-DAG: movzwl	%di, %eax
33; CHECK-DAG: movl %eax, (%rsi)
34; CHECK-DAG: movss %xmm0, 4(%rsi)
35define void @int16_float_pair(i16 signext %tmp1, float %tmp2, i64* %ref.tmp) {
36entry:
37  %t0 = bitcast float %tmp2 to i32
38  %t1 = zext i32 %t0 to i64
39  %t2 = shl nuw i64 %t1, 32
40  %t3 = zext i16 %tmp1 to i64
41  %t4 = or i64 %t2, %t3
42  store i64 %t4, i64* %ref.tmp, align 8
43  ret void
44}
45
46; CHECK-LABEL: int8_float_pair
47; CHECK-DAG: movzbl	%dil, %eax
48; CHECK-DAG: movl %eax, (%rsi)
49; CHECK-DAG: movss %xmm0, 4(%rsi)
50define void @int8_float_pair(i8 signext %tmp1, float %tmp2, i64* %ref.tmp) {
51entry:
52  %t0 = bitcast float %tmp2 to i32
53  %t1 = zext i32 %t0 to i64
54  %t2 = shl nuw i64 %t1, 32
55  %t3 = zext i8 %tmp1 to i64
56  %t4 = or i64 %t2, %t3
57  store i64 %t4, i64* %ref.tmp, align 8
58  ret void
59}
60
61; CHECK-LABEL: int32_int32_pair
62; CHECK: movl	%edi, (%rdx)
63; CHECK: movl	%esi, 4(%rdx)
64define void @int32_int32_pair(i32 %tmp1, i32 %tmp2, i64* %ref.tmp) {
65entry:
66  %t1 = zext i32 %tmp2 to i64
67  %t2 = shl nuw i64 %t1, 32
68  %t3 = zext i32 %tmp1 to i64
69  %t4 = or i64 %t2, %t3
70  store i64 %t4, i64* %ref.tmp, align 8
71  ret void
72}
73
74; CHECK-LABEL: int16_int16_pair
75; CHECK: movw	%di, (%rdx)
76; CHECK: movw	%si, 2(%rdx)
77define void @int16_int16_pair(i16 signext %tmp1, i16 signext %tmp2, i32* %ref.tmp) {
78entry:
79  %t1 = zext i16 %tmp2 to i32
80  %t2 = shl nuw i32 %t1, 16
81  %t3 = zext i16 %tmp1 to i32
82  %t4 = or i32 %t2, %t3
83  store i32 %t4, i32* %ref.tmp, align 4
84  ret void
85}
86
87; CHECK-LABEL: int8_int8_pair
88; CHECK: movb	%dil, (%rdx)
89; CHECK: movb	%sil, 1(%rdx)
90define void @int8_int8_pair(i8 signext %tmp1, i8 signext %tmp2, i16* %ref.tmp) {
91entry:
92  %t1 = zext i8 %tmp2 to i16
93  %t2 = shl nuw i16 %t1, 8
94  %t3 = zext i8 %tmp1 to i16
95  %t4 = or i16 %t2, %t3
96  store i16 %t4, i16* %ref.tmp, align 2
97  ret void
98}
99
100; CHECK-LABEL: int31_int31_pair
101; CHECK: andl $2147483647, %edi
102; CHECK: movl %edi, (%rdx)
103; CHECK: andl $2147483647, %esi
104; CHECK: movl %esi, 4(%rdx)
105define void @int31_int31_pair(i31 %tmp1, i31 %tmp2, i64* %ref.tmp) {
106entry:
107  %t1 = zext i31 %tmp2 to i64
108  %t2 = shl nuw i64 %t1, 32
109  %t3 = zext i31 %tmp1 to i64
110  %t4 = or i64 %t2, %t3
111  store i64 %t4, i64* %ref.tmp, align 8
112  ret void
113}
114
115; CHECK-LABEL: int31_int17_pair
116; CHECK: andl $2147483647, %edi
117; CHECK: movl %edi, (%rdx)
118; CHECK: andl $131071, %esi
119; CHECK: movl %esi, 4(%rdx)
120define void @int31_int17_pair(i31 %tmp1, i17 %tmp2, i64* %ref.tmp) {
121entry:
122  %t1 = zext i17 %tmp2 to i64
123  %t2 = shl nuw i64 %t1, 32
124  %t3 = zext i31 %tmp1 to i64
125  %t4 = or i64 %t2, %t3
126  store i64 %t4, i64* %ref.tmp, align 8
127  ret void
128}
129
130; CHECK-LABEL: int7_int3_pair
131; CHECK: andb $127, %dil
132; CHECK: movb %dil, (%rdx)
133; CHECK: andb $7, %sil
134; CHECK: movb %sil, 1(%rdx)
135define void @int7_int3_pair(i7 signext %tmp1, i3 signext %tmp2, i16* %ref.tmp) {
136entry:
137  %t1 = zext i3 %tmp2 to i16
138  %t2 = shl nuw i16 %t1, 8
139  %t3 = zext i7 %tmp1 to i16
140  %t4 = or i16 %t2, %t3
141  store i16 %t4, i16* %ref.tmp, align 2
142  ret void
143}
144
145; CHECK-LABEL: int24_int24_pair
146; CHECK: movw	%di, (%rdx)
147; CHECK: shrl	$16, %edi
148; CHECK: movb	%dil, 2(%rdx)
149; CHECK: movw    %si, 4(%rdx)
150; CHECK: shrl    $16, %esi
151; CHECK: movb    %sil, 6(%rdx)
152define void @int24_int24_pair(i24 signext %tmp1, i24 signext %tmp2, i48* %ref.tmp) {
153entry:
154  %t1 = zext i24 %tmp2 to i48
155  %t2 = shl nuw i48 %t1, 24
156  %t3 = zext i24 %tmp1 to i48
157  %t4 = or i48 %t2, %t3
158  store i48 %t4, i48* %ref.tmp, align 2
159  ret void
160}
161
162; getTypeSizeInBits(i12) != getTypeStoreSizeInBits(i12), so store split doesn't kick in.
163; CHECK-LABEL: int12_int12_pair
164; CHECK: movl	%esi, %eax
165; CHECK: shll	$12, %eax
166; CHECK: andl	$4095, %edi
167; CHECK: orl	%eax, %edi
168; CHECK: shrl	$4, %esi
169; CHECK: movb	%sil, 2(%rdx)
170; CHECK: movw	%di, (%rdx)
171define void @int12_int12_pair(i12 signext %tmp1, i12 signext %tmp2, i24* %ref.tmp) {
172entry:
173  %t1 = zext i12 %tmp2 to i24
174  %t2 = shl nuw i24 %t1, 12
175  %t3 = zext i12 %tmp1 to i24
176  %t4 = or i24 %t2, %t3
177  store i24 %t4, i24* %ref.tmp, align 2
178  ret void
179}
180
181; getTypeSizeInBits(i14) != getTypeStoreSizeInBits(i14), so store split doesn't kick in.
182; CHECK-LABEL: int7_int7_pair
183; CHECK: movzbl	%sil, %eax
184; CHECK: shll	$7, %eax
185; CHECK: andb	$127, %dil
186; CHECK: movzbl	%dil, %ecx
187; CHECK: orl	%eax, %ecx
188; CHECK: andl	$16383, %ecx
189; CHECK: movw	%cx, (%rdx)
190define void @int7_int7_pair(i7 signext %tmp1, i7 signext %tmp2, i14* %ref.tmp) {
191entry:
192  %t1 = zext i7 %tmp2 to i14
193  %t2 = shl nuw i14 %t1, 7
194  %t3 = zext i7 %tmp1 to i14
195  %t4 = or i14 %t2, %t3
196  store i14 %t4, i14* %ref.tmp, align 2
197  ret void
198}
199
200; getTypeSizeInBits(i2) != getTypeStoreSizeInBits(i2), so store split doesn't kick in.
201; CHECK-LABEL: int1_int1_pair
202; CHECK: addb %sil, %sil
203; CHECK: andb $1, %dil
204; CHECK: orb %sil, %dil
205; CHECK: andb $3, %dil
206; CHECK: movb %dil, (%rdx)
207define void @int1_int1_pair(i1 signext %tmp1, i1 signext %tmp2, i2* %ref.tmp) {
208entry:
209  %t1 = zext i1 %tmp2 to i2
210  %t2 = shl nuw i2 %t1, 1
211  %t3 = zext i1 %tmp1 to i2
212  %t4 = or i2 %t2, %t3
213  store i2 %t4, i2* %ref.tmp, align 1
214  ret void
215}
216
217; CHECK-LABEL: mbb_int32_float_pair
218; CHECK: movl %edi, (%rsi)
219; CHECK: movss %xmm0, 4(%rsi)
220define void @mbb_int32_float_pair(i32 %tmp1, float %tmp2, i64* %ref.tmp) {
221entry:
222  %t0 = bitcast float %tmp2 to i32
223  br label %next
224next:
225  %t1 = zext i32 %t0 to i64
226  %t2 = shl nuw i64 %t1, 32
227  %t3 = zext i32 %tmp1 to i64
228  %t4 = or i64 %t2, %t3
229  store i64 %t4, i64* %ref.tmp, align 8
230  ret void
231}
232
233; CHECK-LABEL: mbb_int32_float_multi_stores
234; CHECK: movl %edi, (%rsi)
235; CHECK: movss %xmm0, 4(%rsi)
236; CHECK: # %bb2
237; CHECK: movl %edi, (%rdx)
238; CHECK: movss %xmm0, 4(%rdx)
239define void @mbb_int32_float_multi_stores(i32 %tmp1, float %tmp2, i64* %ref.tmp, i64* %ref.tmp1, i1 %cmp) {
240entry:
241  %t0 = bitcast float %tmp2 to i32
242  br label %bb1
243bb1:
244  %t1 = zext i32 %t0 to i64
245  %t2 = shl nuw i64 %t1, 32
246  %t3 = zext i32 %tmp1 to i64
247  %t4 = or i64 %t2, %t3
248  store i64 %t4, i64* %ref.tmp, align 8
249  br i1 %cmp, label %bb2, label %exitbb
250bb2:
251  store i64 %t4, i64* %ref.tmp1, align 8
252  br label %exitbb
253exitbb:
254  ret void
255}
256