1 ; Test insertions of memory into the low byte of an i32.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Check a plain insertion with (or (and ... -0xff) (zext (load ....))).
6 ; The whole sequence can be performed by IC.
7 define i32 @f1(i32 %orig, ptr %ptr) {
10 ; CHECK: ic %r2, 0(%r3)
12 %val = load i8, ptr %ptr
13 %ptr2 = zext i8 %val to i32
14 %ptr1 = and i32 %orig, -256
15 %or = or i32 %ptr1, %ptr2
19 ; Like f1, but with the operands reversed.
20 define i32 @f2(i32 %orig, ptr %ptr) {
23 ; CHECK: ic %r2, 0(%r3)
25 %val = load i8, ptr %ptr
26 %ptr2 = zext i8 %val to i32
27 %ptr1 = and i32 %orig, -256
28 %or = or i32 %ptr2, %ptr1
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.
34 define i32 @f3(i32 %orig, ptr %ptr) {
36 ; CHECK: nill %r2, 65024
37 ; CHECK: ic %r2, 0(%r3)
39 %val = load i8, ptr %ptr
40 %ptr2 = zext i8 %val to i32
41 %ptr1 = and i32 %orig, -512
42 %or = or i32 %ptr1, %ptr2
46 ; Like f3, but with the operands reversed.
47 define i32 @f4(i32 %orig, ptr %ptr) {
49 ; CHECK: nill %r2, 65024
50 ; CHECK: ic %r2, 0(%r3)
52 %val = load i8, ptr %ptr
53 %ptr2 = zext i8 %val to i32
54 %ptr1 = and i32 %orig, -512
55 %or = or i32 %ptr2, %ptr1
59 ; Check a case where the low 8 bits are cleared by a shift left.
60 define i32 @f5(i32 %orig, ptr %ptr) {
63 ; CHECK: ic %r2, 0(%r3)
65 %val = load i8, ptr %ptr
66 %ptr2 = zext i8 %val to i32
67 %ptr1 = shl i32 %orig, 8
68 %or = or i32 %ptr1, %ptr2
72 ; Like f5, but with the operands reversed.
73 define i32 @f6(i32 %orig, ptr %ptr) {
76 ; CHECK: ic %r2, 0(%r3)
78 %val = load i8, ptr %ptr
79 %ptr2 = zext i8 %val to i32
80 %ptr1 = shl i32 %orig, 8
81 %or = or i32 %ptr2, %ptr1
85 ; Check insertions into a constant.
86 define i32 @f7(i32 %orig, ptr %ptr) {
89 ; CHECK: ic %r2, 0(%r3)
91 %val = load i8, ptr %ptr
92 %ptr2 = zext i8 %val to i32
93 %or = or i32 %ptr2, 256
97 ; Like f7, but with the operands reversed.
98 define i32 @f8(i32 %orig, ptr %ptr) {
100 ; CHECK: lhi %r2, 256
101 ; CHECK: ic %r2, 0(%r3)
103 %val = load i8, ptr %ptr
104 %ptr2 = zext i8 %val to i32
105 %or = or i32 256, %ptr2
109 ; Check the high end of the IC range.
110 define i32 @f9(i32 %orig, ptr %src) {
112 ; CHECK: ic %r2, 4095(%r3)
114 %ptr = getelementptr i8, ptr %src, i64 4095
115 %val = load i8, ptr %ptr
116 %src2 = zext i8 %val to i32
117 %src1 = and i32 %orig, -256
118 %or = or i32 %src2, %src1
122 ; Check the next byte up, which should use ICY instead of IC.
123 define i32 @f10(i32 %orig, ptr %src) {
125 ; CHECK: icy %r2, 4096(%r3)
127 %ptr = getelementptr i8, ptr %src, i64 4096
128 %val = load i8, ptr %ptr
129 %src2 = zext i8 %val to i32
130 %src1 = and i32 %orig, -256
131 %or = or i32 %src2, %src1
135 ; Check the high end of the ICY range.
136 define i32 @f11(i32 %orig, ptr %src) {
138 ; CHECK: icy %r2, 524287(%r3)
140 %ptr = getelementptr i8, ptr %src, i64 524287
141 %val = load i8, ptr %ptr
142 %src2 = zext i8 %val to i32
143 %src1 = and i32 %orig, -256
144 %or = or i32 %src2, %src1
148 ; Check the next byte up, which needs separate address logic.
149 ; Other sequences besides this one would be OK.
150 define i32 @f12(i32 %orig, ptr %src) {
152 ; CHECK: agfi %r3, 524288
153 ; CHECK: ic %r2, 0(%r3)
155 %ptr = getelementptr i8, ptr %src, i64 524288
156 %val = load i8, ptr %ptr
157 %src2 = zext i8 %val to i32
158 %src1 = and i32 %orig, -256
159 %or = or i32 %src2, %src1
163 ; Check the high end of the negative ICY range.
164 define i32 @f13(i32 %orig, ptr %src) {
166 ; CHECK: icy %r2, -1(%r3)
168 %ptr = getelementptr i8, ptr %src, i64 -1
169 %val = load i8, ptr %ptr
170 %src2 = zext i8 %val to i32
171 %src1 = and i32 %orig, -256
172 %or = or i32 %src2, %src1
176 ; Check the low end of the ICY range.
177 define i32 @f14(i32 %orig, ptr %src) {
179 ; CHECK: icy %r2, -524288(%r3)
181 %ptr = getelementptr i8, ptr %src, i64 -524288
182 %val = load i8, ptr %ptr
183 %src2 = zext i8 %val to i32
184 %src1 = and i32 %orig, -256
185 %or = or i32 %src2, %src1
189 ; Check the next byte down, which needs separate address logic.
190 ; Other sequences besides this one would be OK.
191 define i32 @f15(i32 %orig, ptr %src) {
193 ; CHECK: agfi %r3, -524289
194 ; CHECK: ic %r2, 0(%r3)
196 %ptr = getelementptr i8, ptr %src, i64 -524289
197 %val = load i8, ptr %ptr
198 %src2 = zext i8 %val to i32
199 %src1 = and i32 %orig, -256
200 %or = or i32 %src2, %src1
204 ; Check that IC allows an index.
205 define i32 @f16(i32 %orig, ptr %src, i64 %index) {
207 ; CHECK: ic %r2, 4095({{%r4,%r3|%r3,%r4}})
209 %ptr1 = getelementptr i8, ptr %src, i64 %index
210 %ptr2 = getelementptr i8, ptr %ptr1, i64 4095
211 %val = load i8, ptr %ptr2
212 %src2 = zext i8 %val to i32
213 %src1 = and i32 %orig, -256
214 %or = or i32 %src2, %src1
218 ; Check that ICY allows an index.
219 define i32 @f17(i32 %orig, ptr %src, i64 %index) {
221 ; CHECK: icy %r2, 4096({{%r4,%r3|%r3,%r4}})
223 %ptr1 = getelementptr i8, ptr %src, i64 %index
224 %ptr2 = getelementptr i8, ptr %ptr1, i64 4096
225 %val = load i8, ptr %ptr2
226 %src2 = zext i8 %val to i32
227 %src1 = and i32 %orig, -256
228 %or = or i32 %src2, %src1