[SystemZ] Add CodeGen test cases
[oota-llvm.git] / test / CodeGen / SystemZ / int-div-01.ll
1 ; Test 32-bit signed division and remainder.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 ; Test register division.  The result is in the second of the two registers.
6 define void @f1(i32 *%dest, i32 %a, i32 %b) {
7 ; CHECK: f1:
8 ; CHECK: lgfr %r1, %r3
9 ; CHECK: dsgfr %r0, %r4
10 ; CHECK: st %r1, 0(%r2)
11 ; CHECK: br %r14
12   %div = sdiv i32 %a, %b
13   store i32 %div, i32 *%dest
14   ret void
15 }
16
17 ; Test register remainder.  The result is in the first of the two registers.
18 define void @f2(i32 *%dest, i32 %a, i32 %b) {
19 ; CHECK: f2:
20 ; CHECK: lgfr %r1, %r3
21 ; CHECK: dsgfr %r0, %r4
22 ; CHECK: st %r0, 0(%r2)
23 ; CHECK: br %r14
24   %rem = srem i32 %a, %b
25   store i32 %rem, i32 *%dest
26   ret void
27 }
28
29 ; Test that division and remainder use a single instruction.
30 define i32 @f3(i32 %dummy, i32 %a, i32 %b) {
31 ; CHECK: f3:
32 ; CHECK-NOT: %r2
33 ; CHECK: lgfr %r3, %r3
34 ; CHECK-NOT: %r2
35 ; CHECK: dsgfr %r2, %r4
36 ; CHECK-NOT: dsgfr
37 ; CHECK: or %r2, %r3
38 ; CHECK: br %r14
39   %div = sdiv i32 %a, %b
40   %rem = srem i32 %a, %b
41   %or = or i32 %rem, %div
42   ret i32 %or
43 }
44
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) {
48 ; CHECK: f4:
49 ; CHECK-NOT: {{%r[234]}}
50 ; CHECK: dsgfr %r2, %r4
51 ; CHECK-NOT: dsgfr
52 ; CHECK: or %r2, %r3
53 ; CHECK: br %r14
54   %div = sdiv i32 %a, %b
55   %rem = srem i32 %a, %b
56   %or = or i32 %rem, %div
57   ret i32 %or
58 }
59
60 ; Test that memory dividends are loaded using sign extension (LGF).
61 define i32 @f5(i32 %dummy, i32 *%src, i32 %b) {
62 ; CHECK: f5:
63 ; CHECK-NOT: %r2
64 ; CHECK: lgf %r3, 0(%r3)
65 ; CHECK-NOT: %r2
66 ; CHECK: dsgfr %r2, %r4
67 ; CHECK-NOT: dsgfr
68 ; CHECK: or %r2, %r3
69 ; CHECK: br %r14
70   %a = load i32 *%src
71   %div = sdiv i32 %a, %b
72   %rem = srem i32 %a, %b
73   %or = or i32 %rem, %div
74   ret i32 %or
75 }
76
77 ; Test memory division with no displacement.
78 define void @f6(i32 *%dest, i32 %a, i32 *%src) {
79 ; CHECK: f6:
80 ; CHECK: lgfr %r1, %r3
81 ; CHECK: dsgf %r0, 0(%r4)
82 ; CHECK: st %r1, 0(%r2)
83 ; CHECK: br %r14
84   %b = load i32 *%src
85   %div = sdiv i32 %a, %b
86   store i32 %div, i32 *%dest
87   ret void
88 }
89
90 ; Test memory remainder with no displacement.
91 define void @f7(i32 *%dest, i32 %a, i32 *%src) {
92 ; CHECK: f7:
93 ; CHECK: lgfr %r1, %r3
94 ; CHECK: dsgf %r0, 0(%r4)
95 ; CHECK: st %r0, 0(%r2)
96 ; CHECK: br %r14
97   %b = load i32 *%src
98   %rem = srem i32 %a, %b
99   store i32 %rem, i32 *%dest
100   ret void
101 }
102
103 ; Test both memory division and memory remainder.
104 define i32 @f8(i32 %dummy, i32 %a, i32 *%src) {
105 ; CHECK: f8:
106 ; CHECK-NOT: %r2
107 ; CHECK: lgfr %r3, %r3
108 ; CHECK-NOT: %r2
109 ; CHECK: dsgf %r2, 0(%r4)
110 ; CHECK-NOT: {{dsgf|dsgfr}}
111 ; CHECK: or %r2, %r3
112 ; CHECK: br %r14
113   %b = load i32 *%src
114   %div = sdiv i32 %a, %b
115   %rem = srem i32 %a, %b
116   %or = or i32 %rem, %div
117   ret i32 %or
118 }
119
120 ; Check the high end of the DSGF range.
121 define i32 @f9(i32 %dummy, i32 %a, i32 *%src) {
122 ; CHECK: f9:
123 ; CHECK: dsgf %r2, 524284(%r4)
124 ; CHECK: br %r14
125   %ptr = getelementptr i32 *%src, i64 131071
126   %b = load i32 *%ptr
127   %rem = srem i32 %a, %b
128   ret i32 %rem
129 }
130
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) {
134 ; CHECK: f10:
135 ; CHECK: agfi %r4, 524288
136 ; CHECK: dsgf %r2, 0(%r4)
137 ; CHECK: br %r14
138   %ptr = getelementptr i32 *%src, i64 131072
139   %b = load i32 *%ptr
140   %rem = srem i32 %a, %b
141   ret i32 %rem
142 }
143
144 ; Check the high end of the negative aligned DSGF range.
145 define i32 @f11(i32 %dummy, i32 %a, i32 *%src) {
146 ; CHECK: f11:
147 ; CHECK: dsgf %r2, -4(%r4)
148 ; CHECK: br %r14
149   %ptr = getelementptr i32 *%src, i64 -1
150   %b = load i32 *%ptr
151   %rem = srem i32 %a, %b
152   ret i32 %rem
153 }
154
155 ; Check the low end of the DSGF range.
156 define i32 @f12(i32 %dummy, i32 %a, i32 *%src) {
157 ; CHECK: f12:
158 ; CHECK: dsgf %r2, -524288(%r4)
159 ; CHECK: br %r14
160   %ptr = getelementptr i32 *%src, i64 -131072
161   %b = load i32 *%ptr
162   %rem = srem i32 %a, %b
163   ret i32 %rem
164 }
165
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) {
169 ; CHECK: f13:
170 ; CHECK: agfi %r4, -524292
171 ; CHECK: dsgf %r2, 0(%r4)
172 ; CHECK: br %r14
173   %ptr = getelementptr i32 *%src, i64 -131073
174   %b = load i32 *%ptr
175   %rem = srem i32 %a, %b
176   ret i32 %rem
177 }
178
179 ; Check that DSGF allows an index.
180 define i32 @f14(i32 %dummy, i32 %a, i64 %src, i64 %index) {
181 ; CHECK: f14:
182 ; CHECK: dsgf %r2, 524287(%r5,%r4)
183 ; CHECK: br %r14
184   %add1 = add i64 %src, %index
185   %add2 = add i64 %add1, 524287
186   %ptr = inttoptr i64 %add2 to i32 *
187   %b = load i32 *%ptr
188   %rem = srem i32 %a, %b
189   ret i32 %rem
190 }