1; Test 64-bit signed division and remainder when the divisor is 2; a signed-extended i32. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s 5 6declare i64 @foo() 7 8; Test register division. The result is in the second of the two registers. 9define void @f1(i64 %dummy, i64 %a, i32 %b, ptr %dest) { 10; CHECK-LABEL: f1: 11; CHECK-NOT: {{%r[234]}} 12; CHECK: dsgfr %r2, %r4 13; CHECK: stg %r3, 0(%r5) 14; CHECK: br %r14 15 %bext = sext i32 %b to i64 16 %div = sdiv i64 %a, %bext 17 store i64 %div, ptr %dest 18 ret void 19} 20 21; Test register remainder. The result is in the first of the two registers. 22define void @f2(i64 %dummy, i64 %a, i32 %b, ptr %dest) { 23; CHECK-LABEL: f2: 24; CHECK-NOT: {{%r[234]}} 25; CHECK: dsgfr %r2, %r4 26; CHECK: stg %r2, 0(%r5) 27; CHECK: br %r14 28 %bext = sext i32 %b to i64 29 %rem = srem i64 %a, %bext 30 store i64 %rem, ptr %dest 31 ret void 32} 33 34; Test that division and remainder use a single instruction. 35define i64 @f3(i64 %dummy, i64 %a, i32 %b) { 36; CHECK-LABEL: f3: 37; CHECK-NOT: {{%r[234]}} 38; CHECK: dsgfr %r2, %r4 39; CHECK: ogr %r3, %r2 40; CHECK: lgr %r2, %r3 41; CHECK: br %r14 42 %bext = sext i32 %b to i64 43 %div = sdiv i64 %a, %bext 44 %rem = srem i64 %a, %bext 45 %or = or i64 %rem, %div 46 ret i64 %or 47} 48 49; Test register division when the dividend is zero rather than sign extended. 50; We can't use dsgfr here 51define void @f4(i64 %dummy, i64 %a, i32 %b, ptr %dest) { 52; CHECK-LABEL: f4: 53; CHECK-NOT: dsgfr 54; CHECK: br %r14 55 %bext = zext i32 %b to i64 56 %div = sdiv i64 %a, %bext 57 store i64 %div, ptr %dest 58 ret void 59} 60 61; ...likewise remainder. 62define void @f5(i64 %dummy, i64 %a, i32 %b, ptr %dest) { 63; CHECK-LABEL: f5: 64; CHECK-NOT: dsgfr 65; CHECK: br %r14 66 %bext = zext i32 %b to i64 67 %rem = srem i64 %a, %bext 68 store i64 %rem, ptr %dest 69 ret void 70} 71 72; Test memory division with no displacement. 73define void @f6(i64 %dummy, i64 %a, ptr %src, ptr %dest) { 74; CHECK-LABEL: f6: 75; CHECK-NOT: {{%r[234]}} 76; CHECK: dsgf %r2, 0(%r4) 77; CHECK: stg %r3, 0(%r5) 78; CHECK: br %r14 79 %b = load i32, ptr %src 80 %bext = sext i32 %b to i64 81 %div = sdiv i64 %a, %bext 82 store i64 %div, ptr %dest 83 ret void 84} 85 86; Test memory remainder with no displacement. 87define void @f7(i64 %dummy, i64 %a, ptr %src, ptr %dest) { 88; CHECK-LABEL: f7: 89; CHECK-NOT: {{%r[234]}} 90; CHECK: dsgf %r2, 0(%r4) 91; CHECK: stg %r2, 0(%r5) 92; CHECK: br %r14 93 %b = load i32, ptr %src 94 %bext = sext i32 %b to i64 95 %rem = srem i64 %a, %bext 96 store i64 %rem, ptr %dest 97 ret void 98} 99 100; Test both memory division and memory remainder. 101define i64 @f8(i64 %dummy, i64 %a, ptr %src) { 102; CHECK-LABEL: f8: 103; CHECK-NOT: {{%r[234]}} 104; CHECK: dsgf %r2, 0(%r4) 105; CHECK-NOT: {{dsgf|dsgfr}} 106; CHECK: ogr %r3, %r2 107; CHECK: lgr %r2, %r3 108; CHECK: br %r14 109 %b = load i32, ptr %src 110 %bext = sext i32 %b to i64 111 %div = sdiv i64 %a, %bext 112 %rem = srem i64 %a, %bext 113 %or = or i64 %rem, %div 114 ret i64 %or 115} 116 117; Check the high end of the DSGF range. 118define i64 @f9(i64 %dummy, i64 %a, ptr %src) { 119; CHECK-LABEL: f9: 120; CHECK: dsgf %r2, 524284(%r4) 121; CHECK: br %r14 122 %ptr = getelementptr i32, ptr %src, i64 131071 123 %b = load i32, ptr %ptr 124 %bext = sext i32 %b to i64 125 %rem = srem i64 %a, %bext 126 ret i64 %rem 127} 128 129; Check the next word up, which needs separate address logic. 130; Other sequences besides this one would be OK. 131define i64 @f10(i64 %dummy, i64 %a, ptr %src) { 132; CHECK-LABEL: f10: 133; CHECK: agfi %r4, 524288 134; CHECK: dsgf %r2, 0(%r4) 135; CHECK: br %r14 136 %ptr = getelementptr i32, ptr %src, i64 131072 137 %b = load i32, ptr %ptr 138 %bext = sext i32 %b to i64 139 %rem = srem i64 %a, %bext 140 ret i64 %rem 141} 142 143; Check the high end of the negative aligned DSGF range. 144define i64 @f11(i64 %dummy, i64 %a, ptr %src) { 145; CHECK-LABEL: f11: 146; CHECK: dsgf %r2, -4(%r4) 147; CHECK: br %r14 148 %ptr = getelementptr i32, ptr %src, i64 -1 149 %b = load i32, ptr %ptr 150 %bext = sext i32 %b to i64 151 %rem = srem i64 %a, %bext 152 ret i64 %rem 153} 154 155; Check the low end of the DSGF range. 156define i64 @f12(i64 %dummy, i64 %a, ptr %src) { 157; CHECK-LABEL: f12: 158; CHECK: dsgf %r2, -524288(%r4) 159; CHECK: br %r14 160 %ptr = getelementptr i32, ptr %src, i64 -131072 161 %b = load i32, ptr %ptr 162 %bext = sext i32 %b to i64 163 %rem = srem i64 %a, %bext 164 ret i64 %rem 165} 166 167; Check the next word down, which needs separate address logic. 168; Other sequences besides this one would be OK. 169define i64 @f13(i64 %dummy, i64 %a, ptr %src) { 170; CHECK-LABEL: f13: 171; CHECK: agfi %r4, -524292 172; CHECK: dsgf %r2, 0(%r4) 173; CHECK: br %r14 174 %ptr = getelementptr i32, ptr %src, i64 -131073 175 %b = load i32, ptr %ptr 176 %bext = sext i32 %b to i64 177 %rem = srem i64 %a, %bext 178 ret i64 %rem 179} 180 181; Check that DSGF allows an index. 182define i64 @f14(i64 %dummy, i64 %a, i64 %src, i64 %index) { 183; CHECK-LABEL: f14: 184; CHECK: dsgf %r2, 524287(%r5,%r4) 185; CHECK: br %r14 186 %add1 = add i64 %src, %index 187 %add2 = add i64 %add1, 524287 188 %ptr = inttoptr i64 %add2 to ptr 189 %b = load i32, ptr %ptr 190 %bext = sext i32 %b to i64 191 %rem = srem i64 %a, %bext 192 ret i64 %rem 193} 194 195; Make sure that we still use DSGFR rather than DSGR in cases where 196; a load and division cannot be combined. 197define void @f15(ptr %dest, ptr %src) { 198; CHECK-LABEL: f15: 199; CHECK: l [[B:%r[0-9]+]], 0(%r3) 200; CHECK: brasl %r14, foo@PLT 201; CHECK: lgr %r1, %r2 202; CHECK: dsgfr %r0, [[B]] 203; CHECK: br %r14 204 %b = load i32, ptr %src 205 %a = call i64 @foo() 206 %ext = sext i32 %b to i64 207 %div = sdiv i64 %a, %ext 208 store i64 %div, ptr %dest 209 ret void 210} 211