19e3577ffSUlrich Weigand; Test insertions of 32-bit constants into one half of an i64.
29e3577ffSUlrich Weigand;
39e3577ffSUlrich Weigand; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
49e3577ffSUlrich Weigand
59e3577ffSUlrich Weigand; Prefer LHI over IILF for signed 16-bit constants.
69e3577ffSUlrich Weiganddefine i64 @f1(i64 %a) {
7*d24ab20eSStephen Lin; CHECK-LABEL: f1:
89e3577ffSUlrich Weigand; CHECK-NOT: ni
99e3577ffSUlrich Weigand; CHECK: lhi %r2, 1
109e3577ffSUlrich Weigand; CHECK: br %r14
119e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
129e3577ffSUlrich Weigand  %or = or i64 %and, 1
139e3577ffSUlrich Weigand  ret i64 %or
149e3577ffSUlrich Weigand}
159e3577ffSUlrich Weigand
169e3577ffSUlrich Weigand; Check the high end of the LHI range.
179e3577ffSUlrich Weiganddefine i64 @f2(i64 %a) {
18*d24ab20eSStephen Lin; CHECK-LABEL: f2:
199e3577ffSUlrich Weigand; CHECK-NOT: ni
209e3577ffSUlrich Weigand; CHECK: lhi %r2, 32767
219e3577ffSUlrich Weigand; CHECK: br %r14
229e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
239e3577ffSUlrich Weigand  %or = or i64 %and, 32767
249e3577ffSUlrich Weigand  ret i64 %or
259e3577ffSUlrich Weigand}
269e3577ffSUlrich Weigand
279e3577ffSUlrich Weigand; Check the next value up, which should use IILF instead.
289e3577ffSUlrich Weiganddefine i64 @f3(i64 %a) {
29*d24ab20eSStephen Lin; CHECK-LABEL: f3:
309e3577ffSUlrich Weigand; CHECK-NOT: ni
319e3577ffSUlrich Weigand; CHECK: iilf %r2, 32768
329e3577ffSUlrich Weigand; CHECK: br %r14
339e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
349e3577ffSUlrich Weigand  %or = or i64 %and, 32768
359e3577ffSUlrich Weigand  ret i64 %or
369e3577ffSUlrich Weigand}
379e3577ffSUlrich Weigand
389e3577ffSUlrich Weigand; Check a value in which the lower 16 bits are clear.
399e3577ffSUlrich Weiganddefine i64 @f4(i64 %a) {
40*d24ab20eSStephen Lin; CHECK-LABEL: f4:
419e3577ffSUlrich Weigand; CHECK-NOT: ni
429e3577ffSUlrich Weigand; CHECK: iilf %r2, 65536
439e3577ffSUlrich Weigand; CHECK: br %r14
449e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
459e3577ffSUlrich Weigand  %or = or i64 %and, 65536
469e3577ffSUlrich Weigand  ret i64 %or
479e3577ffSUlrich Weigand}
489e3577ffSUlrich Weigand
499e3577ffSUlrich Weigand; Check the highest useful IILF value (-0x8001).
509e3577ffSUlrich Weiganddefine i64 @f5(i64 %a) {
51*d24ab20eSStephen Lin; CHECK-LABEL: f5:
529e3577ffSUlrich Weigand; CHECK-NOT: ni
539e3577ffSUlrich Weigand; CHECK: iilf %r2, 4294934527
549e3577ffSUlrich Weigand; CHECK: br %r14
559e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
569e3577ffSUlrich Weigand  %or = or i64 %and, 4294934527
579e3577ffSUlrich Weigand  ret i64 %or
589e3577ffSUlrich Weigand}
599e3577ffSUlrich Weigand
609e3577ffSUlrich Weigand; Check the next value up, which should use LHI instead.
619e3577ffSUlrich Weiganddefine i64 @f6(i64 %a) {
62*d24ab20eSStephen Lin; CHECK-LABEL: f6:
639e3577ffSUlrich Weigand; CHECK-NOT: ni
649e3577ffSUlrich Weigand; CHECK: lhi %r2, -32768
659e3577ffSUlrich Weigand; CHECK: br %r14
669e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
679e3577ffSUlrich Weigand  %or = or i64 %and, 4294934528
689e3577ffSUlrich Weigand  ret i64 %or
699e3577ffSUlrich Weigand}
709e3577ffSUlrich Weigand
719e3577ffSUlrich Weigand; Check the highest useful LHI value.  (We use OILF for -1 instead, although
729e3577ffSUlrich Weigand; LHI might be better there too.)
739e3577ffSUlrich Weiganddefine i64 @f7(i64 %a) {
74*d24ab20eSStephen Lin; CHECK-LABEL: f7:
759e3577ffSUlrich Weigand; CHECK-NOT: ni
769e3577ffSUlrich Weigand; CHECK: lhi %r2, -2
779e3577ffSUlrich Weigand; CHECK: br %r14
789e3577ffSUlrich Weigand  %and = and i64 %a, 18446744069414584320
799e3577ffSUlrich Weigand  %or = or i64 %and, 4294967294
809e3577ffSUlrich Weigand  ret i64 %or
819e3577ffSUlrich Weigand}
829e3577ffSUlrich Weigand
839e3577ffSUlrich Weigand; Check that SRLG is still used if some of the high bits are known to be 0
849e3577ffSUlrich Weigand; (and so might be removed from the mask).
859e3577ffSUlrich Weiganddefine i64 @f8(i64 %a) {
86*d24ab20eSStephen Lin; CHECK-LABEL: f8:
879e3577ffSUlrich Weigand; CHECK: srlg %r2, %r2, 1
889e3577ffSUlrich Weigand; CHECK-NEXT: iilf %r2, 32768
899e3577ffSUlrich Weigand; CHECK: br %r14
909e3577ffSUlrich Weigand  %shifted = lshr i64 %a, 1
919e3577ffSUlrich Weigand  %and = and i64 %shifted, 18446744069414584320
929e3577ffSUlrich Weigand  %or = or i64 %and, 32768
939e3577ffSUlrich Weigand  ret i64 %or
949e3577ffSUlrich Weigand}
959e3577ffSUlrich Weigand
969e3577ffSUlrich Weigand; Repeat f8 with addition, which is known to be equivalent to OR in this case.
979e3577ffSUlrich Weiganddefine i64 @f9(i64 %a) {
98*d24ab20eSStephen Lin; CHECK-LABEL: f9:
999e3577ffSUlrich Weigand; CHECK: srlg %r2, %r2, 1
1009e3577ffSUlrich Weigand; CHECK-NEXT: iilf %r2, 32768
1019e3577ffSUlrich Weigand; CHECK: br %r14
1029e3577ffSUlrich Weigand  %shifted = lshr i64 %a, 1
1039e3577ffSUlrich Weigand  %and = and i64 %shifted, 18446744069414584320
1049e3577ffSUlrich Weigand  %or = add i64 %and, 32768
1059e3577ffSUlrich Weigand  ret i64 %or
1069e3577ffSUlrich Weigand}
1079e3577ffSUlrich Weigand
1089e3577ffSUlrich Weigand; Repeat f8 with already-zero bits removed from the mask.
1099e3577ffSUlrich Weiganddefine i64 @f10(i64 %a) {
110*d24ab20eSStephen Lin; CHECK-LABEL: f10:
1119e3577ffSUlrich Weigand; CHECK: srlg %r2, %r2, 1
1129e3577ffSUlrich Weigand; CHECK-NEXT: iilf %r2, 32768
1139e3577ffSUlrich Weigand; CHECK: br %r14
1149e3577ffSUlrich Weigand  %shifted = lshr i64 %a, 1
1159e3577ffSUlrich Weigand  %and = and i64 %shifted, 9223372032559808512
1169e3577ffSUlrich Weigand  %or = or i64 %and, 32768
1179e3577ffSUlrich Weigand  ret i64 %or
1189e3577ffSUlrich Weigand}
1199e3577ffSUlrich Weigand
1209e3577ffSUlrich Weigand; Repeat f10 with addition, which is known to be equivalent to OR in this case.
1219e3577ffSUlrich Weiganddefine i64 @f11(i64 %a) {
122*d24ab20eSStephen Lin; CHECK-LABEL: f11:
1239e3577ffSUlrich Weigand; CHECK: srlg %r2, %r2, 1
1249e3577ffSUlrich Weigand; CHECK-NEXT: iilf %r2, 32768
1259e3577ffSUlrich Weigand; CHECK: br %r14
1269e3577ffSUlrich Weigand  %shifted = lshr i64 %a, 1
1279e3577ffSUlrich Weigand  %and = and i64 %shifted, 9223372032559808512
1289e3577ffSUlrich Weigand  %or = add i64 %and, 32768
1299e3577ffSUlrich Weigand  ret i64 %or
1309e3577ffSUlrich Weigand}
1319e3577ffSUlrich Weigand
1329e3577ffSUlrich Weigand; Check the lowest useful IIHF value.
1339e3577ffSUlrich Weiganddefine i64 @f12(i64 %a) {
134*d24ab20eSStephen Lin; CHECK-LABEL: f12:
1359e3577ffSUlrich Weigand; CHECK-NOT: ni
1369e3577ffSUlrich Weigand; CHECK: iihf %r2, 1
1379e3577ffSUlrich Weigand; CHECK: br %r14
1389e3577ffSUlrich Weigand  %and = and i64 %a, 4294967295
1399e3577ffSUlrich Weigand  %or = or i64 %and, 4294967296
1409e3577ffSUlrich Weigand  ret i64 %or
1419e3577ffSUlrich Weigand}
1429e3577ffSUlrich Weigand
1439e3577ffSUlrich Weigand; Check a value in which the lower 16 bits are clear.
1449e3577ffSUlrich Weiganddefine i64 @f13(i64 %a) {
145*d24ab20eSStephen Lin; CHECK-LABEL: f13:
1469e3577ffSUlrich Weigand; CHECK-NOT: ni
1479e3577ffSUlrich Weigand; CHECK: iihf %r2, 2147483648
1489e3577ffSUlrich Weigand; CHECK: br %r14
1499e3577ffSUlrich Weigand  %and = and i64 %a, 4294967295
1509e3577ffSUlrich Weigand  %or = or i64 %and, 9223372036854775808
1519e3577ffSUlrich Weigand  ret i64 %or
1529e3577ffSUlrich Weigand}
1539e3577ffSUlrich Weigand
1549e3577ffSUlrich Weigand; Check the highest useful IIHF value (0xfffffffe).
1559e3577ffSUlrich Weiganddefine i64 @f14(i64 %a) {
156*d24ab20eSStephen Lin; CHECK-LABEL: f14:
1579e3577ffSUlrich Weigand; CHECK-NOT: ni
1589e3577ffSUlrich Weigand; CHECK: iihf %r2, 4294967294
1599e3577ffSUlrich Weigand; CHECK: br %r14
1609e3577ffSUlrich Weigand  %and = and i64 %a, 4294967295
1619e3577ffSUlrich Weigand  %or = or i64 %and, 18446744065119617024
1629e3577ffSUlrich Weigand  ret i64 %or
1639e3577ffSUlrich Weigand}
1649e3577ffSUlrich Weigand
1659e3577ffSUlrich Weigand; Check a case in which some of the low 32 bits are known to be clear,
1669e3577ffSUlrich Weigand; and so could be removed from the AND mask.
1679e3577ffSUlrich Weiganddefine i64 @f15(i64 %a) {
168*d24ab20eSStephen Lin; CHECK-LABEL: f15:
1699e3577ffSUlrich Weigand; CHECK: sllg %r2, %r2, 1
1709e3577ffSUlrich Weigand; CHECK-NEXT: iihf %r2, 1
1719e3577ffSUlrich Weigand; CHECK: br %r14
1729e3577ffSUlrich Weigand  %shifted = shl i64 %a, 1
1739e3577ffSUlrich Weigand  %and = and i64 %shifted, 4294967295
1749e3577ffSUlrich Weigand  %or = or i64 %and, 4294967296
1759e3577ffSUlrich Weigand  ret i64 %or
1769e3577ffSUlrich Weigand}
1779e3577ffSUlrich Weigand
1789e3577ffSUlrich Weigand; Repeat f15 with the zero bits explicitly removed from the mask.
1799e3577ffSUlrich Weiganddefine i64 @f16(i64 %a) {
180*d24ab20eSStephen Lin; CHECK-LABEL: f16:
1819e3577ffSUlrich Weigand; CHECK: sllg %r2, %r2, 1
1829e3577ffSUlrich Weigand; CHECK-NEXT: iihf %r2, 1
1839e3577ffSUlrich Weigand; CHECK: br %r14
1849e3577ffSUlrich Weigand  %shifted = shl i64 %a, 1
1859e3577ffSUlrich Weigand  %and = and i64 %shifted, 4294967294
1869e3577ffSUlrich Weigand  %or = or i64 %and, 4294967296
1879e3577ffSUlrich Weigand  ret i64 %or
1889e3577ffSUlrich Weigand}
1899e3577ffSUlrich Weigand
1909e3577ffSUlrich Weigand; Check concatenation of two i32s.
1919e3577ffSUlrich Weiganddefine i64 @f17(i32 %a) {
192*d24ab20eSStephen Lin; CHECK-LABEL: f17:
1939e3577ffSUlrich Weigand; CHECK: msr %r2, %r2
1949e3577ffSUlrich Weigand; CHECK-NEXT: iihf %r2, 1
1959e3577ffSUlrich Weigand; CHECK: br %r14
1969e3577ffSUlrich Weigand  %mul = mul i32 %a, %a
1979e3577ffSUlrich Weigand  %ext = zext i32 %mul to i64
1989e3577ffSUlrich Weigand  %or = or i64 %ext, 4294967296
1999e3577ffSUlrich Weigand  ret i64 %or
2009e3577ffSUlrich Weigand}
2019e3577ffSUlrich Weigand
2029e3577ffSUlrich Weigand; Repeat f17 with the operands reversed.
2039e3577ffSUlrich Weiganddefine i64 @f18(i32 %a) {
204*d24ab20eSStephen Lin; CHECK-LABEL: f18:
2059e3577ffSUlrich Weigand; CHECK: msr %r2, %r2
2069e3577ffSUlrich Weigand; CHECK-NEXT: iihf %r2, 1
2079e3577ffSUlrich Weigand; CHECK: br %r14
2089e3577ffSUlrich Weigand  %mul = mul i32 %a, %a
2099e3577ffSUlrich Weigand  %ext = zext i32 %mul to i64
2109e3577ffSUlrich Weigand  %or = or i64 4294967296, %ext
2119e3577ffSUlrich Weigand  ret i64 %or
2129e3577ffSUlrich Weigand}
2139e3577ffSUlrich Weigand
2149e3577ffSUlrich Weigand; The truncation here isn't free; we need an explicit zero extension.
2159e3577ffSUlrich Weiganddefine i64 @f19(i32 %a) {
216*d24ab20eSStephen Lin; CHECK-LABEL: f19:
2179e3577ffSUlrich Weigand; CHECK: llgcr %r2, %r2
2189e3577ffSUlrich Weigand; CHECK: oihl %r2, 1
2199e3577ffSUlrich Weigand; CHECK: br %r14
2209e3577ffSUlrich Weigand  %trunc = trunc i32 %a to i8
2219e3577ffSUlrich Weigand  %ext = zext i8 %trunc to i64
2229e3577ffSUlrich Weigand  %or = or i64 %ext, 4294967296
2239e3577ffSUlrich Weigand  ret i64 %or
2249e3577ffSUlrich Weigand}
225