1; Test 64-bit addition in which the second operand is variable. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5declare i64 @foo() 6 7; Check MSGR. 8define i64 @f1(i64 %a, i64 %b) { 9; CHECK-LABEL: f1: 10; CHECK: msgr %r2, %r3 11; CHECK: br %r14 12 %mul = mul i64 %a, %b 13 ret i64 %mul 14} 15 16; Check MSG with no displacement. 17define i64 @f2(i64 %a, i64 *%src) { 18; CHECK-LABEL: f2: 19; CHECK: msg %r2, 0(%r3) 20; CHECK: br %r14 21 %b = load i64 , i64 *%src 22 %mul = mul i64 %a, %b 23 ret i64 %mul 24} 25 26; Check the high end of the aligned MSG range. 27define i64 @f3(i64 %a, i64 *%src) { 28; CHECK-LABEL: f3: 29; CHECK: msg %r2, 524280(%r3) 30; CHECK: br %r14 31 %ptr = getelementptr i64, i64 *%src, i64 65535 32 %b = load i64 , i64 *%ptr 33 %mul = mul i64 %a, %b 34 ret i64 %mul 35} 36 37; Check the next doubleword up, which needs separate address logic. 38; Other sequences besides this one would be OK. 39define i64 @f4(i64 %a, i64 *%src) { 40; CHECK-LABEL: f4: 41; CHECK: agfi %r3, 524288 42; CHECK: msg %r2, 0(%r3) 43; CHECK: br %r14 44 %ptr = getelementptr i64, i64 *%src, i64 65536 45 %b = load i64 , i64 *%ptr 46 %mul = mul i64 %a, %b 47 ret i64 %mul 48} 49 50; Check the high end of the negative aligned MSG range. 51define i64 @f5(i64 %a, i64 *%src) { 52; CHECK-LABEL: f5: 53; CHECK: msg %r2, -8(%r3) 54; CHECK: br %r14 55 %ptr = getelementptr i64, i64 *%src, i64 -1 56 %b = load i64 , i64 *%ptr 57 %mul = mul i64 %a, %b 58 ret i64 %mul 59} 60 61; Check the low end of the MSG range. 62define i64 @f6(i64 %a, i64 *%src) { 63; CHECK-LABEL: f6: 64; CHECK: msg %r2, -524288(%r3) 65; CHECK: br %r14 66 %ptr = getelementptr i64, i64 *%src, i64 -65536 67 %b = load i64 , i64 *%ptr 68 %mul = mul i64 %a, %b 69 ret i64 %mul 70} 71 72; Check the next doubleword down, which needs separate address logic. 73; Other sequences besides this one would be OK. 74define i64 @f7(i64 %a, i64 *%src) { 75; CHECK-LABEL: f7: 76; CHECK: agfi %r3, -524296 77; CHECK: msg %r2, 0(%r3) 78; CHECK: br %r14 79 %ptr = getelementptr i64, i64 *%src, i64 -65537 80 %b = load i64 , i64 *%ptr 81 %mul = mul i64 %a, %b 82 ret i64 %mul 83} 84 85; Check that MSG allows an index. 86define i64 @f8(i64 %a, i64 %src, i64 %index) { 87; CHECK-LABEL: f8: 88; CHECK: msg %r2, 524280({{%r4,%r3|%r3,%r4}}) 89; CHECK: br %r14 90 %add1 = add i64 %src, %index 91 %add2 = add i64 %add1, 524280 92 %ptr = inttoptr i64 %add2 to i64 * 93 %b = load i64 , i64 *%ptr 94 %mul = mul i64 %a, %b 95 ret i64 %mul 96} 97 98; Check that multiplications of spilled values can use MSG rather than MSGR. 99define i64 @f9(i64 *%ptr0) { 100; CHECK-LABEL: f9: 101; CHECK: brasl %r14, foo@PLT 102; CHECK: msg %r2, 160(%r15) 103; CHECK: br %r14 104 %ptr1 = getelementptr i64, i64 *%ptr0, i64 2 105 %ptr2 = getelementptr i64, i64 *%ptr0, i64 4 106 %ptr3 = getelementptr i64, i64 *%ptr0, i64 6 107 %ptr4 = getelementptr i64, i64 *%ptr0, i64 8 108 %ptr5 = getelementptr i64, i64 *%ptr0, i64 10 109 %ptr6 = getelementptr i64, i64 *%ptr0, i64 12 110 %ptr7 = getelementptr i64, i64 *%ptr0, i64 14 111 %ptr8 = getelementptr i64, i64 *%ptr0, i64 16 112 %ptr9 = getelementptr i64, i64 *%ptr0, i64 18 113 114 %val0 = load i64 , i64 *%ptr0 115 %val1 = load i64 , i64 *%ptr1 116 %val2 = load i64 , i64 *%ptr2 117 %val3 = load i64 , i64 *%ptr3 118 %val4 = load i64 , i64 *%ptr4 119 %val5 = load i64 , i64 *%ptr5 120 %val6 = load i64 , i64 *%ptr6 121 %val7 = load i64 , i64 *%ptr7 122 %val8 = load i64 , i64 *%ptr8 123 %val9 = load i64 , i64 *%ptr9 124 125 %ret = call i64 @foo() 126 127 %mul0 = mul i64 %ret, %val0 128 %mul1 = mul i64 %mul0, %val1 129 %mul2 = mul i64 %mul1, %val2 130 %mul3 = mul i64 %mul2, %val3 131 %mul4 = mul i64 %mul3, %val4 132 %mul5 = mul i64 %mul4, %val5 133 %mul6 = mul i64 %mul5, %val6 134 %mul7 = mul i64 %mul6, %val7 135 %mul8 = mul i64 %mul7, %val8 136 %mul9 = mul i64 %mul8, %val9 137 138 ret i64 %mul9 139} 140