19e3577ffSUlrich Weigand; Test insertions of memory into the low byte of an i32.
29e3577ffSUlrich Weigand;
39e3577ffSUlrich Weigand; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
49e3577ffSUlrich Weigand
59e3577ffSUlrich Weigand; Check a plain insertion with (or (and ... -0xff) (zext (load ....))).
69e3577ffSUlrich Weigand; The whole sequence can be performed by IC.
79e3577ffSUlrich Weiganddefine i32 @f1(i32 %orig, i8 *%ptr) {
8d24ab20eSStephen Lin; CHECK-LABEL: f1:
99e3577ffSUlrich Weigand; CHECK-NOT: ni
109e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
119e3577ffSUlrich Weigand; CHECK: br %r14
12*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
139e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
149e3577ffSUlrich Weigand  %ptr1 = and i32 %orig, -256
159e3577ffSUlrich Weigand  %or = or i32 %ptr1, %ptr2
169e3577ffSUlrich Weigand  ret i32 %or
179e3577ffSUlrich Weigand}
189e3577ffSUlrich Weigand
199e3577ffSUlrich Weigand; Like f1, but with the operands reversed.
209e3577ffSUlrich Weiganddefine i32 @f2(i32 %orig, i8 *%ptr) {
21d24ab20eSStephen Lin; CHECK-LABEL: f2:
229e3577ffSUlrich Weigand; CHECK-NOT: ni
239e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
249e3577ffSUlrich Weigand; CHECK: br %r14
25*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
269e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
279e3577ffSUlrich Weigand  %ptr1 = and i32 %orig, -256
289e3577ffSUlrich Weigand  %or = or i32 %ptr2, %ptr1
299e3577ffSUlrich Weigand  ret i32 %or
309e3577ffSUlrich Weigand}
319e3577ffSUlrich Weigand
329e3577ffSUlrich Weigand; Check a case where more bits than lower 8 are masked out of the
339e3577ffSUlrich Weigand; register value.  We can use IC but must keep the original mask.
349e3577ffSUlrich Weiganddefine i32 @f3(i32 %orig, i8 *%ptr) {
35d24ab20eSStephen Lin; CHECK-LABEL: f3:
366a06ba36SRichard Sandiford; CHECK: nill %r2, 65024
379e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
389e3577ffSUlrich Weigand; CHECK: br %r14
39*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
409e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
419e3577ffSUlrich Weigand  %ptr1 = and i32 %orig, -512
429e3577ffSUlrich Weigand  %or = or i32 %ptr1, %ptr2
439e3577ffSUlrich Weigand  ret i32 %or
449e3577ffSUlrich Weigand}
459e3577ffSUlrich Weigand
469e3577ffSUlrich Weigand; Like f3, but with the operands reversed.
479e3577ffSUlrich Weiganddefine i32 @f4(i32 %orig, i8 *%ptr) {
48d24ab20eSStephen Lin; CHECK-LABEL: f4:
496a06ba36SRichard Sandiford; CHECK: nill %r2, 65024
509e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
519e3577ffSUlrich Weigand; CHECK: br %r14
52*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
539e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
549e3577ffSUlrich Weigand  %ptr1 = and i32 %orig, -512
559e3577ffSUlrich Weigand  %or = or i32 %ptr2, %ptr1
569e3577ffSUlrich Weigand  ret i32 %or
579e3577ffSUlrich Weigand}
589e3577ffSUlrich Weigand
599e3577ffSUlrich Weigand; Check a case where the low 8 bits are cleared by a shift left.
609e3577ffSUlrich Weiganddefine i32 @f5(i32 %orig, i8 *%ptr) {
61d24ab20eSStephen Lin; CHECK-LABEL: f5:
629e3577ffSUlrich Weigand; CHECK: sll %r2, 8
639e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
649e3577ffSUlrich Weigand; CHECK: br %r14
65*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
669e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
679e3577ffSUlrich Weigand  %ptr1 = shl i32 %orig, 8
689e3577ffSUlrich Weigand  %or = or i32 %ptr1, %ptr2
699e3577ffSUlrich Weigand  ret i32 %or
709e3577ffSUlrich Weigand}
719e3577ffSUlrich Weigand
729e3577ffSUlrich Weigand; Like f5, but with the operands reversed.
739e3577ffSUlrich Weiganddefine i32 @f6(i32 %orig, i8 *%ptr) {
74d24ab20eSStephen Lin; CHECK-LABEL: f6:
759e3577ffSUlrich Weigand; CHECK: sll %r2, 8
769e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
779e3577ffSUlrich Weigand; CHECK: br %r14
78*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
799e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
809e3577ffSUlrich Weigand  %ptr1 = shl i32 %orig, 8
819e3577ffSUlrich Weigand  %or = or i32 %ptr2, %ptr1
829e3577ffSUlrich Weigand  ret i32 %or
839e3577ffSUlrich Weigand}
849e3577ffSUlrich Weigand
859e3577ffSUlrich Weigand; Check insertions into a constant.
869e3577ffSUlrich Weiganddefine i32 @f7(i32 %orig, i8 *%ptr) {
87d24ab20eSStephen Lin; CHECK-LABEL: f7:
889e3577ffSUlrich Weigand; CHECK: lhi %r2, 256
899e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
909e3577ffSUlrich Weigand; CHECK: br %r14
91*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
929e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
939e3577ffSUlrich Weigand  %or = or i32 %ptr2, 256
949e3577ffSUlrich Weigand  ret i32 %or
959e3577ffSUlrich Weigand}
969e3577ffSUlrich Weigand
979e3577ffSUlrich Weigand; Like f7, but with the operands reversed.
989e3577ffSUlrich Weiganddefine i32 @f8(i32 %orig, i8 *%ptr) {
99d24ab20eSStephen Lin; CHECK-LABEL: f8:
1009e3577ffSUlrich Weigand; CHECK: lhi %r2, 256
1019e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
1029e3577ffSUlrich Weigand; CHECK: br %r14
103*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1049e3577ffSUlrich Weigand  %ptr2 = zext i8 %val to i32
1059e3577ffSUlrich Weigand  %or = or i32 256, %ptr2
1069e3577ffSUlrich Weigand  ret i32 %or
1079e3577ffSUlrich Weigand}
1089e3577ffSUlrich Weigand
1099e3577ffSUlrich Weigand; Check the high end of the IC range.
1109e3577ffSUlrich Weiganddefine i32 @f9(i32 %orig, i8 *%src) {
111d24ab20eSStephen Lin; CHECK-LABEL: f9:
1129e3577ffSUlrich Weigand; CHECK: ic %r2, 4095(%r3)
1139e3577ffSUlrich Weigand; CHECK: br %r14
11479e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 4095
115*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1169e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1179e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1189e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1199e3577ffSUlrich Weigand  ret i32 %or
1209e3577ffSUlrich Weigand}
1219e3577ffSUlrich Weigand
1229e3577ffSUlrich Weigand; Check the next byte up, which should use ICY instead of IC.
1239e3577ffSUlrich Weiganddefine i32 @f10(i32 %orig, i8 *%src) {
124d24ab20eSStephen Lin; CHECK-LABEL: f10:
1259e3577ffSUlrich Weigand; CHECK: icy %r2, 4096(%r3)
1269e3577ffSUlrich Weigand; CHECK: br %r14
12779e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 4096
128*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1299e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1309e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1319e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1329e3577ffSUlrich Weigand  ret i32 %or
1339e3577ffSUlrich Weigand}
1349e3577ffSUlrich Weigand
1359e3577ffSUlrich Weigand; Check the high end of the ICY range.
1369e3577ffSUlrich Weiganddefine i32 @f11(i32 %orig, i8 *%src) {
137d24ab20eSStephen Lin; CHECK-LABEL: f11:
1389e3577ffSUlrich Weigand; CHECK: icy %r2, 524287(%r3)
1399e3577ffSUlrich Weigand; CHECK: br %r14
14079e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 524287
141*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1429e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1439e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1449e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1459e3577ffSUlrich Weigand  ret i32 %or
1469e3577ffSUlrich Weigand}
1479e3577ffSUlrich Weigand
1489e3577ffSUlrich Weigand; Check the next byte up, which needs separate address logic.
1499e3577ffSUlrich Weigand; Other sequences besides this one would be OK.
1509e3577ffSUlrich Weiganddefine i32 @f12(i32 %orig, i8 *%src) {
151d24ab20eSStephen Lin; CHECK-LABEL: f12:
1529e3577ffSUlrich Weigand; CHECK: agfi %r3, 524288
1539e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
1549e3577ffSUlrich Weigand; CHECK: br %r14
15579e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 524288
156*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1579e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1589e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1599e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1609e3577ffSUlrich Weigand  ret i32 %or
1619e3577ffSUlrich Weigand}
1629e3577ffSUlrich Weigand
1639e3577ffSUlrich Weigand; Check the high end of the negative ICY range.
1649e3577ffSUlrich Weiganddefine i32 @f13(i32 %orig, i8 *%src) {
165d24ab20eSStephen Lin; CHECK-LABEL: f13:
1669e3577ffSUlrich Weigand; CHECK: icy %r2, -1(%r3)
1679e3577ffSUlrich Weigand; CHECK: br %r14
16879e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 -1
169*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1709e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1719e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1729e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1739e3577ffSUlrich Weigand  ret i32 %or
1749e3577ffSUlrich Weigand}
1759e3577ffSUlrich Weigand
1769e3577ffSUlrich Weigand; Check the low end of the ICY range.
1779e3577ffSUlrich Weiganddefine i32 @f14(i32 %orig, i8 *%src) {
178d24ab20eSStephen Lin; CHECK-LABEL: f14:
1799e3577ffSUlrich Weigand; CHECK: icy %r2, -524288(%r3)
1809e3577ffSUlrich Weigand; CHECK: br %r14
18179e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 -524288
182*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1839e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1849e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
1859e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
1869e3577ffSUlrich Weigand  ret i32 %or
1879e3577ffSUlrich Weigand}
1889e3577ffSUlrich Weigand
1899e3577ffSUlrich Weigand; Check the next byte down, which needs separate address logic.
1909e3577ffSUlrich Weigand; Other sequences besides this one would be OK.
1919e3577ffSUlrich Weiganddefine i32 @f15(i32 %orig, i8 *%src) {
192d24ab20eSStephen Lin; CHECK-LABEL: f15:
1939e3577ffSUlrich Weigand; CHECK: agfi %r3, -524289
1949e3577ffSUlrich Weigand; CHECK: ic %r2, 0(%r3)
1959e3577ffSUlrich Weigand; CHECK: br %r14
19679e6c749SDavid Blaikie  %ptr = getelementptr i8, i8 *%src, i64 -524289
197*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr
1989e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
1999e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
2009e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
2019e3577ffSUlrich Weigand  ret i32 %or
2029e3577ffSUlrich Weigand}
2039e3577ffSUlrich Weigand
2049e3577ffSUlrich Weigand; Check that IC allows an index.
2059e3577ffSUlrich Weiganddefine i32 @f16(i32 %orig, i8 *%src, i64 %index) {
206d24ab20eSStephen Lin; CHECK-LABEL: f16:
2079e3577ffSUlrich Weigand; CHECK: ic %r2, 4095({{%r4,%r3|%r3,%r4}})
2089e3577ffSUlrich Weigand; CHECK: br %r14
20979e6c749SDavid Blaikie  %ptr1 = getelementptr i8, i8 *%src, i64 %index
21079e6c749SDavid Blaikie  %ptr2 = getelementptr i8, i8 *%ptr1, i64 4095
211*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr2
2129e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
2139e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
2149e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
2159e3577ffSUlrich Weigand  ret i32 %or
2169e3577ffSUlrich Weigand}
2179e3577ffSUlrich Weigand
2189e3577ffSUlrich Weigand; Check that ICY allows an index.
2199e3577ffSUlrich Weiganddefine i32 @f17(i32 %orig, i8 *%src, i64 %index) {
220d24ab20eSStephen Lin; CHECK-LABEL: f17:
2219e3577ffSUlrich Weigand; CHECK: icy %r2, 4096({{%r4,%r3|%r3,%r4}})
2229e3577ffSUlrich Weigand; CHECK: br %r14
22379e6c749SDavid Blaikie  %ptr1 = getelementptr i8, i8 *%src, i64 %index
22479e6c749SDavid Blaikie  %ptr2 = getelementptr i8, i8 *%ptr1, i64 4096
225*a79ac14fSDavid Blaikie  %val = load i8, i8 *%ptr2
2269e3577ffSUlrich Weigand  %src2 = zext i8 %val to i32
2279e3577ffSUlrich Weigand  %src1 = and i32 %orig, -256
2289e3577ffSUlrich Weigand  %or = or i32 %src2, %src1
2299e3577ffSUlrich Weigand  ret i32 %or
2309e3577ffSUlrich Weigand}
231