| ; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s |
| ; RUN: llc < %s -O3 -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s |
| |
| define <2 x float> @fma_1(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: fma_1: |
| ; CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s |
| %tmp1 = fmul contract <2 x float> %A, %B; |
| %tmp2 = fadd contract <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| ; This case will fold as it was only available through unsafe before, now available from |
| ; the contract on the fadd |
| define <2 x float> @fma_2(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: fma_2: |
| ; CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s |
| %tmp1 = fmul <2 x float> %A, %B; |
| %tmp2 = fadd contract <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| define <2 x float> @no_fma_1(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: no_fma_1: |
| ; CHECK: fmul |
| ; CHECK: fadd |
| %tmp1 = fmul contract <2 x float> %A, %B; |
| %tmp2 = fadd <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| define <2 x float> @fma_sub_1(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: fma_sub_1: |
| ; CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s |
| %tmp1 = fmul contract <2 x float> %A, %B; |
| %tmp2 = fsub contract <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| ; This case will fold as it was only available through unsafe before, now available from |
| ; the contract on the fsub |
| define <2 x float> @fma_sub_2(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: fma_sub_2: |
| ; CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s |
| %tmp1 = fmul <2 x float> %A, %B; |
| %tmp2 = fsub contract <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| define <2 x float> @no_fma_sub_1(<2 x float> %A, <2 x float> %B, <2 x float> %C) { |
| ; CHECK-LABEL: no_fma_sub_1: |
| ; CHECK: fmul |
| ; CHECK: fsub |
| %tmp1 = fmul contract <2 x float> %A, %B; |
| %tmp2 = fsub <2 x float> %C, %tmp1; |
| ret <2 x float> %tmp2 |
| } |
| |
| ; Regression test: contract FMF allows folding (A * 0 + B) to FMA(A, 0, B), but |
| ; reassoc FMF must not allow further folding to just (B) without additional |
| ; FMFs (ninf, nnan) |
| define float @fma_zero(float %A, float %B) { |
| ; CHECK-LABEL: fma_zero: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: movi d2, #0000000000000000 |
| ; CHECK-NEXT: fmadd s0, s0, s2, s1 |
| ; CHECK-NEXT: ret |
| %tmp1 = fmul contract reassoc float %A, 0.0e+0; |
| %tmp2 = fadd contract reassoc float %B, %tmp1; |
| ret float %tmp2 |
| } |