| # RUN: llc -run-pass=machine-combiner -o - -simplify-mir -mtriple=arm64-apple-iphoneos %s | FileCheck %s | 
 |  | 
 | # Can create FMADD, because both the fmul and fadd have all fast-math flags. | 
 | # | 
 | # CHECK-LABEL: name: scalar_fmadd_fast | 
 | # CHECK:        [[C:%.*]]:fpr32 = COPY $s2 | 
 | # CHECK-NEXT:   [[B:%.*]]:fpr32 = COPY $s1 | 
 | # CHECK-NEXT:   [[A:%.*]]:fpr32 = COPY $s0 | 
 | # CHECK-NEXT:   :fpr32 = nnan ninf nsz arcp contract afn reassoc FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr | 
 | --- | 
 | name:            scalar_fmadd_fast | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr32 } | 
 |   - { id: 1, class: fpr32 } | 
 |   - { id: 2, class: fpr32 } | 
 |   - { id: 3, class: fpr32 } | 
 |   - { id: 4, class: fpr32 } | 
 | liveins: | 
 |   - { reg: '$s0', virtual-reg: '%0' } | 
 |   - { reg: '$s1', virtual-reg: '%1' } | 
 |   - { reg: '$s2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $s0, $s1, $s2 | 
 |  | 
 |     %2:fpr32 = COPY $s2 | 
 |     %1:fpr32 = COPY $s1 | 
 |     %0:fpr32 = COPY $s0 | 
 |     %3:fpr32 = nnan ninf nsz arcp contract afn reassoc FMULSrr %1, %0, implicit $fpcr | 
 |     %4:fpr32 = nnan ninf nsz arcp contract afn reassoc FADDSrr killed %3, %2, implicit $fpcr | 
 |     $s0 = COPY %4 | 
 |     RET_ReallyLR implicit $s0 | 
 |  | 
 | ... | 
 |  | 
 | # Can create FMADD, because both the fmul and fadd have the contract fast-math flag. | 
 | # | 
 | # CHECK-LABEL: name: scalar_fmadd_contract | 
 | # CHECK:        [[C:%.*]]:fpr32 = COPY $s2 | 
 | # CHECK-NEXT:   [[B:%.*]]:fpr32 = COPY $s1 | 
 | # CHECK-NEXT:   [[A:%.*]]:fpr32 = COPY $s0 | 
 | # CHECK-NEXT:   :fpr32 = contract FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr | 
 |  | 
 | --- | 
 | name:            scalar_fmadd_contract | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr32 } | 
 |   - { id: 1, class: fpr32 } | 
 |   - { id: 2, class: fpr32 } | 
 |   - { id: 3, class: fpr32 } | 
 |   - { id: 4, class: fpr32 } | 
 | liveins: | 
 |   - { reg: '$s0', virtual-reg: '%0' } | 
 |   - { reg: '$s1', virtual-reg: '%1' } | 
 |   - { reg: '$s2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $s0, $s1, $s2 | 
 |  | 
 |     %2:fpr32 = COPY $s2 | 
 |     %1:fpr32 = COPY $s1 | 
 |     %0:fpr32 = COPY $s0 | 
 |     %3:fpr32 = contract FMULSrr %1, %0, implicit $fpcr | 
 |     %4:fpr32 = contract FADDSrr killed %3, %2, implicit $fpcr | 
 |     $s0 = COPY %4 | 
 |     RET_ReallyLR implicit $s0 | 
 |  | 
 | ... | 
 |  | 
 | # Do not create FMADD, because we don't have the contract flag on the FADD. | 
 |  | 
 | # CHECK-LABEL: name: scalar_fmadd_contract_op0 | 
 | # CHECK:        [[C:%.*]]:fpr32 = COPY $s2 | 
 | # CHECK-NEXT:   [[B:%.*]]:fpr32 = COPY $s1 | 
 | # CHECK-NEXT:   [[A:%.*]]:fpr32 = COPY $s0 | 
 | # CHECK-NEXT:   [[MUL:%.*]]:fpr32 = contract FMULSrr [[B]], [[A]], implicit $fpcr | 
 | # CHECK-NEXT:   fpr32 = FADDSrr killed [[MUL]], [[C]], implicit $fpcr | 
 | --- | 
 | name:            scalar_fmadd_contract_op0 | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr32 } | 
 |   - { id: 1, class: fpr32 } | 
 |   - { id: 2, class: fpr32 } | 
 |   - { id: 3, class: fpr32 } | 
 |   - { id: 4, class: fpr32 } | 
 | liveins: | 
 |   - { reg: '$s0', virtual-reg: '%0' } | 
 |   - { reg: '$s1', virtual-reg: '%1' } | 
 |   - { reg: '$s2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $s0, $s1, $s2 | 
 |  | 
 |     %2:fpr32 = COPY $s2 | 
 |     %1:fpr32 = COPY $s1 | 
 |     %0:fpr32 = COPY $s0 | 
 |     %3:fpr32 = contract FMULSrr %1, %0, implicit $fpcr | 
 |     %4:fpr32 = FADDSrr killed %3, %2, implicit $fpcr | 
 |     $s0 = COPY %4 | 
 |     RET_ReallyLR implicit $s0 | 
 |  | 
 | ... | 
 |  | 
 | # Do create FMADD, because we have the contract flag on the FADD. | 
 | # | 
 | # CHECK-LABEL: name: scalar_fmadd_contract_op1 | 
 | # CHECK:        [[C:%.*]]:fpr32 = COPY $s2 | 
 | # CHECK-NEXT:   [[B:%.*]]:fpr32 = COPY $s1 | 
 | # CHECK-NEXT:   [[A:%.*]]:fpr32 = COPY $s0 | 
 | # CHECK-NEXT:   :fpr32 = contract FMADDSrrr [[B]], [[A]], [[C]], implicit $fpcr | 
 |  | 
 | --- | 
 | name:            scalar_fmadd_contract_op1 | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr32 } | 
 |   - { id: 1, class: fpr32 } | 
 |   - { id: 2, class: fpr32 } | 
 |   - { id: 3, class: fpr32 } | 
 |   - { id: 4, class: fpr32 } | 
 | liveins: | 
 |   - { reg: '$s0', virtual-reg: '%0' } | 
 |   - { reg: '$s1', virtual-reg: '%1' } | 
 |   - { reg: '$s2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $s0, $s1, $s2 | 
 |  | 
 |     %2:fpr32 = COPY $s2 | 
 |     %1:fpr32 = COPY $s1 | 
 |     %0:fpr32 = COPY $s0 | 
 |     %3:fpr32 = FMULSrr %1, %0, implicit $fpcr | 
 |     %4:fpr32 = contract FADDSrr killed %3, %2, implicit $fpcr | 
 |     $s0 = COPY %4 | 
 |     RET_ReallyLR implicit $s0 | 
 |  | 
 | ... | 
 |  | 
 | # Do not create FMADD, as nsz flag does not allow it. | 
 | # | 
 | # CHECK-LABEL: name: scalar_fmadd_nsz | 
 | # CHECK:        [[C:%.*]]:fpr32 = COPY $s2 | 
 | # CHECK-NEXT:   [[B:%.*]]:fpr32 = COPY $s1 | 
 | # CHECK-NEXT:   [[A:%.*]]:fpr32 = COPY $s0 | 
 | # CHECK-NEXT:   [[MUL:%.*]]:fpr32 = nsz FMULSrr [[B]], [[A]], implicit $fpcr | 
 | # CHECK-NEXT:   fpr32 = nsz FADDSrr killed [[MUL]], [[C]], implicit $fpcr | 
 |  | 
 | --- | 
 | name:            scalar_fmadd_nsz | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr32 } | 
 |   - { id: 1, class: fpr32 } | 
 |   - { id: 2, class: fpr32 } | 
 |   - { id: 3, class: fpr32 } | 
 |   - { id: 4, class: fpr32 } | 
 | liveins: | 
 |   - { reg: '$s0', virtual-reg: '%0' } | 
 |   - { reg: '$s1', virtual-reg: '%1' } | 
 |   - { reg: '$s2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $s0, $s1, $s2 | 
 |  | 
 |     %2:fpr32 = COPY $s2 | 
 |     %1:fpr32 = COPY $s1 | 
 |     %0:fpr32 = COPY $s0 | 
 |     %3:fpr32 = nsz FMULSrr %1, %0, implicit $fpcr | 
 |     %4:fpr32 = nsz FADDSrr killed %3, %2, implicit $fpcr | 
 |     $s0 = COPY %4 | 
 |     RET_ReallyLR implicit $s0 | 
 |  | 
 | ... | 
 |  | 
 | # Can create FMLA, because both the fmul and fadd have all fast-math flags. | 
 | # | 
 | # CHECK-LABEL: name: vector_fmadd_fast | 
 | # CHECK:       [[C:%.*]]:fpr128 = COPY $q2 | 
 | # CHECK-NEXT:  [[B:%.*]]:fpr128 = COPY $q1 | 
 | # CHECK-NEXT:  [[A:%.*]]:fpr128 = COPY $q0 | 
 | # CHECK-NEXT:  fpr128 = nnan ninf nsz arcp contract afn reassoc FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr | 
 | --- | 
 | name:            vector_fmadd_fast | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr128 } | 
 |   - { id: 1, class: fpr128 } | 
 |   - { id: 2, class: fpr128 } | 
 |   - { id: 3, class: fpr128 } | 
 |   - { id: 4, class: fpr128 } | 
 | liveins: | 
 |   - { reg: '$q0', virtual-reg: '%0' } | 
 |   - { reg: '$q1', virtual-reg: '%1' } | 
 |   - { reg: '$q2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $q0, $q1, $q2 | 
 |  | 
 |     %2:fpr128 = COPY $q2 | 
 |     %1:fpr128 = COPY $q1 | 
 |     %0:fpr128 = COPY $q0 | 
 |     %3:fpr128 = nnan ninf nsz arcp contract afn reassoc FMULv2f64 %1, %0, implicit $fpcr | 
 |     %4:fpr128 = nnan ninf nsz arcp contract afn reassoc FADDv2f64 killed %3, %2, implicit $fpcr | 
 |     $q0 = COPY %4 | 
 |     RET_ReallyLR implicit $q0 | 
 |  | 
 | ... | 
 |  | 
 | # Can create FMLA, because both the fmul and fadd have the contract fast-math flag. | 
 | # | 
 | # CHECK-LABEL: name: vector_fmadd_contract | 
 | # CHECK:       [[C:%.*]]:fpr128 = COPY $q2 | 
 | # CHECK-NEXT:  [[B:%.*]]:fpr128 = COPY $q1 | 
 | # CHECK-NEXT:  [[A:%.*]]:fpr128 = COPY $q0 | 
 | # CHECK-NEXT:  fpr128 = contract FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr | 
 | --- | 
 | name:            vector_fmadd_contract | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr128 } | 
 |   - { id: 1, class: fpr128 } | 
 |   - { id: 2, class: fpr128 } | 
 |   - { id: 3, class: fpr128 } | 
 |   - { id: 4, class: fpr128 } | 
 | liveins: | 
 |   - { reg: '$q0', virtual-reg: '%0' } | 
 |   - { reg: '$q1', virtual-reg: '%1' } | 
 |   - { reg: '$q2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $q0, $q1, $q2 | 
 |  | 
 |     %2:fpr128 = COPY $q2 | 
 |     %1:fpr128 = COPY $q1 | 
 |     %0:fpr128 = COPY $q0 | 
 |     %3:fpr128 = contract FMULv2f64 %1, %0, implicit $fpcr | 
 |     %4:fpr128 = contract FADDv2f64 killed %3, %2, implicit $fpcr | 
 |     $q0 = COPY %4 | 
 |     RET_ReallyLR implicit $q0 | 
 |  | 
 | ... | 
 |  | 
 | # Do not create FMLA, because we don't have the contract flag on the FADD. | 
 | # | 
 | # CHECK-LABEL: name: vector_fmadd_contract_op0 | 
 | # CHECK:       [[C:%.*]]:fpr128 = COPY $q2 | 
 | # CHECK-NEXT:  [[B:%.*]]:fpr128 = COPY $q1 | 
 | # CHECK-NEXT:  [[A:%.*]]:fpr128 = COPY $q0 | 
 | # CHECK-NEXT:  [[MUL:%.*]]:fpr128 = contract FMULv2f64 [[B]], [[A]], implicit $fpcr | 
 | # CHECK-NEXT:  fpr128 = FADDv2f64 killed [[MUL]], [[C]], implicit $fpcr | 
 | --- | 
 | name:            vector_fmadd_contract_op0 | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr128 } | 
 |   - { id: 1, class: fpr128 } | 
 |   - { id: 2, class: fpr128 } | 
 |   - { id: 3, class: fpr128 } | 
 |   - { id: 4, class: fpr128 } | 
 | liveins: | 
 |   - { reg: '$q0', virtual-reg: '%0' } | 
 |   - { reg: '$q1', virtual-reg: '%1' } | 
 |   - { reg: '$q2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $q0, $q1, $q2 | 
 |  | 
 |     %2:fpr128 = COPY $q2 | 
 |     %1:fpr128 = COPY $q1 | 
 |     %0:fpr128 = COPY $q0 | 
 |     %3:fpr128 = contract FMULv2f64 %1, %0, implicit $fpcr | 
 |     %4:fpr128 = FADDv2f64 killed %3, %2, implicit $fpcr | 
 |     $q0 = COPY %4 | 
 |     RET_ReallyLR implicit $q0 | 
 |  | 
 | ... | 
 |  | 
 | # Do create FMLA, because we have the contract flag on the FADD. | 
 | # | 
 | # CHECK-LABEL: name: vector_fmadd_contract_op1 | 
 | # CHECK:       [[C:%.*]]:fpr128 = COPY $q2 | 
 | # CHECK-NEXT:  [[B:%.*]]:fpr128 = COPY $q1 | 
 | # CHECK-NEXT:  [[A:%.*]]:fpr128 = COPY $q0 | 
 | # CHECK-NEXT:  fpr128 = contract FMLAv2f64 [[C]], [[B]], [[A]], implicit $fpcr | 
 |  | 
 | --- | 
 | name:            vector_fmadd_contract_op1 | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr128 } | 
 |   - { id: 1, class: fpr128 } | 
 |   - { id: 2, class: fpr128 } | 
 |   - { id: 3, class: fpr128 } | 
 |   - { id: 4, class: fpr128 } | 
 | liveins: | 
 |   - { reg: '$q0', virtual-reg: '%0' } | 
 |   - { reg: '$q1', virtual-reg: '%1' } | 
 |   - { reg: '$q2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $q0, $q1, $q2 | 
 |  | 
 |     %2:fpr128 = COPY $q2 | 
 |     %1:fpr128 = COPY $q1 | 
 |     %0:fpr128 = COPY $q0 | 
 |     %3:fpr128 = FMULv2f64 %1, %0, implicit $fpcr | 
 |     %4:fpr128 = contract FADDv2f64 killed %3, %2, implicit $fpcr | 
 |     $q0 = COPY %4 | 
 |     RET_ReallyLR implicit $q0 | 
 |  | 
 | ... | 
 |  | 
 | # Do not create FMLA, as nsz flag does not allow it. | 
 | # | 
 | # CHECK-LABEL: name: vector_fmadd_nsz | 
 | # CHECK:       [[C:%.*]]:fpr128 = COPY $q2 | 
 | # CHECK-NEXT:  [[B:%.*]]:fpr128 = COPY $q1 | 
 | # CHECK-NEXT:  [[A:%.*]]:fpr128 = COPY $q0 | 
 | # CHECK-NEXT:  [[MUL:%.*]]:fpr128 = nsz FMULv2f64 [[B]], [[A]], implicit $fpcr | 
 | # CHECK-NEXT:  fpr128 = nsz FADDv2f64 killed [[MUL]], [[C]], implicit $fpcr | 
 | --- | 
 | name:            vector_fmadd_nsz | 
 | alignment:       4 | 
 | tracksRegLiveness: true | 
 | registers: | 
 |   - { id: 0, class: fpr128 } | 
 |   - { id: 1, class: fpr128 } | 
 |   - { id: 2, class: fpr128 } | 
 |   - { id: 3, class: fpr128 } | 
 |   - { id: 4, class: fpr128 } | 
 | liveins: | 
 |   - { reg: '$q0', virtual-reg: '%0' } | 
 |   - { reg: '$q1', virtual-reg: '%1' } | 
 |   - { reg: '$q2', virtual-reg: '%2' } | 
 | frameInfo: | 
 |   maxAlignment:    1 | 
 |   maxCallFrameSize: 0 | 
 | machineFunctionInfo: {} | 
 | body:             | | 
 |   bb.0.entry: | 
 |     liveins: $q0, $q1, $q2 | 
 |  | 
 |     %2:fpr128 = COPY $q2 | 
 |     %1:fpr128 = COPY $q1 | 
 |     %0:fpr128 = COPY $q0 | 
 |     %3:fpr128 = nsz FMULv2f64 %1, %0, implicit $fpcr | 
 |     %4:fpr128 = nsz FADDv2f64 killed %3, %2, implicit $fpcr | 
 |     $q0 = COPY %4 | 
 |     RET_ReallyLR implicit $q0 | 
 |  | 
 | ... |