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