1; Test 32-bit subtraction. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 5 6declare i32 @foo() 7 8; Check SR. 9define i32 @f1(i32 %a, i32 %b) { 10; CHECK-LABEL: f1: 11; CHECK: sr %r2, %r3 12; CHECK: br %r14 13 %sub = sub i32 %a, %b 14 ret i32 %sub 15} 16 17; Check the low end of the S range. 18define i32 @f2(i32 %a, i32 *%src) { 19; CHECK-LABEL: f2: 20; CHECK: s %r2, 0(%r3) 21; CHECK: br %r14 22 %b = load i32, i32 *%src 23 %sub = sub i32 %a, %b 24 ret i32 %sub 25} 26 27; Check the high end of the aligned S range. 28define i32 @f3(i32 %a, i32 *%src) { 29; CHECK-LABEL: f3: 30; CHECK: s %r2, 4092(%r3) 31; CHECK: br %r14 32 %ptr = getelementptr i32, i32 *%src, i64 1023 33 %b = load i32, i32 *%ptr 34 %sub = sub i32 %a, %b 35 ret i32 %sub 36} 37 38; Check the next word up, which should use SY instead of S. 39define i32 @f4(i32 %a, i32 *%src) { 40; CHECK-LABEL: f4: 41; CHECK: sy %r2, 4096(%r3) 42; CHECK: br %r14 43 %ptr = getelementptr i32, i32 *%src, i64 1024 44 %b = load i32, i32 *%ptr 45 %sub = sub i32 %a, %b 46 ret i32 %sub 47} 48 49; Check the high end of the aligned SY range. 50define i32 @f5(i32 %a, i32 *%src) { 51; CHECK-LABEL: f5: 52; CHECK: sy %r2, 524284(%r3) 53; CHECK: br %r14 54 %ptr = getelementptr i32, i32 *%src, i64 131071 55 %b = load i32, i32 *%ptr 56 %sub = sub i32 %a, %b 57 ret i32 %sub 58} 59 60; Check the next word up, which needs separate address logic. 61; Other sequences besides this one would be OK. 62define i32 @f6(i32 %a, i32 *%src) { 63; CHECK-LABEL: f6: 64; CHECK: agfi %r3, 524288 65; CHECK: s %r2, 0(%r3) 66; CHECK: br %r14 67 %ptr = getelementptr i32, i32 *%src, i64 131072 68 %b = load i32, i32 *%ptr 69 %sub = sub i32 %a, %b 70 ret i32 %sub 71} 72 73; Check the high end of the negative aligned SY range. 74define i32 @f7(i32 %a, i32 *%src) { 75; CHECK-LABEL: f7: 76; CHECK: sy %r2, -4(%r3) 77; CHECK: br %r14 78 %ptr = getelementptr i32, i32 *%src, i64 -1 79 %b = load i32, i32 *%ptr 80 %sub = sub i32 %a, %b 81 ret i32 %sub 82} 83 84; Check the low end of the SY range. 85define i32 @f8(i32 %a, i32 *%src) { 86; CHECK-LABEL: f8: 87; CHECK: sy %r2, -524288(%r3) 88; CHECK: br %r14 89 %ptr = getelementptr i32, i32 *%src, i64 -131072 90 %b = load i32, i32 *%ptr 91 %sub = sub i32 %a, %b 92 ret i32 %sub 93} 94 95; Check the next word down, which needs separate address logic. 96; Other sequences besides this one would be OK. 97define i32 @f9(i32 %a, i32 *%src) { 98; CHECK-LABEL: f9: 99; CHECK: agfi %r3, -524292 100; CHECK: s %r2, 0(%r3) 101; CHECK: br %r14 102 %ptr = getelementptr i32, i32 *%src, i64 -131073 103 %b = load i32, i32 *%ptr 104 %sub = sub i32 %a, %b 105 ret i32 %sub 106} 107 108; Check that S allows an index. 109define i32 @f10(i32 %a, i64 %src, i64 %index) { 110; CHECK-LABEL: f10: 111; CHECK: s %r2, 4092({{%r4,%r3|%r3,%r4}}) 112; CHECK: br %r14 113 %add1 = add i64 %src, %index 114 %add2 = add i64 %add1, 4092 115 %ptr = inttoptr i64 %add2 to i32 * 116 %b = load i32, i32 *%ptr 117 %sub = sub i32 %a, %b 118 ret i32 %sub 119} 120 121; Check that SY allows an index. 122define i32 @f11(i32 %a, i64 %src, i64 %index) { 123; CHECK-LABEL: f11: 124; CHECK: sy %r2, 4096({{%r4,%r3|%r3,%r4}}) 125; CHECK: br %r14 126 %add1 = add i64 %src, %index 127 %add2 = add i64 %add1, 4096 128 %ptr = inttoptr i64 %add2 to i32 * 129 %b = load i32, i32 *%ptr 130 %sub = sub i32 %a, %b 131 ret i32 %sub 132} 133 134; Check that subtractions of spilled values can use S rather than SR. 135define i32 @f12(i32 *%ptr0) { 136; CHECK-LABEL: f12: 137; CHECK: brasl %r14, foo@PLT 138; CHECK: s %r2, 16{{[04]}}(%r15) 139; CHECK: br %r14 140 %ptr1 = getelementptr i32, i32 *%ptr0, i64 2 141 %ptr2 = getelementptr i32, i32 *%ptr0, i64 4 142 %ptr3 = getelementptr i32, i32 *%ptr0, i64 6 143 %ptr4 = getelementptr i32, i32 *%ptr0, i64 8 144 %ptr5 = getelementptr i32, i32 *%ptr0, i64 10 145 %ptr6 = getelementptr i32, i32 *%ptr0, i64 12 146 %ptr7 = getelementptr i32, i32 *%ptr0, i64 14 147 %ptr8 = getelementptr i32, i32 *%ptr0, i64 16 148 %ptr9 = getelementptr i32, i32 *%ptr0, i64 18 149 150 %val0 = load i32, i32 *%ptr0 151 %val1 = load i32, i32 *%ptr1 152 %val2 = load i32, i32 *%ptr2 153 %val3 = load i32, i32 *%ptr3 154 %val4 = load i32, i32 *%ptr4 155 %val5 = load i32, i32 *%ptr5 156 %val6 = load i32, i32 *%ptr6 157 %val7 = load i32, i32 *%ptr7 158 %val8 = load i32, i32 *%ptr8 159 %val9 = load i32, i32 *%ptr9 160 161 %ret = call i32 @foo() 162 163 %sub0 = sub i32 %ret, %val0 164 %sub1 = sub i32 %sub0, %val1 165 %sub2 = sub i32 %sub1, %val2 166 %sub3 = sub i32 %sub2, %val3 167 %sub4 = sub i32 %sub3, %val4 168 %sub5 = sub i32 %sub4, %val5 169 %sub6 = sub i32 %sub5, %val6 170 %sub7 = sub i32 %sub6, %val7 171 %sub8 = sub i32 %sub7, %val8 172 %sub9 = sub i32 %sub8, %val9 173 174 ret i32 %sub9 175} 176