1*9880d681SAndroid Build Coastguard Worker; Test 128-bit addition in which the second operand is variable. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdeclare i128 *@foo() 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Test register addition. 9*9880d681SAndroid Build Coastguard Workerdefine void @f1(i128 *%ptr) { 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 11*9880d681SAndroid Build Coastguard Worker; CHECK: algr 12*9880d681SAndroid Build Coastguard Worker; CHECK: alcgr 13*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 14*9880d681SAndroid Build Coastguard Worker %value = load i128 , i128 *%ptr 15*9880d681SAndroid Build Coastguard Worker %add = add i128 %value, %value 16*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%ptr 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Test memory addition with no offset. Making the load of %a volatile 21*9880d681SAndroid Build Coastguard Worker; should force the memory operand to be %b. 22*9880d681SAndroid Build Coastguard Workerdefine void @f2(i128 *%aptr, i64 %addr) { 23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 24*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, 8(%r3) 25*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, 0(%r3) 26*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 27*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 28*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 29*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 30*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 31*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 32*9880d681SAndroid Build Coastguard Worker ret void 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; Test the highest aligned offset that is in range of both ALG and ALCG. 36*9880d681SAndroid Build Coastguard Workerdefine void @f3(i128 *%aptr, i64 %base) { 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 38*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, 524280(%r3) 39*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, 524272(%r3) 40*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 41*9880d681SAndroid Build Coastguard Worker %addr = add i64 %base, 524272 42*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 43*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 44*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 45*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 46*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 47*9880d681SAndroid Build Coastguard Worker ret void 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; Test the next doubleword up, which requires separate address logic for ALG. 51*9880d681SAndroid Build Coastguard Workerdefine void @f4(i128 *%aptr, i64 %base) { 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 53*9880d681SAndroid Build Coastguard Worker; CHECK: lgr [[BASE:%r[1-5]]], %r3 54*9880d681SAndroid Build Coastguard Worker; CHECK: agfi [[BASE]], 524288 55*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, 0([[BASE]]) 56*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, 524280(%r3) 57*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 58*9880d681SAndroid Build Coastguard Worker %addr = add i64 %base, 524280 59*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 60*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 61*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 62*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 63*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 64*9880d681SAndroid Build Coastguard Worker ret void 65*9880d681SAndroid Build Coastguard Worker} 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker; Test the next doubleword after that, which requires separate logic for 68*9880d681SAndroid Build Coastguard Worker; both instructions. It would be better to create an anchor at 524288 69*9880d681SAndroid Build Coastguard Worker; that both instructions can use, but that isn't implemented yet. 70*9880d681SAndroid Build Coastguard Workerdefine void @f5(i128 *%aptr, i64 %base) { 71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 72*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, 0({{%r[1-5]}}) 73*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, 0({{%r[1-5]}}) 74*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 75*9880d681SAndroid Build Coastguard Worker %addr = add i64 %base, 524288 76*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 77*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 78*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 79*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 80*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 81*9880d681SAndroid Build Coastguard Worker ret void 82*9880d681SAndroid Build Coastguard Worker} 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker; Test the lowest displacement that is in range of both ALG and ALCG. 85*9880d681SAndroid Build Coastguard Workerdefine void @f6(i128 *%aptr, i64 %base) { 86*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 87*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, -524280(%r3) 88*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, -524288(%r3) 89*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 90*9880d681SAndroid Build Coastguard Worker %addr = add i64 %base, -524288 91*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 92*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 93*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 94*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 95*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 96*9880d681SAndroid Build Coastguard Worker ret void 97*9880d681SAndroid Build Coastguard Worker} 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker; Test the next doubleword down, which is out of range of the ALCG. 100*9880d681SAndroid Build Coastguard Workerdefine void @f7(i128 *%aptr, i64 %base) { 101*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 102*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-5]}}, -524288(%r3) 103*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-5]}}, 0({{%r[1-5]}}) 104*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 105*9880d681SAndroid Build Coastguard Worker %addr = add i64 %base, -524296 106*9880d681SAndroid Build Coastguard Worker %bptr = inttoptr i64 %addr to i128 * 107*9880d681SAndroid Build Coastguard Worker %a = load volatile i128 , i128 *%aptr 108*9880d681SAndroid Build Coastguard Worker %b = load i128 , i128 *%bptr 109*9880d681SAndroid Build Coastguard Worker %add = add i128 %a, %b 110*9880d681SAndroid Build Coastguard Worker store i128 %add, i128 *%aptr 111*9880d681SAndroid Build Coastguard Worker ret void 112*9880d681SAndroid Build Coastguard Worker} 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker; Check that additions of spilled values can use ALG and ALCG rather than 115*9880d681SAndroid Build Coastguard Worker; ALGR and ALCGR. 116*9880d681SAndroid Build Coastguard Workerdefine void @f8(i128 *%ptr0) { 117*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 118*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 119*9880d681SAndroid Build Coastguard Worker; CHECK: alg {{%r[0-9]+}}, {{[0-9]+}}(%r15) 120*9880d681SAndroid Build Coastguard Worker; CHECK: alcg {{%r[0-9]+}}, {{[0-9]+}}(%r15) 121*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 122*9880d681SAndroid Build Coastguard Worker %ptr1 = getelementptr i128, i128 *%ptr0, i128 2 123*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr i128, i128 *%ptr0, i128 4 124*9880d681SAndroid Build Coastguard Worker %ptr3 = getelementptr i128, i128 *%ptr0, i128 6 125*9880d681SAndroid Build Coastguard Worker %ptr4 = getelementptr i128, i128 *%ptr0, i128 8 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker %val0 = load i128 , i128 *%ptr0 128*9880d681SAndroid Build Coastguard Worker %val1 = load i128 , i128 *%ptr1 129*9880d681SAndroid Build Coastguard Worker %val2 = load i128 , i128 *%ptr2 130*9880d681SAndroid Build Coastguard Worker %val3 = load i128 , i128 *%ptr3 131*9880d681SAndroid Build Coastguard Worker %val4 = load i128 , i128 *%ptr4 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker %retptr = call i128 *@foo() 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker %ret = load i128 , i128 *%retptr 136*9880d681SAndroid Build Coastguard Worker %add0 = add i128 %ret, %val0 137*9880d681SAndroid Build Coastguard Worker %add1 = add i128 %add0, %val1 138*9880d681SAndroid Build Coastguard Worker %add2 = add i128 %add1, %val2 139*9880d681SAndroid Build Coastguard Worker %add3 = add i128 %add2, %val3 140*9880d681SAndroid Build Coastguard Worker %add4 = add i128 %add3, %val4 141*9880d681SAndroid Build Coastguard Worker store i128 %add4, i128 *%retptr 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker ret void 144*9880d681SAndroid Build Coastguard Worker} 145