1; Test 128-bit addition in which the second operand is a zero-extended i32. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5; Check register additions. The XOR ensures that we don't instead zero-extend 6; %b into a register and use memory addition. 7define void @f1(i128 *%aptr, i32 %b) { 8; CHECK-LABEL: f1: 9; CHECK: algfr {{%r[0-5]}}, %r3 10; CHECK: alcg 11; CHECK: br %r14 12 %a = load i128, i128 *%aptr 13 %xor = xor i128 %a, 127 14 %bext = zext i32 %b to i128 15 %add = add i128 %xor, %bext 16 store i128 %add, i128 *%aptr 17 ret void 18} 19 20; Like f1, but using an "in-register" extension. 21define void @f2(i128 *%aptr, i64 %b) { 22; CHECK-LABEL: f2: 23; CHECK: algfr {{%r[0-5]}}, %r3 24; CHECK: alcg 25; CHECK: br %r14 26 %a = load i128, i128 *%aptr 27 %xor = xor i128 %a, 127 28 %trunc = trunc i64 %b to i32 29 %bext = zext i32 %trunc to i128 30 %add = add i128 %xor, %bext 31 store i128 %add, i128 *%aptr 32 ret void 33} 34 35; Test register addition in cases where the second operand is zero extended 36; from i64 rather than i32, but is later masked to i32 range. 37define void @f3(i128 *%aptr, i64 %b) { 38; CHECK-LABEL: f3: 39; CHECK: algfr {{%r[0-5]}}, %r3 40; CHECK: alcg 41; CHECK: br %r14 42 %a = load i128, i128 *%aptr 43 %xor = xor i128 %a, 127 44 %bext = zext i64 %b to i128 45 %and = and i128 %bext, 4294967295 46 %add = add i128 %xor, %and 47 store i128 %add, i128 *%aptr 48 ret void 49} 50 51; Test ALGF with no offset. 52define void @f4(i128 *%aptr, i32 *%bsrc) { 53; CHECK-LABEL: f4: 54; CHECK: algf {{%r[0-5]}}, 0(%r3) 55; CHECK: alcg 56; CHECK: br %r14 57 %a = load i128, i128 *%aptr 58 %xor = xor i128 %a, 127 59 %b = load i32, i32 *%bsrc 60 %bext = zext i32 %b to i128 61 %add = add i128 %xor, %bext 62 store i128 %add, i128 *%aptr 63 ret void 64} 65 66; Check the high end of the ALGF range. 67define void @f5(i128 *%aptr, i32 *%bsrc) { 68; CHECK-LABEL: f5: 69; CHECK: algf {{%r[0-5]}}, 524284(%r3) 70; CHECK: alcg 71; CHECK: br %r14 72 %a = load i128, i128 *%aptr 73 %xor = xor i128 %a, 127 74 %ptr = getelementptr i32, i32 *%bsrc, i64 131071 75 %b = load i32, i32 *%ptr 76 %bext = zext i32 %b to i128 77 %add = add i128 %xor, %bext 78 store i128 %add, i128 *%aptr 79 ret void 80} 81 82; Check the next word up, which must use separate address logic. 83; Other sequences besides this one would be OK. 84define void @f6(i128 *%aptr, i32 *%bsrc) { 85; CHECK-LABEL: f6: 86; CHECK: agfi %r3, 524288 87; CHECK: algf {{%r[0-5]}}, 0(%r3) 88; CHECK: alcg 89; CHECK: br %r14 90 %a = load i128, i128 *%aptr 91 %xor = xor i128 %a, 127 92 %ptr = getelementptr i32, i32 *%bsrc, i64 131072 93 %b = load i32, i32 *%ptr 94 %bext = zext i32 %b to i128 95 %add = add i128 %xor, %bext 96 store i128 %add, i128 *%aptr 97 ret void 98} 99 100; Check the high end of the negative aligned ALGF range. 101define void @f7(i128 *%aptr, i32 *%bsrc) { 102; CHECK-LABEL: f7: 103; CHECK: algf {{%r[0-5]}}, -4(%r3) 104; CHECK: alcg 105; CHECK: br %r14 106 %a = load i128, i128 *%aptr 107 %xor = xor i128 %a, 127 108 %ptr = getelementptr i32, i32 *%bsrc, i128 -1 109 %b = load i32, i32 *%ptr 110 %bext = zext i32 %b to i128 111 %add = add i128 %xor, %bext 112 store i128 %add, i128 *%aptr 113 ret void 114} 115 116; Check the low end of the ALGF range. 117define void @f8(i128 *%aptr, i32 *%bsrc) { 118; CHECK-LABEL: f8: 119; CHECK: algf {{%r[0-5]}}, -524288(%r3) 120; CHECK: alcg 121; CHECK: br %r14 122 %a = load i128, i128 *%aptr 123 %xor = xor i128 %a, 127 124 %ptr = getelementptr i32, i32 *%bsrc, i128 -131072 125 %b = load i32, i32 *%ptr 126 %bext = zext i32 %b to i128 127 %add = add i128 %xor, %bext 128 store i128 %add, i128 *%aptr 129 ret void 130} 131 132; Check the next word down, which needs separate address logic. 133; Other sequences besides this one would be OK. 134define void @f9(i128 *%aptr, i32 *%bsrc) { 135; CHECK-LABEL: f9: 136; CHECK: agfi %r3, -524292 137; CHECK: algf {{%r[0-5]}}, 0(%r3) 138; CHECK: alcg 139; CHECK: br %r14 140 %a = load i128, i128 *%aptr 141 %xor = xor i128 %a, 127 142 %ptr = getelementptr i32, i32 *%bsrc, i128 -131073 143 %b = load i32, i32 *%ptr 144 %bext = zext i32 %b to i128 145 %add = add i128 %xor, %bext 146 store i128 %add, i128 *%aptr 147 ret void 148} 149 150; Check that ALGF allows an index. 151define void @f10(i128 *%aptr, i64 %src, i64 %index) { 152; CHECK-LABEL: f10: 153; CHECK: algf {{%r[0-5]}}, 524284({{%r4,%r3|%r3,%r4}}) 154; CHECK: br %r14 155 %a = load i128, i128 *%aptr 156 %xor = xor i128 %a, 127 157 %add1 = add i64 %src, %index 158 %add2 = add i64 %add1, 524284 159 %ptr = inttoptr i64 %add2 to i32 * 160 %b = load i32, i32 *%ptr 161 %bext = zext i32 %b to i128 162 %add = add i128 %xor, %bext 163 store i128 %add, i128 *%aptr 164 ret void 165} 166