1 ; Testg 64-bit signed division and remainder.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s
7 ; Testg register division. The result is in the second of the two registers.
8 define void @f1(i64 %dummy, i64 %a, i64 %b, i64 *%dest) {
10 ; CHECK-NOT: {{%r[234]}}
11 ; CHECK: dsgr %r2, %r4
12 ; CHECK: stg %r3, 0(%r5)
14 %div = sdiv 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) {
22 ; CHECK-NOT: {{%r[234]}}
23 ; CHECK: dsgr %r2, %r4
24 ; CHECK: stg %r2, 0(%r5)
26 %rem = srem i64 %a, %b
27 store i64 %rem, i64 *%dest
31 ; Testg that division and remainder use a single instruction.
32 define i64 @f3(i64 %dummy1, i64 %a, i64 %b) {
34 ; CHECK-NOT: {{%r[234]}}
35 ; CHECK: dsgr %r2, %r4
40 %div = sdiv i64 %a, %b
41 %rem = srem i64 %a, %b
42 %or = or i64 %rem, %div
46 ; Testg memory division with no displacement.
47 define void @f4(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
49 ; CHECK-NOT: {{%r[234]}}
50 ; CHECK: dsg %r2, 0(%r4)
51 ; CHECK: stg %r3, 0(%r5)
53 %b = load i64, i64 *%src
54 %div = sdiv i64 %a, %b
55 store i64 %div, i64 *%dest
59 ; Testg memory remainder with no displacement.
60 define void @f5(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) {
62 ; CHECK-NOT: {{%r[234]}}
63 ; CHECK: dsg %r2, 0(%r4)
64 ; CHECK: stg %r2, 0(%r5)
66 %b = load i64, i64 *%src
67 %rem = srem i64 %a, %b
68 store i64 %rem, i64 *%dest
72 ; Testg both memory division and memory remainder.
73 define i64 @f6(i64 %dummy, i64 %a, i64 *%src) {
75 ; CHECK-NOT: {{%r[234]}}
76 ; CHECK: dsg %r2, 0(%r4)
77 ; CHECK-NOT: {{dsg|dsgr}}
81 %b = load i64, i64 *%src
82 %div = sdiv i64 %a, %b
83 %rem = srem i64 %a, %b
84 %or = or i64 %rem, %div
88 ; Check the high end of the DSG range.
89 define i64 @f7(i64 %dummy, i64 %a, i64 *%src) {
91 ; CHECK: dsg %r2, 524280(%r4)
93 %ptr = getelementptr i64, i64 *%src, i64 65535
94 %b = load i64, i64 *%ptr
95 %rem = srem i64 %a, %b
99 ; Check the next doubleword up, which needs separate address logic.
100 ; Other sequences besides this one would be OK.
101 define i64 @f8(i64 %dummy, i64 %a, i64 *%src) {
103 ; CHECK: agfi %r4, 524288
104 ; CHECK: dsg %r2, 0(%r4)
106 %ptr = getelementptr i64, i64 *%src, i64 65536
107 %b = load i64, i64 *%ptr
108 %rem = srem i64 %a, %b
112 ; Check the high end of the negative aligned DSG range.
113 define i64 @f9(i64 %dummy, i64 %a, i64 *%src) {
115 ; CHECK: dsg %r2, -8(%r4)
117 %ptr = getelementptr i64, i64 *%src, i64 -1
118 %b = load i64, i64 *%ptr
119 %rem = srem i64 %a, %b
123 ; Check the low end of the DSG range.
124 define i64 @f10(i64 %dummy, i64 %a, i64 *%src) {
126 ; CHECK: dsg %r2, -524288(%r4)
128 %ptr = getelementptr i64, i64 *%src, i64 -65536
129 %b = load i64, i64 *%ptr
130 %rem = srem i64 %a, %b
134 ; Check the next doubleword down, which needs separate address logic.
135 ; Other sequences besides this one would be OK.
136 define i64 @f11(i64 %dummy, i64 %a, i64 *%src) {
138 ; CHECK: agfi %r4, -524296
139 ; CHECK: dsg %r2, 0(%r4)
141 %ptr = getelementptr i64, i64 *%src, i64 -65537
142 %b = load i64, i64 *%ptr
143 %rem = srem i64 %a, %b
147 ; Check that DSG allows an index.
148 define i64 @f12(i64 %dummy, i64 %a, i64 %src, i64 %index) {
150 ; CHECK: dsg %r2, 524287(%r5,%r4)
152 %add1 = add i64 %src, %index
153 %add2 = add i64 %add1, 524287
154 %ptr = inttoptr i64 %add2 to i64 *
155 %b = load i64, i64 *%ptr
156 %rem = srem i64 %a, %b
160 ; Check that divisions of spilled values can use DSG rather than DSGR.
161 define i64 @f13(i64 *%ptr0) {
163 ; CHECK: brasl %r14, foo@PLT
164 ; CHECK: dsg {{%r[0-9]+}}, 160(%r15)
166 %ptr1 = getelementptr i64, i64 *%ptr0, i64 2
167 %ptr2 = getelementptr i64, i64 *%ptr0, i64 4
168 %ptr3 = getelementptr i64, i64 *%ptr0, i64 6
169 %ptr4 = getelementptr i64, i64 *%ptr0, i64 8
170 %ptr5 = getelementptr i64, i64 *%ptr0, i64 10
171 %ptr6 = getelementptr i64, i64 *%ptr0, i64 12
172 %ptr7 = getelementptr i64, i64 *%ptr0, i64 14
173 %ptr8 = getelementptr i64, i64 *%ptr0, i64 16
174 %ptr9 = getelementptr i64, i64 *%ptr0, i64 18
175 %ptr10 = getelementptr i64, i64 *%ptr0, i64 20
177 %val0 = load i64, i64 *%ptr0
178 %val1 = load i64, i64 *%ptr1
179 %val2 = load i64, i64 *%ptr2
180 %val3 = load i64, i64 *%ptr3
181 %val4 = load i64, i64 *%ptr4
182 %val5 = load i64, i64 *%ptr5
183 %val6 = load i64, i64 *%ptr6
184 %val7 = load i64, i64 *%ptr7
185 %val8 = load i64, i64 *%ptr8
186 %val9 = load i64, i64 *%ptr9
187 %val10 = load i64, i64 *%ptr10
189 %ret = call i64 @foo()
191 %div0 = sdiv i64 %ret, %val0
192 %div1 = sdiv i64 %div0, %val1
193 %div2 = sdiv i64 %div1, %val2
194 %div3 = sdiv i64 %div2, %val3
195 %div4 = sdiv i64 %div3, %val4
196 %div5 = sdiv i64 %div4, %val5
197 %div6 = sdiv i64 %div5, %val6
198 %div7 = sdiv i64 %div6, %val7
199 %div8 = sdiv i64 %div7, %val8
200 %div9 = sdiv i64 %div8, %val9
201 %div10 = sdiv i64 %div9, %val10