[PowerPC] Generate Power9 extswsli extend sign and shift immediate instruction
[llvm-core.git] / test / CodeGen / Mips / madd-msub.ll
blob776491973cb34c120d616d4e582fa05d8a541b0b
1 ; RUN: llc -march=mips -mcpu=mips32   < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,32
2 ; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,32
3 ; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,32R6
4 ; RUN: llc -march=mips -mcpu=mips32 -mattr=dsp < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=DSP
5 ; RUN: llc -march=mips -mcpu=mips64   -target-abi n64 < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,64
6 ; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,64
7 ; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,64R6
9 ; FIXME: The MIPS16 test should check its output
10 ; RUN: llc -march=mips -mattr=mips16 < %s
12 ; ALL-LABEL: madd1:
14 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
15 ; 32-DAG:        mtlo $6
16 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
17 ; 32-DAG:        [[m]]fhi $2
18 ; 32-DAG:        [[m]]flo $3
20 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
21 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
22 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
23 ; DSP-DAG:       mfhi $2, $[[AC]]
24 ; DSP-DAG:       mflo $3, $[[AC]]
26 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
27 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
28 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
29 ; 32R6-DAG:      muh  $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
30 ; 32R6-DAG:      sra  $[[T4:[0-9]+]], $6, 31
31 ; 32R6-DAG:      addu $[[T5:[0-9]+]], $[[T3]], $[[T4]]
32 ; 32R6-DAG:      addu $2, $[[T5]], $[[T2]]
34 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
35 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
36 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
37 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
38 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
39 ; 64-DAG:        daddu $2, $[[T2]], $[[T3]]
41 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
42 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
43 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
44 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
45 ; 64R6-DAG:      daddu $2, $[[T2]], $[[T3]]
47 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
48 entry:
49   %conv = sext i32 %a to i64
50   %conv2 = sext i32 %b to i64
51   %mul = mul nsw i64 %conv2, %conv
52   %conv4 = sext i32 %c to i64
53   %add = add nsw i64 %mul, %conv4
54   ret i64 %add
57 ; ALL-LABEL: madd2:
59 ; FIXME: We don't really need this instruction
60 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
61 ; 32-DAG:        mtlo $6
62 ; 32-DAG:        [[m:m]]addu ${{[45]}}, ${{[45]}}
63 ; 32-DAG:        [[m]]fhi $2
64 ; 32-DAG:        [[m]]flo $3
66 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
67 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
68 ; DSP-DAG:       maddu $[[AC]], ${{[45]}}, ${{[45]}}
69 ; DSP-DAG:       mfhi $2, $[[AC]]
70 ; DSP-DAG:       mflo $3, $[[AC]]
72 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
73 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
74 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
75 ; FIXME: There's a redundant move here. We should remove it
76 ; 32R6-DAG:      muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
77 ; 32R6-DAG:      addu $2, $[[T3]], $[[T2]]
79 ; 64-DAG:        d[[m:m]]ult $5, $4
80 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
81 ; 64-DAG:        daddu $2, $[[T0]], $6
83 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
84 ; 64R6-DAG:      daddu $2, $[[T0]], $6
86 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
87 entry:
88   %conv = zext i32 %a to i64
89   %conv2 = zext i32 %b to i64
90   %mul = mul nsw i64 %conv2, %conv
91   %conv4 = zext i32 %c to i64
92   %add = add nsw i64 %mul, %conv4
93   ret i64 %add
96 ; ALL-LABEL: madd3:
98 ; 32-DAG:        mthi $6
99 ; 32-DAG:        mtlo $7
100 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
101 ; 32-DAG:        [[m]]fhi $2
102 ; 32-DAG:        [[m]]flo $3
104 ; DSP-DAG:       mthi $6, $[[AC:ac[0-3]+]]
105 ; DSP-DAG:       mtlo $7, $[[AC]]
106 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
107 ; DSP-DAG:       mfhi $2, $[[AC]]
108 ; DSP-DAG:       mflo $3, $[[AC]]
110 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
111 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
112 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $1
113 ; 32R6-DAG:      muh  $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
114 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $6
115 ; 32R6-DAG:      addu $2, $[[T4]], $[[T2]]
117 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
118 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
119 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
120 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
121 ; 64-DAG:        daddu $2, $[[T2]], $6
123 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
124 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
125 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
126 ; 64R6-DAG:      daddu $2, $[[T2]], $6
128 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
129 entry:
130   %conv = sext i32 %a to i64
131   %conv2 = sext i32 %b to i64
132   %mul = mul nsw i64 %conv2, %conv
133   %add = add nsw i64 %mul, %c
134   ret i64 %add
137 ; ALL-LABEL: madd4
138 ; ALL-NOT: madd ${{[0-9]+}}, ${{[0-9]+}}
140 define i32 @madd4(i32 %a, i32 %b, i32 %c) {
141 entry:
142   %mul = mul nsw i32 %a, %b
143   %add = add nsw i32 %c, %mul
145   ret i32 %add
148 ; ALL-LABEL: msub1:
150 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
151 ; 32-DAG:        mtlo $6
152 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
153 ; 32-DAG:        [[m]]fhi $2
154 ; 32-DAG:        [[m]]flo $3
156 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
157 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
158 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
159 ; DSP-DAG:       mfhi $2, $[[AC]]
160 ; DSP-DAG:       mflo $3, $[[AC]]
162 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
163 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $6, $[[T0]]
164 ; 32R6-DAG:      muh  $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
165 ; 32R6-DAG:      sra  $[[T3:[0-9]+]], $6, 31
166 ; 32R6-DAG:      subu $[[T4:[0-9]+]], $[[T3]], $[[T2]]
167 ; 32R6-DAG:      subu $2, $[[T4]], $[[T1]]
168 ; 32R6-DAG:      subu $3, $6, $[[T0]]
170 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
171 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
172 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
173 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
174 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
175 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
177 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
178 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
179 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
180 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
181 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
183 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
184 entry:
185   %conv = sext i32 %c to i64
186   %conv2 = sext i32 %a to i64
187   %conv4 = sext i32 %b to i64
188   %mul = mul nsw i64 %conv4, %conv2
189   %sub = sub nsw i64 %conv, %mul
190   ret i64 %sub
193 ; ALL-LABEL: msub2:
195 ; FIXME: We don't really need this instruction
196 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
197 ; 32-DAG:        mtlo $6
198 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
199 ; 32-DAG:        [[m]]fhi $2
200 ; 32-DAG:        [[m]]flo $3
202 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
203 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
204 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
205 ; DSP-DAG:       mfhi $2, $[[AC]]
206 ; DSP-DAG:       mflo $3, $[[AC]]
208 ; 32R6-DAG:      mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
209 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $6, $[[T0]]
210 ; 32R6-DAG:      muhu $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
211 ; 32R6-DAG:      negu $[[T3:[0-9]+]], $[[T2]]
212 ; 32R6-DAG:      subu $2, $[[T3]], $[[T1]]
213 ; 32R6-DAG:      subu $3, $6, $[[T0]]
215 ; 64-DAG:        d[[m:m]]ult $5, $4
216 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
217 ; 64-DAG:        dsubu $2, $6, $[[T0]]
219 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
220 ; 64R6-DAG:      dsubu $2, $6, $[[T0]]
222 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
223 entry:
224   %conv = zext i32 %c to i64
225   %conv2 = zext i32 %a to i64
226   %conv4 = zext i32 %b to i64
227   %mul = mul nsw i64 %conv4, %conv2
228   %sub = sub nsw i64 %conv, %mul
229   ret i64 %sub
232 ; ALL-LABEL: msub3:
234 ; FIXME: We don't really need this instruction
235 ; 32-DAG:        mthi $6
236 ; 32-DAG:        mtlo $7
237 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
238 ; 32-DAG:        [[m]]fhi $2
239 ; 32-DAG:        [[m]]flo $3
241 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
242 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
243 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
244 ; DSP-DAG:       mfhi $2, $[[AC]]
245 ; DSP-DAG:       mflo $3, $[[AC]]
247 ; 32R6-DAG:      mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
248 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $7, $[[T0]]
249 ; 32R6-DAG:      muh $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
250 ; 32R6-DAG:      subu $[[T3:[0-9]+]], $6, $[[T2]]
251 ; 32R6-DAG:      subu $2, $[[T3]], $[[T1]]
252 ; 32R6-DAG:      subu $3, $7, $[[T0]]
254 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
255 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
256 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
257 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
258 ; 64-DAG:        dsubu $2, $6, $[[T2]]
260 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
261 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
262 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
263 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
265 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
266 entry:
267   %conv = sext i32 %a to i64
268   %conv3 = sext i32 %b to i64
269   %mul = mul nsw i64 %conv3, %conv
270   %sub = sub nsw i64 %c, %mul
271   ret i64 %sub
274 ; ALL-LABEL: msub4
275 ; ALL-NOT: msub ${{[0-9]+}}, ${{[0-9]+}}
277 define i32 @msub4(i32 %a, i32 %b, i32 %c) {
278 entry:
279   %mul = mul nsw i32 %a, %b
280   %sub = sub nsw i32 %c, %mul
282   ret i32 %sub