1 # RUN: llc -run-pass=machine-combiner -o - -simplify-mir -mtriple=arm64-apple-iphoneos %s | FileCheck %s
3 # Can create FMADD, because both the fmul and fadd have all fast-math flags.
5 # CHECK-LABEL: name: scalar_fmadd_fast
6 # CHECK: [[C:%.*]]:fpr32 = COPY $s2
7 # CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1
8 # CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0
9 # CHECK-NEXT: :fpr32 = nnan ninf nsz arcp contract afn reassoc FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr
11 name: scalar_fmadd_fast
13 tracksRegLiveness: true
15 - { id: 0, class: fpr32 }
16 - { id: 1, class: fpr32 }
17 - { id: 2, class: fpr32 }
18 - { id: 3, class: fpr32 }
19 - { id: 4, class: fpr32 }
21 - { reg: '$s0', virtual-reg: '%0' }
22 - { reg: '$s1', virtual-reg: '%1' }
23 - { reg: '$s2', virtual-reg: '%2' }
27 machineFunctionInfo: {}
30 liveins: $s0, $s1, $s2
35 %3:fpr32 = nnan ninf nsz arcp contract afn reassoc FMULSrr %1, %0, implicit $fpcr
36 %4:fpr32 = nnan ninf nsz arcp contract afn reassoc FADDSrr killed %3, %2, implicit $fpcr
38 RET_ReallyLR implicit $s0
42 # Can create FMADD, because both the fmul and fadd have the contract fast-math flag.
44 # CHECK-LABEL: name: scalar_fmadd_contract
45 # CHECK: [[C:%.*]]:fpr32 = COPY $s2
46 # CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1
47 # CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0
48 # CHECK-NEXT: :fpr32 = contract FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr
51 name: scalar_fmadd_contract
53 tracksRegLiveness: true
55 - { id: 0, class: fpr32 }
56 - { id: 1, class: fpr32 }
57 - { id: 2, class: fpr32 }
58 - { id: 3, class: fpr32 }
59 - { id: 4, class: fpr32 }
61 - { reg: '$s0', virtual-reg: '%0' }
62 - { reg: '$s1', virtual-reg: '%1' }
63 - { reg: '$s2', virtual-reg: '%2' }
67 machineFunctionInfo: {}
70 liveins: $s0, $s1, $s2
75 %3:fpr32 = contract FMULSrr %1, %0, implicit $fpcr
76 %4:fpr32 = contract FADDSrr killed %3, %2, implicit $fpcr
78 RET_ReallyLR implicit $s0
82 # Do not create FMADD, because we don't have the contract flag on the FADD.
84 # CHECK-LABEL: name: scalar_fmadd_contract_op0
85 # CHECK: [[C:%.*]]:fpr32 = COPY $s2
86 # CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1
87 # CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0
88 # CHECK-NEXT: [[MUL:%.*]]:fpr32 = contract FMULSrr [[B]], [[A]], implicit $fpcr
89 # CHECK-NEXT: fpr32 = FADDSrr killed [[MUL]], [[C]], implicit $fpcr
91 name: scalar_fmadd_contract_op0
93 tracksRegLiveness: true
95 - { id: 0, class: fpr32 }
96 - { id: 1, class: fpr32 }
97 - { id: 2, class: fpr32 }
98 - { id: 3, class: fpr32 }
99 - { id: 4, class: fpr32 }
101 - { reg: '$s0', virtual-reg: '%0' }
102 - { reg: '$s1', virtual-reg: '%1' }
103 - { reg: '$s2', virtual-reg: '%2' }
107 machineFunctionInfo: {}
110 liveins: $s0, $s1, $s2
115 %3:fpr32 = contract FMULSrr %1, %0, implicit $fpcr
116 %4:fpr32 = FADDSrr killed %3, %2, implicit $fpcr
118 RET_ReallyLR implicit $s0
122 # Do create FMADD, because we have the contract flag on the FADD.
124 # CHECK-LABEL: name: scalar_fmadd_contract_op1
125 # CHECK: [[C:%.*]]:fpr32 = COPY $s2
126 # CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1
127 # CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0
128 # CHECK-NEXT: :fpr32 = contract FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr
131 name: scalar_fmadd_contract_op1
133 tracksRegLiveness: true
135 - { id: 0, class: fpr32 }
136 - { id: 1, class: fpr32 }
137 - { id: 2, class: fpr32 }
138 - { id: 3, class: fpr32 }
139 - { id: 4, class: fpr32 }
141 - { reg: '$s0', virtual-reg: '%0' }
142 - { reg: '$s1', virtual-reg: '%1' }
143 - { reg: '$s2', virtual-reg: '%2' }
147 machineFunctionInfo: {}
150 liveins: $s0, $s1, $s2
155 %3:fpr32 = FMULSrr %1, %0, implicit $fpcr
156 %4:fpr32 = contract FADDSrr killed %3, %2, implicit $fpcr
158 RET_ReallyLR implicit $s0
162 # Do not create FMADD, as nsz flag does not allow it.
164 # CHECK-LABEL: name: scalar_fmadd_nsz
165 # CHECK: [[C:%.*]]:fpr32 = COPY $s2
166 # CHECK-NEXT: [[B:%.*]]:fpr32 = COPY $s1
167 # CHECK-NEXT: [[A:%.*]]:fpr32 = COPY $s0
168 # CHECK-NEXT: [[MUL:%.*]]:fpr32 = nsz FMULSrr [[B]], [[A]], implicit $fpcr
169 # CHECK-NEXT: fpr32 = nsz FADDSrr killed [[MUL]], [[C]], implicit $fpcr
172 name: scalar_fmadd_nsz
174 tracksRegLiveness: true
176 - { id: 0, class: fpr32 }
177 - { id: 1, class: fpr32 }
178 - { id: 2, class: fpr32 }
179 - { id: 3, class: fpr32 }
180 - { id: 4, class: fpr32 }
182 - { reg: '$s0', virtual-reg: '%0' }
183 - { reg: '$s1', virtual-reg: '%1' }
184 - { reg: '$s2', virtual-reg: '%2' }
188 machineFunctionInfo: {}
191 liveins: $s0, $s1, $s2
196 %3:fpr32 = nsz FMULSrr %1, %0, implicit $fpcr
197 %4:fpr32 = nsz FADDSrr killed %3, %2, implicit $fpcr
199 RET_ReallyLR implicit $s0
203 # Can create FMLA, because both the fmul and fadd have all fast-math flags.
205 # CHECK-LABEL: name: vector_fmadd_fast
206 # CHECK: [[C:%.*]]:fpr128 = COPY $q2
207 # CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1
208 # CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0
209 # CHECK-NEXT: fpr128 = nnan ninf nsz arcp contract afn reassoc FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr
211 name: vector_fmadd_fast
213 tracksRegLiveness: true
215 - { id: 0, class: fpr128 }
216 - { id: 1, class: fpr128 }
217 - { id: 2, class: fpr128 }
218 - { id: 3, class: fpr128 }
219 - { id: 4, class: fpr128 }
221 - { reg: '$q0', virtual-reg: '%0' }
222 - { reg: '$q1', virtual-reg: '%1' }
223 - { reg: '$q2', virtual-reg: '%2' }
227 machineFunctionInfo: {}
230 liveins: $q0, $q1, $q2
235 %3:fpr128 = nnan ninf nsz arcp contract afn reassoc FMULv2f64 %1, %0, implicit $fpcr
236 %4:fpr128 = nnan ninf nsz arcp contract afn reassoc FADDv2f64 killed %3, %2, implicit $fpcr
238 RET_ReallyLR implicit $q0
242 # Can create FMLA, because both the fmul and fadd have the contract fast-math flag.
244 # CHECK-LABEL: name: vector_fmadd_contract
245 # CHECK: [[C:%.*]]:fpr128 = COPY $q2
246 # CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1
247 # CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0
248 # CHECK-NEXT: fpr128 = contract FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr
250 name: vector_fmadd_contract
252 tracksRegLiveness: true
254 - { id: 0, class: fpr128 }
255 - { id: 1, class: fpr128 }
256 - { id: 2, class: fpr128 }
257 - { id: 3, class: fpr128 }
258 - { id: 4, class: fpr128 }
260 - { reg: '$q0', virtual-reg: '%0' }
261 - { reg: '$q1', virtual-reg: '%1' }
262 - { reg: '$q2', virtual-reg: '%2' }
266 machineFunctionInfo: {}
269 liveins: $q0, $q1, $q2
274 %3:fpr128 = contract FMULv2f64 %1, %0, implicit $fpcr
275 %4:fpr128 = contract FADDv2f64 killed %3, %2, implicit $fpcr
277 RET_ReallyLR implicit $q0
281 # Do not create FMLA, because we don't have the contract flag on the FADD.
283 # CHECK-LABEL: name: vector_fmadd_contract_op0
284 # CHECK: [[C:%.*]]:fpr128 = COPY $q2
285 # CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1
286 # CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0
287 # CHECK-NEXT: [[MUL:%.*]]:fpr128 = contract FMULv2f64 [[B]], [[A]], implicit $fpcr
288 # CHECK-NEXT: fpr128 = FADDv2f64 killed [[MUL]], [[C]], implicit $fpcr
290 name: vector_fmadd_contract_op0
292 tracksRegLiveness: true
294 - { id: 0, class: fpr128 }
295 - { id: 1, class: fpr128 }
296 - { id: 2, class: fpr128 }
297 - { id: 3, class: fpr128 }
298 - { id: 4, class: fpr128 }
300 - { reg: '$q0', virtual-reg: '%0' }
301 - { reg: '$q1', virtual-reg: '%1' }
302 - { reg: '$q2', virtual-reg: '%2' }
306 machineFunctionInfo: {}
309 liveins: $q0, $q1, $q2
314 %3:fpr128 = contract FMULv2f64 %1, %0, implicit $fpcr
315 %4:fpr128 = FADDv2f64 killed %3, %2, implicit $fpcr
317 RET_ReallyLR implicit $q0
321 # Do create FMLA, because we have the contract flag on the FADD.
323 # CHECK-LABEL: name: vector_fmadd_contract_op1
324 # CHECK: [[C:%.*]]:fpr128 = COPY $q2
325 # CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1
326 # CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0
327 # CHECK-NEXT: fpr128 = contract FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr
330 name: vector_fmadd_contract_op1
332 tracksRegLiveness: true
334 - { id: 0, class: fpr128 }
335 - { id: 1, class: fpr128 }
336 - { id: 2, class: fpr128 }
337 - { id: 3, class: fpr128 }
338 - { id: 4, class: fpr128 }
340 - { reg: '$q0', virtual-reg: '%0' }
341 - { reg: '$q1', virtual-reg: '%1' }
342 - { reg: '$q2', virtual-reg: '%2' }
346 machineFunctionInfo: {}
349 liveins: $q0, $q1, $q2
354 %3:fpr128 = FMULv2f64 %1, %0, implicit $fpcr
355 %4:fpr128 = contract FADDv2f64 killed %3, %2, implicit $fpcr
357 RET_ReallyLR implicit $q0
361 # Do not create FMLA, as nsz flag does not allow it.
363 # CHECK-LABEL: name: vector_fmadd_nsz
364 # CHECK: [[C:%.*]]:fpr128 = COPY $q2
365 # CHECK-NEXT: [[B:%.*]]:fpr128 = COPY $q1
366 # CHECK-NEXT: [[A:%.*]]:fpr128 = COPY $q0
367 # CHECK-NEXT: [[MUL:%.*]]:fpr128 = nsz FMULv2f64 [[B]], [[A]], implicit $fpcr
368 # CHECK-NEXT: fpr128 = nsz FADDv2f64 killed [[MUL]], [[C]], implicit $fpcr
370 name: vector_fmadd_nsz
372 tracksRegLiveness: true
374 - { id: 0, class: fpr128 }
375 - { id: 1, class: fpr128 }
376 - { id: 2, class: fpr128 }
377 - { id: 3, class: fpr128 }
378 - { id: 4, class: fpr128 }
380 - { reg: '$q0', virtual-reg: '%0' }
381 - { reg: '$q1', virtual-reg: '%1' }
382 - { reg: '$q2', virtual-reg: '%2' }
386 machineFunctionInfo: {}
389 liveins: $q0, $q1, $q2
394 %3:fpr128 = nsz FMULv2f64 %1, %0, implicit $fpcr
395 %4:fpr128 = nsz FADDv2f64 killed %3, %2, implicit $fpcr
397 RET_ReallyLR implicit $q0