1 ; Test 32-bit signed division and remainder.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Test register division. The result is in the second of the two registers.
6 define void @f1(i32 *%dest, i32 %a, i32 %b) {
9 ; CHECK: dsgfr %r0, %r4
10 ; CHECK: st %r1, 0(%r2)
12 %div = sdiv i32 %a, %b
13 store i32 %div, i32 *%dest
17 ; Test register remainder. The result is in the first of the two registers.
18 define void @f2(i32 *%dest, i32 %a, i32 %b) {
20 ; CHECK: lgfr %r1, %r3
21 ; CHECK: dsgfr %r0, %r4
22 ; CHECK: st %r0, 0(%r2)
24 %rem = srem i32 %a, %b
25 store i32 %rem, i32 *%dest
29 ; Test that division and remainder use a single instruction.
30 define i32 @f3(i32 %dummy, i32 %a, i32 %b) {
33 ; CHECK: lgfr %r3, %r3
35 ; CHECK: dsgfr %r2, %r4
39 %div = sdiv i32 %a, %b
40 %rem = srem i32 %a, %b
41 %or = or i32 %rem, %div
45 ; Check that the sign extension of the dividend is elided when the argument
46 ; is already sign-extended.
47 define i32 @f4(i32 %dummy, i32 signext %a, i32 %b) {
49 ; CHECK-NOT: {{%r[234]}}
50 ; CHECK: dsgfr %r2, %r4
54 %div = sdiv i32 %a, %b
55 %rem = srem i32 %a, %b
56 %or = or i32 %rem, %div
60 ; Test that memory dividends are loaded using sign extension (LGF).
61 define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
64 ; CHECK: lgf %r3, 0(%r3)
66 ; CHECK: dsgfr %r2, %r4
71 %div = sdiv i32 %a, %b
72 %rem = srem i32 %a, %b
73 %or = or i32 %rem, %div
77 ; Test memory division with no displacement.
78 define void @f6(i32 *%dest, i32 %a, i32 *%src) {
80 ; CHECK: lgfr %r1, %r3
81 ; CHECK: dsgf %r0, 0(%r4)
82 ; CHECK: st %r1, 0(%r2)
85 %div = sdiv i32 %a, %b
86 store i32 %div, i32 *%dest
90 ; Test memory remainder with no displacement.
91 define void @f7(i32 *%dest, i32 %a, i32 *%src) {
93 ; CHECK: lgfr %r1, %r3
94 ; CHECK: dsgf %r0, 0(%r4)
95 ; CHECK: st %r0, 0(%r2)
98 %rem = srem i32 %a, %b
99 store i32 %rem, i32 *%dest
103 ; Test both memory division and memory remainder.
104 define i32 @f8(i32 %dummy, i32 %a, i32 *%src) {
107 ; CHECK: lgfr %r3, %r3
109 ; CHECK: dsgf %r2, 0(%r4)
110 ; CHECK-NOT: {{dsgf|dsgfr}}
114 %div = sdiv i32 %a, %b
115 %rem = srem i32 %a, %b
116 %or = or i32 %rem, %div
120 ; Check the high end of the DSGF range.
121 define i32 @f9(i32 %dummy, i32 %a, i32 *%src) {
123 ; CHECK: dsgf %r2, 524284(%r4)
125 %ptr = getelementptr i32 *%src, i64 131071
127 %rem = srem i32 %a, %b
131 ; Check the next word up, which needs separate address logic.
132 ; Other sequences besides this one would be OK.
133 define i32 @f10(i32 %dummy, i32 %a, i32 *%src) {
135 ; CHECK: agfi %r4, 524288
136 ; CHECK: dsgf %r2, 0(%r4)
138 %ptr = getelementptr i32 *%src, i64 131072
140 %rem = srem i32 %a, %b
144 ; Check the high end of the negative aligned DSGF range.
145 define i32 @f11(i32 %dummy, i32 %a, i32 *%src) {
147 ; CHECK: dsgf %r2, -4(%r4)
149 %ptr = getelementptr i32 *%src, i64 -1
151 %rem = srem i32 %a, %b
155 ; Check the low end of the DSGF range.
156 define i32 @f12(i32 %dummy, i32 %a, i32 *%src) {
158 ; CHECK: dsgf %r2, -524288(%r4)
160 %ptr = getelementptr i32 *%src, i64 -131072
162 %rem = srem i32 %a, %b
166 ; Check the next word down, which needs separate address logic.
167 ; Other sequences besides this one would be OK.
168 define i32 @f13(i32 %dummy, i32 %a, i32 *%src) {
170 ; CHECK: agfi %r4, -524292
171 ; CHECK: dsgf %r2, 0(%r4)
173 %ptr = getelementptr i32 *%src, i64 -131073
175 %rem = srem i32 %a, %b
179 ; Check that DSGF allows an index.
180 define i32 @f14(i32 %dummy, i32 %a, i64 %src, i64 %index) {
182 ; CHECK: dsgf %r2, 524287(%r5,%r4)
184 %add1 = add i64 %src, %index
185 %add2 = add i64 %add1, 524287
186 %ptr = inttoptr i64 %add2 to i32 *
188 %rem = srem i32 %a, %b