blob: 04f622b44e7442695e3df6bb1cea8b74f8e84a2e [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; Testg 64-bit unsigned division and remainder.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Testg register division. The result is in the second of the two registers.
6define void @f1(i64 %dummy, i64 %a, i64 %b, i64 *%dest) {
7; CHECK: f1:
8; CHECK-NOT: %r3
9; CHECK: {{llill|lghi}} %r2, 0
10; CHECK-NOT: %r3
11; CHECK: dlgr %r2, %r4
12; CHECK: stg %r3, 0(%r5)
13; CHECK: br %r14
14 %div = udiv i64 %a, %b
15 store i64 %div, i64 *%dest
16 ret void
17}
18
19; Testg register remainder. The result is in the first of the two registers.
20define void @f2(i64 %dummy, i64 %a, i64 %b, i64 *%dest) {
21; CHECK: f2:
22; CHECK-NOT: %r3
23; CHECK: {{llill|lghi}} %r2, 0
24; CHECK-NOT: %r3
25; CHECK: dlgr %r2, %r4
26; CHECK: stg %r2, 0(%r5)
27; CHECK: br %r14
28 %rem = urem i64 %a, %b
29 store i64 %rem, i64 *%dest
30 ret void
31}
32
33; Testg that division and remainder use a single instruction.
34define i64 @f3(i64 %dummy1, i64 %a, i64 %b) {
35; CHECK: f3:
36; CHECK-NOT: %r3
37; CHECK: {{llill|lghi}} %r2, 0
38; CHECK-NOT: %r3
39; CHECK: dlgr %r2, %r4
40; CHECK-NOT: dlgr
41; CHECK: ogr %r2, %r3
42; CHECK: br %r14
43 %div = udiv i64 %a, %b
44 %rem = urem i64 %a, %b
45 %or = or i64 %rem, %div
46 ret i64 %or
47}
48
49; Testg memory division with no displacement.
50define void @f4(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
51; CHECK: f4:
52; CHECK-NOT: %r3
53; CHECK: {{llill|lghi}} %r2, 0
54; CHECK-NOT: %r3
55; CHECK: dlg %r2, 0(%r4)
56; CHECK: stg %r3, 0(%r5)
57; CHECK: br %r14
58 %b = load i64 *%src
59 %div = udiv i64 %a, %b
60 store i64 %div, i64 *%dest
61 ret void
62}
63
64; Testg memory remainder with no displacement.
65define void @f5(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
66; CHECK: f5:
67; CHECK-NOT: %r3
68; CHECK: {{llill|lghi}} %r2, 0
69; CHECK-NOT: %r3
70; CHECK: dlg %r2, 0(%r4)
71; CHECK: stg %r2, 0(%r5)
72; CHECK: br %r14
73 %b = load i64 *%src
74 %rem = urem i64 %a, %b
75 store i64 %rem, i64 *%dest
76 ret void
77}
78
79; Testg both memory division and memory remainder.
80define i64 @f6(i64 %dummy, i64 %a, i64 *%src) {
81; CHECK: f6:
82; CHECK-NOT: %r3
83; CHECK: {{llill|lghi}} %r2, 0
84; CHECK-NOT: %r3
85; CHECK: dlg %r2, 0(%r4)
86; CHECK-NOT: {{dlg|dlgr}}
87; CHECK: ogr %r2, %r3
88; CHECK: br %r14
89 %b = load i64 *%src
90 %div = udiv i64 %a, %b
91 %rem = urem i64 %a, %b
92 %or = or i64 %rem, %div
93 ret i64 %or
94}
95
96; Check the high end of the DLG range.
97define i64 @f7(i64 %dummy, i64 %a, i64 *%src) {
98; CHECK: f7:
99; CHECK: dlg %r2, 524280(%r4)
100; CHECK: br %r14
101 %ptr = getelementptr i64 *%src, i64 65535
102 %b = load i64 *%ptr
103 %rem = urem i64 %a, %b
104 ret i64 %rem
105}
106
107; Check the next doubleword up, which needs separate address logic.
108; Other sequences besides this one would be OK.
109define i64 @f8(i64 %dummy, i64 %a, i64 *%src) {
110; CHECK: f8:
111; CHECK: agfi %r4, 524288
112; CHECK: dlg %r2, 0(%r4)
113; CHECK: br %r14
114 %ptr = getelementptr i64 *%src, i64 65536
115 %b = load i64 *%ptr
116 %rem = urem i64 %a, %b
117 ret i64 %rem
118}
119
120; Check the high end of the negative aligned DLG range.
121define i64 @f9(i64 %dummy, i64 %a, i64 *%src) {
122; CHECK: f9:
123; CHECK: dlg %r2, -8(%r4)
124; CHECK: br %r14
125 %ptr = getelementptr i64 *%src, i64 -1
126 %b = load i64 *%ptr
127 %rem = urem i64 %a, %b
128 ret i64 %rem
129}
130
131; Check the low end of the DLG range.
132define i64 @f10(i64 %dummy, i64 %a, i64 *%src) {
133; CHECK: f10:
134; CHECK: dlg %r2, -524288(%r4)
135; CHECK: br %r14
136 %ptr = getelementptr i64 *%src, i64 -65536
137 %b = load i64 *%ptr
138 %rem = urem i64 %a, %b
139 ret i64 %rem
140}
141
142; Check the next doubleword down, which needs separate address logic.
143; Other sequences besides this one would be OK.
144define i64 @f11(i64 %dummy, i64 %a, i64 *%src) {
145; CHECK: f11:
146; CHECK: agfi %r4, -524296
147; CHECK: dlg %r2, 0(%r4)
148; CHECK: br %r14
149 %ptr = getelementptr i64 *%src, i64 -65537
150 %b = load i64 *%ptr
151 %rem = urem i64 %a, %b
152 ret i64 %rem
153}
154
155; Check that DLG allows an index.
156define i64 @f12(i64 %dummy, i64 %a, i64 %src, i64 %index) {
157; CHECK: f12:
158; CHECK: dlg %r2, 524287(%r5,%r4)
159; CHECK: br %r14
160 %add1 = add i64 %src, %index
161 %add2 = add i64 %add1, 524287
162 %ptr = inttoptr i64 %add2 to i64 *
163 %b = load i64 *%ptr
164 %rem = urem i64 %a, %b
165 ret i64 %rem
166}