19e3577ffSUlrich Weigand; Test insertions of i32s into the low half of an i64. 29e3577ffSUlrich Weigand; 39e3577ffSUlrich Weigand; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 49e3577ffSUlrich Weigand 59e3577ffSUlrich Weigand; Insertion of an i32 can be done using LR. 69e3577ffSUlrich Weiganddefine i64 @f1(i64 %a, i32 %b) { 7d24ab20eSStephen Lin; CHECK-LABEL: f1: 89e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 99e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 109e3577ffSUlrich Weigand; CHECK: br %r14 119e3577ffSUlrich Weigand %low = zext i32 %b to i64 129e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 139e3577ffSUlrich Weigand %res = or i64 %high, %low 149e3577ffSUlrich Weigand ret i64 %res 159e3577ffSUlrich Weigand} 169e3577ffSUlrich Weigand 179e3577ffSUlrich Weigand; ... and again with the operands reversed. 189e3577ffSUlrich Weiganddefine i64 @f2(i64 %a, i32 %b) { 19d24ab20eSStephen Lin; CHECK-LABEL: f2: 209e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 219e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 229e3577ffSUlrich Weigand; CHECK: br %r14 239e3577ffSUlrich Weigand %low = zext i32 %b to i64 249e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 259e3577ffSUlrich Weigand %res = or i64 %low, %high 269e3577ffSUlrich Weigand ret i64 %res 279e3577ffSUlrich Weigand} 289e3577ffSUlrich Weigand 299e3577ffSUlrich Weigand; Like f1, but with "in register" zero extension. 309e3577ffSUlrich Weiganddefine i64 @f3(i64 %a, i64 %b) { 31d24ab20eSStephen Lin; CHECK-LABEL: f3: 329e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 339e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 349e3577ffSUlrich Weigand; CHECK: br %r14 359e3577ffSUlrich Weigand %low = and i64 %b, 4294967295 369e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 379e3577ffSUlrich Weigand %res = or i64 %high, %low 389e3577ffSUlrich Weigand ret i64 %res 399e3577ffSUlrich Weigand} 409e3577ffSUlrich Weigand 419e3577ffSUlrich Weigand; ... and again with the operands reversed. 429e3577ffSUlrich Weiganddefine i64 @f4(i64 %a, i64 %b) { 43d24ab20eSStephen Lin; CHECK-LABEL: f4: 449e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 459e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 469e3577ffSUlrich Weigand; CHECK: br %r14 479e3577ffSUlrich Weigand %low = and i64 %b, 4294967295 489e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 499e3577ffSUlrich Weigand %res = or i64 %low, %high 509e3577ffSUlrich Weigand ret i64 %res 519e3577ffSUlrich Weigand} 529e3577ffSUlrich Weigand 539e3577ffSUlrich Weigand; Unary operations can be done directly into the low half. 549e3577ffSUlrich Weiganddefine i64 @f5(i64 %a, i32 %b) { 55d24ab20eSStephen Lin; CHECK-LABEL: f5: 569e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 579e3577ffSUlrich Weigand; CHECK: lcr %r2, %r3 589e3577ffSUlrich Weigand; CHECK: br %r14 599e3577ffSUlrich Weigand %neg = sub i32 0, %b 609e3577ffSUlrich Weigand %low = zext i32 %neg to i64 619e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 629e3577ffSUlrich Weigand %res = or i64 %high, %low 639e3577ffSUlrich Weigand ret i64 %res 649e3577ffSUlrich Weigand} 659e3577ffSUlrich Weigand 669e3577ffSUlrich Weigand; ...likewise three-operand binary operations like RLL. 679e3577ffSUlrich Weiganddefine i64 @f6(i64 %a, i32 %b) { 68d24ab20eSStephen Lin; CHECK-LABEL: f6: 699e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 709e3577ffSUlrich Weigand; CHECK: rll %r2, %r3, 1 719e3577ffSUlrich Weigand; CHECK: br %r14 729e3577ffSUlrich Weigand %parta = shl i32 %b, 1 739e3577ffSUlrich Weigand %partb = lshr i32 %b, 31 749e3577ffSUlrich Weigand %rot = or i32 %parta, %partb 759e3577ffSUlrich Weigand %low = zext i32 %rot to i64 769e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 779e3577ffSUlrich Weigand %res = or i64 %low, %high 789e3577ffSUlrich Weigand ret i64 %res 799e3577ffSUlrich Weigand} 809e3577ffSUlrich Weigand 819e3577ffSUlrich Weigand; Loads can be done directly into the low half. The range of L is checked 829e3577ffSUlrich Weigand; in the move tests. 839e3577ffSUlrich Weiganddefine i64 @f7(i64 %a, i32 *%src) { 84d24ab20eSStephen Lin; CHECK-LABEL: f7: 859e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 869e3577ffSUlrich Weigand; CHECK: l %r2, 0(%r3) 879e3577ffSUlrich Weigand; CHECK: br %r14 88*a79ac14fSDavid Blaikie %b = load i32, i32 *%src 899e3577ffSUlrich Weigand %low = zext i32 %b to i64 909e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 919e3577ffSUlrich Weigand %res = or i64 %high, %low 929e3577ffSUlrich Weigand ret i64 %res 939e3577ffSUlrich Weigand} 949e3577ffSUlrich Weigand 959e3577ffSUlrich Weigand; ...likewise extending loads. 969e3577ffSUlrich Weiganddefine i64 @f8(i64 %a, i8 *%src) { 97d24ab20eSStephen Lin; CHECK-LABEL: f8: 989e3577ffSUlrich Weigand; CHECK-NOT: {{%r[23]}} 999e3577ffSUlrich Weigand; CHECK: lb %r2, 0(%r3) 1009e3577ffSUlrich Weigand; CHECK: br %r14 101*a79ac14fSDavid Blaikie %byte = load i8, i8 *%src 1029e3577ffSUlrich Weigand %b = sext i8 %byte to i32 1039e3577ffSUlrich Weigand %low = zext i32 %b to i64 1049e3577ffSUlrich Weigand %high = and i64 %a, -4294967296 1059e3577ffSUlrich Weigand %res = or i64 %high, %low 1069e3577ffSUlrich Weigand ret i64 %res 1079e3577ffSUlrich Weigand} 1089e3577ffSUlrich Weigand 1099e3577ffSUlrich Weigand; Check a case like f1 in which there is no AND. We simply know from context 1109e3577ffSUlrich Weigand; that the upper half of one OR operand and the lower half of the other are 1119e3577ffSUlrich Weigand; both clear. 1129e3577ffSUlrich Weiganddefine i64 @f9(i64 %a, i32 %b) { 113d24ab20eSStephen Lin; CHECK-LABEL: f9: 1149e3577ffSUlrich Weigand; CHECK: sllg %r2, %r2, 32 1159e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 1169e3577ffSUlrich Weigand; CHECK: br %r14 1179e3577ffSUlrich Weigand %shift = shl i64 %a, 32 1189e3577ffSUlrich Weigand %low = zext i32 %b to i64 1199e3577ffSUlrich Weigand %or = or i64 %shift, %low 1209e3577ffSUlrich Weigand ret i64 %or 1219e3577ffSUlrich Weigand} 1229e3577ffSUlrich Weigand 1239e3577ffSUlrich Weigand; ...and again with the operands reversed. 1249e3577ffSUlrich Weiganddefine i64 @f10(i64 %a, i32 %b) { 125d24ab20eSStephen Lin; CHECK-LABEL: f10: 1269e3577ffSUlrich Weigand; CHECK: sllg %r2, %r2, 32 1279e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 1289e3577ffSUlrich Weigand; CHECK: br %r14 1299e3577ffSUlrich Weigand %shift = shl i64 %a, 32 1309e3577ffSUlrich Weigand %low = zext i32 %b to i64 1319e3577ffSUlrich Weigand %or = or i64 %low, %shift 1329e3577ffSUlrich Weigand ret i64 %or 1339e3577ffSUlrich Weigand} 1349e3577ffSUlrich Weigand 1359e3577ffSUlrich Weigand; Like f9, but with "in register" zero extension. 1369e3577ffSUlrich Weiganddefine i64 @f11(i64 %a, i64 %b) { 137d24ab20eSStephen Lin; CHECK-LABEL: f11: 1389e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 1399e3577ffSUlrich Weigand; CHECK: br %r14 1409e3577ffSUlrich Weigand %shift = shl i64 %a, 32 1419e3577ffSUlrich Weigand %low = and i64 %b, 4294967295 1429e3577ffSUlrich Weigand %or = or i64 %shift, %low 1439e3577ffSUlrich Weigand ret i64 %or 1449e3577ffSUlrich Weigand} 1459e3577ffSUlrich Weigand 1469e3577ffSUlrich Weigand; ...and again with the operands reversed. 1479e3577ffSUlrich Weiganddefine i64 @f12(i64 %a, i64 %b) { 148d24ab20eSStephen Lin; CHECK-LABEL: f12: 1499e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 1509e3577ffSUlrich Weigand; CHECK: br %r14 1519e3577ffSUlrich Weigand %shift = shl i64 %a, 32 1529e3577ffSUlrich Weigand %low = and i64 %b, 4294967295 1539e3577ffSUlrich Weigand %or = or i64 %low, %shift 1549e3577ffSUlrich Weigand ret i64 %or 1559e3577ffSUlrich Weigand} 1569e3577ffSUlrich Weigand 1579e3577ffSUlrich Weigand; Like f9, but for larger shifts than 32. 1589e3577ffSUlrich Weiganddefine i64 @f13(i64 %a, i32 %b) { 159d24ab20eSStephen Lin; CHECK-LABEL: f13: 1609e3577ffSUlrich Weigand; CHECK: sllg %r2, %r2, 60 1619e3577ffSUlrich Weigand; CHECK: lr %r2, %r3 1629e3577ffSUlrich Weigand; CHECK: br %r14 1639e3577ffSUlrich Weigand %shift = shl i64 %a, 60 1649e3577ffSUlrich Weigand %low = zext i32 %b to i64 1659e3577ffSUlrich Weigand %or = or i64 %shift, %low 1669e3577ffSUlrich Weigand ret i64 %or 1679e3577ffSUlrich Weigand} 168ccc2a7c1SRichard Sandiford 169ccc2a7c1SRichard Sandiford; We previously wrongly removed the upper AND as dead. 170ccc2a7c1SRichard Sandiforddefine i64 @f14(i64 %a, i64 %b) { 171ccc2a7c1SRichard Sandiford; CHECK-LABEL: f14: 172ccc2a7c1SRichard Sandiford; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0 173ccc2a7c1SRichard Sandiford; CHECK: br %r14 174ccc2a7c1SRichard Sandiford %and1 = and i64 %a, 144115188075855872 175ccc2a7c1SRichard Sandiford %and2 = and i64 %b, 15 176ccc2a7c1SRichard Sandiford %or = or i64 %and1, %and2 177ccc2a7c1SRichard Sandiford %res = icmp eq i64 %or, 0 178ccc2a7c1SRichard Sandiford %ext = sext i1 %res to i64 179ccc2a7c1SRichard Sandiford ret i64 %ext 180ccc2a7c1SRichard Sandiford} 181d1093636SRichard Sandiford 182d1093636SRichard Sandiford; Check another representation of f8. 183d1093636SRichard Sandiforddefine i64 @f15(i64 %a, i8 *%src) { 184d1093636SRichard Sandiford; CHECK-LABEL: f15: 185d1093636SRichard Sandiford; CHECK-NOT: {{%r[23]}} 186d1093636SRichard Sandiford; CHECK: lb %r2, 0(%r3) 187d1093636SRichard Sandiford; CHECK: br %r14 188*a79ac14fSDavid Blaikie %byte = load i8, i8 *%src 189d1093636SRichard Sandiford %b = sext i8 %byte to i64 190d1093636SRichard Sandiford %low = and i64 %b, 4294967295 191d1093636SRichard Sandiford %high = and i64 %a, -4294967296 192d1093636SRichard Sandiford %res = or i64 %high, %low 193d1093636SRichard Sandiford ret i64 %res 194d1093636SRichard Sandiford} 195