1; Test insertions of 32-bit constants into one half of an i64.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Prefer LHI over IILF for signed 16-bit constants.
6define i64 @f1(i64 %a) {
7; CHECK-LABEL: f1:
8; CHECK-NOT: ni
9; CHECK: lhi %r2, 1
10; CHECK: br %r14
11  %and = and i64 %a, 18446744069414584320
12  %or = or i64 %and, 1
13  ret i64 %or
14}
15
16; Check the high end of the LHI range.
17define i64 @f2(i64 %a) {
18; CHECK-LABEL: f2:
19; CHECK-NOT: ni
20; CHECK: lhi %r2, 32767
21; CHECK: br %r14
22  %and = and i64 %a, 18446744069414584320
23  %or = or i64 %and, 32767
24  ret i64 %or
25}
26
27; Check the next value up, which should use IILF instead.
28define i64 @f3(i64 %a) {
29; CHECK-LABEL: f3:
30; CHECK-NOT: ni
31; CHECK: iilf %r2, 32768
32; CHECK: br %r14
33  %and = and i64 %a, 18446744069414584320
34  %or = or i64 %and, 32768
35  ret i64 %or
36}
37
38; Check a value in which the lower 16 bits are clear.
39define i64 @f4(i64 %a) {
40; CHECK-LABEL: f4:
41; CHECK-NOT: ni
42; CHECK: iilf %r2, 65536
43; CHECK: br %r14
44  %and = and i64 %a, 18446744069414584320
45  %or = or i64 %and, 65536
46  ret i64 %or
47}
48
49; Check the highest useful IILF value (-0x8001).
50define i64 @f5(i64 %a) {
51; CHECK-LABEL: f5:
52; CHECK-NOT: ni
53; CHECK: iilf %r2, 4294934527
54; CHECK: br %r14
55  %and = and i64 %a, 18446744069414584320
56  %or = or i64 %and, 4294934527
57  ret i64 %or
58}
59
60; Check the next value up, which should use LHI instead.
61define i64 @f6(i64 %a) {
62; CHECK-LABEL: f6:
63; CHECK-NOT: ni
64; CHECK: lhi %r2, -32768
65; CHECK: br %r14
66  %and = and i64 %a, 18446744069414584320
67  %or = or i64 %and, 4294934528
68  ret i64 %or
69}
70
71; Check the highest useful LHI value.  (We use OILF for -1 instead, although
72; LHI might be better there too.)
73define i64 @f7(i64 %a) {
74; CHECK-LABEL: f7:
75; CHECK-NOT: ni
76; CHECK: lhi %r2, -2
77; CHECK: br %r14
78  %and = and i64 %a, 18446744069414584320
79  %or = or i64 %and, 4294967294
80  ret i64 %or
81}
82
83; Check that SRLG is still used if some of the high bits are known to be 0
84; (and so might be removed from the mask).
85define i64 @f8(i64 %a) {
86; CHECK-LABEL: f8:
87; CHECK: srlg %r2, %r2, 1
88; CHECK-NEXT: iilf %r2, 32768
89; CHECK: br %r14
90  %shifted = lshr i64 %a, 1
91  %and = and i64 %shifted, 18446744069414584320
92  %or = or i64 %and, 32768
93  ret i64 %or
94}
95
96; Repeat f8 with addition, which is known to be equivalent to OR in this case.
97define i64 @f9(i64 %a) {
98; CHECK-LABEL: f9:
99; CHECK: srlg %r2, %r2, 1
100; CHECK-NEXT: iilf %r2, 32768
101; CHECK: br %r14
102  %shifted = lshr i64 %a, 1
103  %and = and i64 %shifted, 18446744069414584320
104  %or = add i64 %and, 32768
105  ret i64 %or
106}
107
108; Repeat f8 with already-zero bits removed from the mask.
109define i64 @f10(i64 %a) {
110; CHECK-LABEL: f10:
111; CHECK: srlg %r2, %r2, 1
112; CHECK-NEXT: iilf %r2, 32768
113; CHECK: br %r14
114  %shifted = lshr i64 %a, 1
115  %and = and i64 %shifted, 9223372032559808512
116  %or = or i64 %and, 32768
117  ret i64 %or
118}
119
120; Repeat f10 with addition, which is known to be equivalent to OR in this case.
121define i64 @f11(i64 %a) {
122; CHECK-LABEL: f11:
123; CHECK: srlg %r2, %r2, 1
124; CHECK-NEXT: iilf %r2, 32768
125; CHECK: br %r14
126  %shifted = lshr i64 %a, 1
127  %and = and i64 %shifted, 9223372032559808512
128  %or = add i64 %and, 32768
129  ret i64 %or
130}
131
132; Check the lowest useful IIHF value.
133define i64 @f12(i64 %a) {
134; CHECK-LABEL: f12:
135; CHECK-NOT: ni
136; CHECK: iihf %r2, 1
137; CHECK: br %r14
138  %and = and i64 %a, 4294967295
139  %or = or i64 %and, 4294967296
140  ret i64 %or
141}
142
143; Check a value in which the lower 16 bits are clear.
144define i64 @f13(i64 %a) {
145; CHECK-LABEL: f13:
146; CHECK-NOT: ni
147; CHECK: iihf %r2, 2147483648
148; CHECK: br %r14
149  %and = and i64 %a, 4294967295
150  %or = or i64 %and, 9223372036854775808
151  ret i64 %or
152}
153
154; Check the highest useful IIHF value (0xfffffffe).
155define i64 @f14(i64 %a) {
156; CHECK-LABEL: f14:
157; CHECK-NOT: ni
158; CHECK: iihf %r2, 4294967294
159; CHECK: br %r14
160  %and = and i64 %a, 4294967295
161  %or = or i64 %and, 18446744065119617024
162  ret i64 %or
163}
164
165; Check a case in which some of the low 32 bits are known to be clear,
166; and so could be removed from the AND mask.
167define i64 @f15(i64 %a) {
168; CHECK-LABEL: f15:
169; CHECK: sllg %r2, %r2, 1
170; CHECK-NEXT: iihf %r2, 1
171; CHECK: br %r14
172  %shifted = shl i64 %a, 1
173  %and = and i64 %shifted, 4294967295
174  %or = or i64 %and, 4294967296
175  ret i64 %or
176}
177
178; Repeat f15 with the zero bits explicitly removed from the mask.
179define i64 @f16(i64 %a) {
180; CHECK-LABEL: f16:
181; CHECK: sllg %r2, %r2, 1
182; CHECK-NEXT: iihf %r2, 1
183; CHECK: br %r14
184  %shifted = shl i64 %a, 1
185  %and = and i64 %shifted, 4294967294
186  %or = or i64 %and, 4294967296
187  ret i64 %or
188}
189
190; Check concatenation of two i32s.
191define i64 @f17(i32 %a) {
192; CHECK-LABEL: f17:
193; CHECK: msr %r2, %r2
194; CHECK-NEXT: iihf %r2, 1
195; CHECK: br %r14
196  %mul = mul i32 %a, %a
197  %ext = zext i32 %mul to i64
198  %or = or i64 %ext, 4294967296
199  ret i64 %or
200}
201
202; Repeat f17 with the operands reversed.
203define i64 @f18(i32 %a) {
204; CHECK-LABEL: f18:
205; CHECK: msr %r2, %r2
206; CHECK-NEXT: iihf %r2, 1
207; CHECK: br %r14
208  %mul = mul i32 %a, %a
209  %ext = zext i32 %mul to i64
210  %or = or i64 4294967296, %ext
211  ret i64 %or
212}
213
214; The truncation here isn't free; we need an explicit zero extension.
215define i64 @f19(i32 %a) {
216; CHECK-LABEL: f19:
217; CHECK: llgcr %r2, %r2
218; CHECK: oihl %r2, 1
219; CHECK: br %r14
220  %trunc = trunc i32 %a to i8
221  %ext = zext i8 %trunc to i64
222  %or = or i64 %ext, 4294967296
223  ret i64 %or
224}
225