brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 0567c10 Raw
211 lines · plain
1; Test 64-bit signed division and remainder when the divisor is2; a signed-extended i32.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s5 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, %r413; CHECK: stg %r3, 0(%r5)14; CHECK: br %r1415  %bext = sext i32 %b to i6416  %div = sdiv i64 %a, %bext17  store i64 %div, ptr %dest18  ret void19}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, %r426; CHECK: stg %r2, 0(%r5)27; CHECK: br %r1428  %bext = sext i32 %b to i6429  %rem = srem i64 %a, %bext30  store i64 %rem, ptr %dest31  ret void32}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, %r439; CHECK: ogr %r3, %r240; CHECK: lgr %r2, %r341; CHECK: br %r1442  %bext = sext i32 %b to i6443  %div = sdiv i64 %a, %bext44  %rem = srem i64 %a, %bext45  %or = or i64 %rem, %div46  ret i64 %or47}48 49; Test register division when the dividend is zero rather than sign extended.50; We can't use dsgfr here51define void @f4(i64 %dummy, i64 %a, i32 %b, ptr %dest) {52; CHECK-LABEL: f4:53; CHECK-NOT: dsgfr54; CHECK: br %r1455  %bext = zext i32 %b to i6456  %div = sdiv i64 %a, %bext57  store i64 %div, ptr %dest58  ret void59}60 61; ...likewise remainder.62define void @f5(i64 %dummy, i64 %a, i32 %b, ptr %dest) {63; CHECK-LABEL: f5:64; CHECK-NOT: dsgfr65; CHECK: br %r1466  %bext = zext i32 %b to i6467  %rem = srem i64 %a, %bext68  store i64 %rem, ptr %dest69  ret void70}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 %r1479  %b = load i32, ptr %src80  %bext = sext i32 %b to i6481  %div = sdiv i64 %a, %bext82  store i64 %div, ptr %dest83  ret void84}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 %r1493  %b = load i32, ptr %src94  %bext = sext i32 %b to i6495  %rem = srem i64 %a, %bext96  store i64 %rem, ptr %dest97  ret void98}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, %r2107; CHECK: lgr %r2, %r3108; CHECK: br %r14109  %b = load i32, ptr %src110  %bext = sext i32 %b to i64111  %div = sdiv i64 %a, %bext112  %rem = srem i64 %a, %bext113  %or = or i64 %rem, %div114  ret i64 %or115}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 %r14122  %ptr = getelementptr i32, ptr %src, i64 131071123  %b = load i32, ptr %ptr124  %bext = sext i32 %b to i64125  %rem = srem i64 %a, %bext126  ret i64 %rem127}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, 524288134; CHECK: dsgf %r2, 0(%r4)135; CHECK: br %r14136  %ptr = getelementptr i32, ptr %src, i64 131072137  %b = load i32, ptr %ptr138  %bext = sext i32 %b to i64139  %rem = srem i64 %a, %bext140  ret i64 %rem141}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 %r14148  %ptr = getelementptr i32, ptr %src, i64 -1149  %b = load i32, ptr %ptr150  %bext = sext i32 %b to i64151  %rem = srem i64 %a, %bext152  ret i64 %rem153}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 %r14160  %ptr = getelementptr i32, ptr %src, i64 -131072161  %b = load i32, ptr %ptr162  %bext = sext i32 %b to i64163  %rem = srem i64 %a, %bext164  ret i64 %rem165}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, -524292172; CHECK: dsgf %r2, 0(%r4)173; CHECK: br %r14174  %ptr = getelementptr i32, ptr %src, i64 -131073175  %b = load i32, ptr %ptr176  %bext = sext i32 %b to i64177  %rem = srem i64 %a, %bext178  ret i64 %rem179}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 %r14186  %add1 = add i64 %src, %index187  %add2 = add i64 %add1, 524287188  %ptr = inttoptr i64 %add2 to ptr189  %b = load i32, ptr %ptr190  %bext = sext i32 %b to i64191  %rem = srem i64 %a, %bext192  ret i64 %rem193}194 195; Make sure that we still use DSGFR rather than DSGR in cases where196; 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@PLT201; CHECK: lgr %r1, %r2202; CHECK: dsgfr %r0, [[B]]203; CHECK: br %r14204  %b = load i32, ptr %src205  %a = call i64 @foo()206  %ext = sext i32 %b to i64207  %div = sdiv i64 %a, %ext208  store i64 %div, ptr %dest209  ret void210}211