1 ; Test 64-bit addition in which the second operand is variable. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 declare i64 @foo() 6 7 ; Check MSGR. 8 define 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. 17 define 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. 27 define 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. 39 define 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. 51 define 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. 62 define 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. 74 define 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. 86 define 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. 99 define 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