1 ; Testg 64-bit unsigned division and remainder.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Testg register division. The result is in the second of the two registers.
6 define void @f1(i64 %dummy, i64 %a, i64 %b, i64 *%dest) {
9 ; CHECK: {{llill|lghi}} %r2, 0
11 ; CHECK: dlgr %r2, %r4
12 ; CHECK: stg %r3, 0(%r5)
14 %div = udiv i64 %a, %b
15 store i64 %div, i64 *%dest
19 ; Testg register remainder. The result is in the first of the two registers.
20 define void @f2(i64 %dummy, i64 %a, i64 %b, i64 *%dest) {
23 ; CHECK: {{llill|lghi}} %r2, 0
25 ; CHECK: dlgr %r2, %r4
26 ; CHECK: stg %r2, 0(%r5)
28 %rem = urem i64 %a, %b
29 store i64 %rem, i64 *%dest
33 ; Testg that division and remainder use a single instruction.
34 define i64 @f3(i64 %dummy1, i64 %a, i64 %b) {
37 ; CHECK: {{llill|lghi}} %r2, 0
39 ; CHECK: dlgr %r2, %r4
43 %div = udiv i64 %a, %b
44 %rem = urem i64 %a, %b
45 %or = or i64 %rem, %div
49 ; Testg memory division with no displacement.
50 define void @f4(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
53 ; CHECK: {{llill|lghi}} %r2, 0
55 ; CHECK: dlg %r2, 0(%r4)
56 ; CHECK: stg %r3, 0(%r5)
59 %div = udiv i64 %a, %b
60 store i64 %div, i64 *%dest
64 ; Testg memory remainder with no displacement.
65 define void @f5(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
68 ; CHECK: {{llill|lghi}} %r2, 0
70 ; CHECK: dlg %r2, 0(%r4)
71 ; CHECK: stg %r2, 0(%r5)
74 %rem = urem i64 %a, %b
75 store i64 %rem, i64 *%dest
79 ; Testg both memory division and memory remainder.
80 define i64 @f6(i64 %dummy, i64 %a, i64 *%src) {
83 ; CHECK: {{llill|lghi}} %r2, 0
85 ; CHECK: dlg %r2, 0(%r4)
86 ; CHECK-NOT: {{dlg|dlgr}}
90 %div = udiv i64 %a, %b
91 %rem = urem i64 %a, %b
92 %or = or i64 %rem, %div
96 ; Check the high end of the DLG range.
97 define i64 @f7(i64 %dummy, i64 %a, i64 *%src) {
99 ; CHECK: dlg %r2, 524280(%r4)
101 %ptr = getelementptr i64 *%src, i64 65535
103 %rem = urem i64 %a, %b
107 ; Check the next doubleword up, which needs separate address logic.
108 ; Other sequences besides this one would be OK.
109 define i64 @f8(i64 %dummy, i64 %a, i64 *%src) {
111 ; CHECK: agfi %r4, 524288
112 ; CHECK: dlg %r2, 0(%r4)
114 %ptr = getelementptr i64 *%src, i64 65536
116 %rem = urem i64 %a, %b
120 ; Check the high end of the negative aligned DLG range.
121 define i64 @f9(i64 %dummy, i64 %a, i64 *%src) {
123 ; CHECK: dlg %r2, -8(%r4)
125 %ptr = getelementptr i64 *%src, i64 -1
127 %rem = urem i64 %a, %b
131 ; Check the low end of the DLG range.
132 define i64 @f10(i64 %dummy, i64 %a, i64 *%src) {
134 ; CHECK: dlg %r2, -524288(%r4)
136 %ptr = getelementptr i64 *%src, i64 -65536
138 %rem = urem i64 %a, %b
142 ; Check the next doubleword down, which needs separate address logic.
143 ; Other sequences besides this one would be OK.
144 define i64 @f11(i64 %dummy, i64 %a, i64 *%src) {
146 ; CHECK: agfi %r4, -524296
147 ; CHECK: dlg %r2, 0(%r4)
149 %ptr = getelementptr i64 *%src, i64 -65537
151 %rem = urem i64 %a, %b
155 ; Check that DLG allows an index.
156 define i64 @f12(i64 %dummy, i64 %a, i64 %src, i64 %index) {
158 ; CHECK: dlg %r2, 524287(%r5,%r4)
160 %add1 = add i64 %src, %index
161 %add2 = add i64 %add1, 524287
162 %ptr = inttoptr i64 %add2 to i64 *
164 %rem = urem i64 %a, %b