[DAGCombiner] Eliminate dead stores to stack.
[llvm-complete.git] / test / CodeGen / Mips / madd-msub.ll
blobc5f7af1de20d5b65f98202424bbc7a9495f50dae
1 ; RUN: llc -march=mips -mcpu=mips32 < %s \
2 ; RUN:   | FileCheck %s -check-prefixes=ALL,32
3 ; RUN: llc -march=mips -mcpu=mips32r2 < %s \
4 ; RUN:   | FileCheck %s -check-prefixes=ALL,32
5 ; RUN: llc -march=mips -mcpu=mips32r6 < %s \
6 ; RUN:   | FileCheck %s -check-prefixes=ALL,32R6
7 ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s \
8 ; RUN:   | FileCheck %s -check-prefix=DSP
9 ; RUN: llc -march=mips -mcpu=mips64   -target-abi n64 < %s \
10 ; RUN:   | FileCheck %s -check-prefixes=ALL,64
11 ; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s \
12 ; RUN:   | FileCheck %s -check-prefixes=ALL,64
13 ; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s \
14 ; RUN:   | FileCheck %s -check-prefixes=ALL,64R6
16 ; FIXME: The MIPS16 test should check its output
17 ; RUN: llc -march=mips -mattr=mips16 < %s
19 ; ALL-LABEL: madd1:
21 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
22 ; 32-DAG:        mtlo $6
23 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
24 ; 32-DAG:        [[m]]fhi $2
25 ; 32-DAG:        [[m]]flo $3
27 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
28 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
29 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
30 ; DSP-DAG:       mfhi $2, $[[AC]]
31 ; DSP-DAG:       mflo $3, $[[AC]]
33 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
34 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
35 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
36 ; 32R6-DAG:      muh  $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
37 ; 32R6-DAG:      sra  $[[T4:[0-9]+]], $6, 31
38 ; 32R6-DAG:      addu $[[T5:[0-9]+]], $[[T3]], $[[T4]]
39 ; 32R6-DAG:      addu $2, $[[T5]], $[[T2]]
41 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
42 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
43 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
44 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
45 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
46 ; 64-DAG:        daddu $2, $[[T2]], $[[T3]]
48 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
49 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
50 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
51 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
52 ; 64R6-DAG:      daddu $2, $[[T2]], $[[T3]]
54 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
55 entry:
56   %conv = sext i32 %a to i64
57   %conv2 = sext i32 %b to i64
58   %mul = mul nsw i64 %conv2, %conv
59   %conv4 = sext i32 %c to i64
60   %add = add nsw i64 %mul, %conv4
61   ret i64 %add
64 ; ALL-LABEL: madd2:
66 ; FIXME: We don't really need this instruction
67 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
68 ; 32-DAG:        mtlo $6
69 ; 32-DAG:        [[m:m]]addu ${{[45]}}, ${{[45]}}
70 ; 32-DAG:        [[m]]fhi $2
71 ; 32-DAG:        [[m]]flo $3
73 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
74 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
75 ; DSP-DAG:       maddu $[[AC]], ${{[45]}}, ${{[45]}}
76 ; DSP-DAG:       mfhi $2, $[[AC]]
77 ; DSP-DAG:       mflo $3, $[[AC]]
79 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
80 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
81 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
82 ; FIXME: There's a redundant move here. We should remove it
83 ; 32R6-DAG:      muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
84 ; 32R6-DAG:      addu $2, $[[T3]], $[[T2]]
86 ; 64-DAG:        d[[m:m]]ult $5, $4
87 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
88 ; 64-DAG:        daddu $2, $[[T0]], $6
90 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
91 ; 64R6-DAG:      daddu $2, $[[T0]], $6
93 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
94 entry:
95   %conv = zext i32 %a to i64
96   %conv2 = zext i32 %b to i64
97   %mul = mul nsw i64 %conv2, %conv
98   %conv4 = zext i32 %c to i64
99   %add = add nsw i64 %mul, %conv4
100   ret i64 %add
103 ; ALL-LABEL: madd3:
105 ; 32-DAG:        mthi $6
106 ; 32-DAG:        mtlo $7
107 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
108 ; 32-DAG:        [[m]]fhi $2
109 ; 32-DAG:        [[m]]flo $3
111 ; DSP-DAG:       mthi $6, $[[AC:ac[0-3]+]]
112 ; DSP-DAG:       mtlo $7, $[[AC]]
113 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
114 ; DSP-DAG:       mfhi $2, $[[AC]]
115 ; DSP-DAG:       mflo $3, $[[AC]]
117 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
118 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
119 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $1
120 ; 32R6-DAG:      muh  $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
121 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $6
122 ; 32R6-DAG:      addu $2, $[[T4]], $[[T2]]
124 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
125 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
126 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
127 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
128 ; 64-DAG:        daddu $2, $[[T2]], $6
130 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
131 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
132 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
133 ; 64R6-DAG:      daddu $2, $[[T2]], $6
135 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
136 entry:
137   %conv = sext i32 %a to i64
138   %conv2 = sext i32 %b to i64
139   %mul = mul nsw i64 %conv2, %conv
140   %add = add nsw i64 %mul, %c
141   ret i64 %add
144 ; ALL-LABEL: madd4
145 ; ALL-NOT: madd ${{[0-9]+}}, ${{[0-9]+}}
147 define i32 @madd4(i32 %a, i32 %b, i32 %c) {
148 entry:
149   %mul = mul nsw i32 %a, %b
150   %add = add nsw i32 %c, %mul
152   ret i32 %add
155 ; ALL-LABEL: msub1:
157 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
158 ; 32-DAG:        mtlo $6
159 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
160 ; 32-DAG:        [[m]]fhi $2
161 ; 32-DAG:        [[m]]flo $3
163 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
164 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
165 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
166 ; DSP-DAG:       mfhi $2, $[[AC]]
167 ; DSP-DAG:       mflo $3, $[[AC]]
169 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
170 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $6, $[[T0]]
171 ; 32R6-DAG:      muh  $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
172 ; 32R6-DAG:      sra  $[[T3:[0-9]+]], $6, 31
173 ; 32R6-DAG:      subu $[[T4:[0-9]+]], $[[T3]], $[[T2]]
174 ; 32R6-DAG:      subu $2, $[[T4]], $[[T1]]
175 ; 32R6-DAG:      subu $3, $6, $[[T0]]
177 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
178 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
179 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
180 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
181 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
182 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
184 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
185 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
186 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
187 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
188 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
190 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
191 entry:
192   %conv = sext i32 %c to i64
193   %conv2 = sext i32 %a to i64
194   %conv4 = sext i32 %b to i64
195   %mul = mul nsw i64 %conv4, %conv2
196   %sub = sub nsw i64 %conv, %mul
197   ret i64 %sub
200 ; ALL-LABEL: msub2:
202 ; FIXME: We don't really need this instruction
203 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
204 ; 32-DAG:        mtlo $6
205 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
206 ; 32-DAG:        [[m]]fhi $2
207 ; 32-DAG:        [[m]]flo $3
209 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
210 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
211 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
212 ; DSP-DAG:       mfhi $2, $[[AC]]
213 ; DSP-DAG:       mflo $3, $[[AC]]
215 ; 32R6-DAG:      mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
216 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $6, $[[T0]]
217 ; 32R6-DAG:      muhu $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
218 ; 32R6-DAG:      negu $[[T3:[0-9]+]], $[[T2]]
219 ; 32R6-DAG:      subu $2, $[[T3]], $[[T1]]
220 ; 32R6-DAG:      subu $3, $6, $[[T0]]
222 ; 64-DAG:        d[[m:m]]ult $5, $4
223 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
224 ; 64-DAG:        dsubu $2, $6, $[[T0]]
226 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
227 ; 64R6-DAG:      dsubu $2, $6, $[[T0]]
229 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
230 entry:
231   %conv = zext i32 %c to i64
232   %conv2 = zext i32 %a to i64
233   %conv4 = zext i32 %b to i64
234   %mul = mul nsw i64 %conv4, %conv2
235   %sub = sub nsw i64 %conv, %mul
236   ret i64 %sub
239 ; ALL-LABEL: msub3:
241 ; FIXME: We don't really need this instruction
242 ; 32-DAG:        mthi $6
243 ; 32-DAG:        mtlo $7
244 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
245 ; 32-DAG:        [[m]]fhi $2
246 ; 32-DAG:        [[m]]flo $3
248 ; DSP-DAG:       mtlo $7, $[[AC:ac[0-3]+]]
249 ; DSP-DAG:       mthi $6, $[[AC]]
250 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
251 ; DSP-DAG:       mfhi $2, $[[AC]]
252 ; DSP-DAG:       mflo $3, $[[AC]]
254 ; 32R6-DAG:      mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
255 ; 32R6-DAG:      sltu $[[T1:[0-9]+]], $7, $[[T0]]
256 ; 32R6-DAG:      muh $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
257 ; 32R6-DAG:      subu $[[T3:[0-9]+]], $6, $[[T2]]
258 ; 32R6-DAG:      subu $2, $[[T3]], $[[T1]]
259 ; 32R6-DAG:      subu $3, $7, $[[T0]]
261 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
262 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
263 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
264 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
265 ; 64-DAG:        dsubu $2, $6, $[[T2]]
267 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
268 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
269 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
270 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
272 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
273 entry:
274   %conv = sext i32 %a to i64
275   %conv3 = sext i32 %b to i64
276   %mul = mul nsw i64 %conv3, %conv
277   %sub = sub nsw i64 %c, %mul
278   ret i64 %sub
281 ; ALL-LABEL: msub4
282 ; ALL-NOT: msub ${{[0-9]+}}, ${{[0-9]+}}
284 define i32 @msub4(i32 %a, i32 %b, i32 %c) {
285 entry:
286   %mul = mul nsw i32 %a, %b
287   %sub = sub nsw i32 %c, %mul
289   ret i32 %sub