xref: /aosp_15_r20/external/llvm/test/CodeGen/SystemZ/insert-02.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; Test insertions of memory into the low byte 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; Check a plain insertion with (or (and ... -0xff) (zext (load ....))).
6*9880d681SAndroid Build Coastguard Worker; The whole sequence can be performed by IC.
7*9880d681SAndroid Build Coastguard Workerdefine i64 @f1(i64 %orig, i8 *%ptr) {
8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1:
9*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ni
10*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
11*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
12*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
13*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
14*9880d681SAndroid Build Coastguard Worker  %ptr1 = and i64 %orig, -256
15*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr1, %ptr2
16*9880d681SAndroid Build Coastguard Worker  ret i64 %or
17*9880d681SAndroid Build Coastguard Worker}
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; Like f1, but with the operands reversed.
20*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %orig, i8 *%ptr) {
21*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2:
22*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: ni
23*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
24*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
25*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
26*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
27*9880d681SAndroid Build Coastguard Worker  %ptr1 = and i64 %orig, -256
28*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr2, %ptr1
29*9880d681SAndroid Build Coastguard Worker  ret i64 %or
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker; Check a case where more bits than lower 8 are masked out of the
33*9880d681SAndroid Build Coastguard Worker; register value.  We can use IC but must keep the original mask.
34*9880d681SAndroid Build Coastguard Workerdefine i64 @f3(i64 %orig, i8 *%ptr) {
35*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3:
36*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65024
37*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
38*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
39*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
40*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
41*9880d681SAndroid Build Coastguard Worker  %ptr1 = and i64 %orig, -512
42*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr1, %ptr2
43*9880d681SAndroid Build Coastguard Worker  ret i64 %or
44*9880d681SAndroid Build Coastguard Worker}
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; Like f3, but with the operands reversed.
47*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %orig, i8 *%ptr) {
48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4:
49*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65024
50*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
51*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
52*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
53*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
54*9880d681SAndroid Build Coastguard Worker  %ptr1 = and i64 %orig, -512
55*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr2, %ptr1
56*9880d681SAndroid Build Coastguard Worker  ret i64 %or
57*9880d681SAndroid Build Coastguard Worker}
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker; Check a case where the low 8 bits are cleared by a shift left.
60*9880d681SAndroid Build Coastguard Workerdefine i64 @f5(i64 %orig, i8 *%ptr) {
61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5:
62*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2, %r2, 8
63*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
64*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
65*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
66*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
67*9880d681SAndroid Build Coastguard Worker  %ptr1 = shl i64 %orig, 8
68*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr1, %ptr2
69*9880d681SAndroid Build Coastguard Worker  ret i64 %or
70*9880d681SAndroid Build Coastguard Worker}
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker; Like f5, but with the operands reversed.
73*9880d681SAndroid Build Coastguard Workerdefine i64 @f6(i64 %orig, i8 *%ptr) {
74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6:
75*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2, %r2, 8
76*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
77*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
78*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
79*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
80*9880d681SAndroid Build Coastguard Worker  %ptr1 = shl i64 %orig, 8
81*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr2, %ptr1
82*9880d681SAndroid Build Coastguard Worker  ret i64 %or
83*9880d681SAndroid Build Coastguard Worker}
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker; Check insertions into a constant.
86*9880d681SAndroid Build Coastguard Workerdefine i64 @f7(i64 %orig, i8 *%ptr) {
87*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7:
88*9880d681SAndroid Build Coastguard Worker; CHECK: lghi %r2, 256
89*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
90*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
91*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
92*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
93*9880d681SAndroid Build Coastguard Worker  %or = or i64 %ptr2, 256
94*9880d681SAndroid Build Coastguard Worker  ret i64 %or
95*9880d681SAndroid Build Coastguard Worker}
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker; Like f7, but with the operands reversed.
98*9880d681SAndroid Build Coastguard Workerdefine i64 @f8(i64 %orig, i8 *%ptr) {
99*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8:
100*9880d681SAndroid Build Coastguard Worker; CHECK: lghi %r2, 256
101*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
102*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
103*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
104*9880d681SAndroid Build Coastguard Worker  %ptr2 = zext i8 %val to i64
105*9880d681SAndroid Build Coastguard Worker  %or = or i64 256, %ptr2
106*9880d681SAndroid Build Coastguard Worker  ret i64 %or
107*9880d681SAndroid Build Coastguard Worker}
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker; Check the high end of the IC range.
110*9880d681SAndroid Build Coastguard Workerdefine i64 @f9(i64 %orig, i8 *%src) {
111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9:
112*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 4095(%r3)
113*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
114*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 4095
115*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
116*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
117*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
118*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
119*9880d681SAndroid Build Coastguard Worker  ret i64 %or
120*9880d681SAndroid Build Coastguard Worker}
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker; Check the next byte up, which should use ICY instead of IC.
123*9880d681SAndroid Build Coastguard Workerdefine i64 @f10(i64 %orig, i8 *%src) {
124*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10:
125*9880d681SAndroid Build Coastguard Worker; CHECK: icy %r2, 4096(%r3)
126*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
127*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 4096
128*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
129*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
130*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
131*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
132*9880d681SAndroid Build Coastguard Worker  ret i64 %or
133*9880d681SAndroid Build Coastguard Worker}
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker; Check the high end of the ICY range.
136*9880d681SAndroid Build Coastguard Workerdefine i64 @f11(i64 %orig, i8 *%src) {
137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11:
138*9880d681SAndroid Build Coastguard Worker; CHECK: icy %r2, 524287(%r3)
139*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
140*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 524287
141*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
142*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
143*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
144*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
145*9880d681SAndroid Build Coastguard Worker  ret i64 %or
146*9880d681SAndroid Build Coastguard Worker}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker; Check the next byte up, which needs separate address logic.
149*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK.
150*9880d681SAndroid Build Coastguard Workerdefine i64 @f12(i64 %orig, i8 *%src) {
151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12:
152*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r3, 524288
153*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
154*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
155*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 524288
156*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
157*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
158*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
159*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
160*9880d681SAndroid Build Coastguard Worker  ret i64 %or
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker; Check the high end of the negative ICY range.
164*9880d681SAndroid Build Coastguard Workerdefine i64 @f13(i64 %orig, i8 *%src) {
165*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13:
166*9880d681SAndroid Build Coastguard Worker; CHECK: icy %r2, -1(%r3)
167*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
168*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 -1
169*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
170*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
171*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
172*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
173*9880d681SAndroid Build Coastguard Worker  ret i64 %or
174*9880d681SAndroid Build Coastguard Worker}
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker; Check the low end of the ICY range.
177*9880d681SAndroid Build Coastguard Workerdefine i64 @f14(i64 %orig, i8 *%src) {
178*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14:
179*9880d681SAndroid Build Coastguard Worker; CHECK: icy %r2, -524288(%r3)
180*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
181*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 -524288
182*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
183*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
184*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
185*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
186*9880d681SAndroid Build Coastguard Worker  ret i64 %or
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker; Check the next byte down, which needs separate address logic.
190*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK.
191*9880d681SAndroid Build Coastguard Workerdefine i64 @f15(i64 %orig, i8 *%src) {
192*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15:
193*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r3, -524289
194*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 0(%r3)
195*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
196*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i8, i8 *%src, i64 -524289
197*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr
198*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
199*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
200*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
201*9880d681SAndroid Build Coastguard Worker  ret i64 %or
202*9880d681SAndroid Build Coastguard Worker}
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker; Check that IC allows an index.
205*9880d681SAndroid Build Coastguard Workerdefine i64 @f16(i64 %orig, i8 *%src, i64 %index) {
206*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16:
207*9880d681SAndroid Build Coastguard Worker; CHECK: ic %r2, 4095({{%r4,%r3|%r3,%r4}})
208*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
209*9880d681SAndroid Build Coastguard Worker  %ptr1 = getelementptr i8, i8 *%src, i64 %index
210*9880d681SAndroid Build Coastguard Worker  %ptr2 = getelementptr i8, i8 *%ptr1, i64 4095
211*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr2
212*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
213*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
214*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
215*9880d681SAndroid Build Coastguard Worker  ret i64 %or
216*9880d681SAndroid Build Coastguard Worker}
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker; Check that ICY allows an index.
219*9880d681SAndroid Build Coastguard Workerdefine i64 @f17(i64 %orig, i8 *%src, i64 %index) {
220*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17:
221*9880d681SAndroid Build Coastguard Worker; CHECK: icy %r2, 4096({{%r4,%r3|%r3,%r4}})
222*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
223*9880d681SAndroid Build Coastguard Worker  %ptr1 = getelementptr i8, i8 *%src, i64 %index
224*9880d681SAndroid Build Coastguard Worker  %ptr2 = getelementptr i8, i8 *%ptr1, i64 4096
225*9880d681SAndroid Build Coastguard Worker  %val = load i8 , i8 *%ptr2
226*9880d681SAndroid Build Coastguard Worker  %src2 = zext i8 %val to i64
227*9880d681SAndroid Build Coastguard Worker  %src1 = and i64 %orig, -256
228*9880d681SAndroid Build Coastguard Worker  %or = or i64 %src2, %src1
229*9880d681SAndroid Build Coastguard Worker  ret i64 %or
230*9880d681SAndroid Build Coastguard Worker}
231