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