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