[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / SystemZ / int-div-03.ll
blobc4a00ca0aaafcb3b172ce6a9cc3504dd3aaed403
1 ; Test 64-bit signed division and remainder when the divisor is
2 ; a signed-extended i32.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s
6 declare i64 @foo()
8 ; Test register division.  The result is in the second of the two registers.
9 define 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
21 ; Test register remainder.  The result is in the first of the two registers.
22 define 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
34 ; Test that division and remainder use a single instruction.
35 define 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
49 ; Test register division when the dividend is zero rather than sign extended.
50 ; We can't use dsgfr here
51 define void @f4(i64 %dummy, i64 %a, i32 %b, i64 *%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, i64 *%dest
58   ret void
61 ; ...likewise remainder.
62 define void @f5(i64 %dummy, i64 %a, i32 %b, i64 *%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, i64 *%dest
69   ret void
72 ; Test memory division with no displacement.
73 define void @f6(i64 %dummy, i64 %a, i32 *%src, i64 *%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, i32 *%src
80   %bext = sext i32 %b to i64
81   %div = sdiv i64 %a, %bext
82   store i64 %div, i64 *%dest
83   ret void
86 ; Test memory remainder with no displacement.
87 define void @f7(i64 %dummy, i64 %a, i32 *%src, i64 *%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, i32 *%src
94   %bext = sext i32 %b to i64
95   %rem = srem i64 %a, %bext
96   store i64 %rem, i64 *%dest
97   ret void
100 ; Test both memory division and memory remainder.
101 define i64 @f8(i64 %dummy, i64 %a, i32 *%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, i32 *%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
117 ; Check the high end of the DSGF range.
118 define i64 @f9(i64 %dummy, i64 %a, i32 *%src) {
119 ; CHECK-LABEL: f9:
120 ; CHECK: dsgf %r2, 524284(%r4)
121 ; CHECK: br %r14
122   %ptr = getelementptr i32, i32 *%src, i64 131071
123   %b = load i32, i32 *%ptr
124   %bext = sext i32 %b to i64
125   %rem = srem i64 %a, %bext
126   ret i64 %rem
129 ; Check the next word up, which needs separate address logic.
130 ; Other sequences besides this one would be OK.
131 define i64 @f10(i64 %dummy, i64 %a, i32 *%src) {
132 ; CHECK-LABEL: f10:
133 ; CHECK: agfi %r4, 524288
134 ; CHECK: dsgf %r2, 0(%r4)
135 ; CHECK: br %r14
136   %ptr = getelementptr i32, i32 *%src, i64 131072
137   %b = load i32, i32 *%ptr
138   %bext = sext i32 %b to i64
139   %rem = srem i64 %a, %bext
140   ret i64 %rem
143 ; Check the high end of the negative aligned DSGF range.
144 define i64 @f11(i64 %dummy, i64 %a, i32 *%src) {
145 ; CHECK-LABEL: f11:
146 ; CHECK: dsgf %r2, -4(%r4)
147 ; CHECK: br %r14
148   %ptr = getelementptr i32, i32 *%src, i64 -1
149   %b = load i32, i32 *%ptr
150   %bext = sext i32 %b to i64
151   %rem = srem i64 %a, %bext
152   ret i64 %rem
155 ; Check the low end of the DSGF range.
156 define i64 @f12(i64 %dummy, i64 %a, i32 *%src) {
157 ; CHECK-LABEL: f12:
158 ; CHECK: dsgf %r2, -524288(%r4)
159 ; CHECK: br %r14
160   %ptr = getelementptr i32, i32 *%src, i64 -131072
161   %b = load i32, i32 *%ptr
162   %bext = sext i32 %b to i64
163   %rem = srem i64 %a, %bext
164   ret i64 %rem
167 ; Check the next word down, which needs separate address logic.
168 ; Other sequences besides this one would be OK.
169 define i64 @f13(i64 %dummy, i64 %a, i32 *%src) {
170 ; CHECK-LABEL: f13:
171 ; CHECK: agfi %r4, -524292
172 ; CHECK: dsgf %r2, 0(%r4)
173 ; CHECK: br %r14
174   %ptr = getelementptr i32, i32 *%src, i64 -131073
175   %b = load i32, i32 *%ptr
176   %bext = sext i32 %b to i64
177   %rem = srem i64 %a, %bext
178   ret i64 %rem
181 ; Check that DSGF allows an index.
182 define 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 i32 *
189   %b = load i32, i32 *%ptr
190   %bext = sext i32 %b to i64
191   %rem = srem i64 %a, %bext
192   ret i64 %rem
195 ; Make sure that we still use DSGFR rather than DSGR in cases where
196 ; a load and division cannot be combined.
197 define void @f15(i64 *%dest, i32 *%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, i32 *%src
205   %a = call i64 @foo()
206   %ext = sext i32 %b to i64
207   %div = sdiv i64 %a, %ext
208   store i64 %div, i64 *%dest
209   ret void