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