| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver2 | FileCheck %s --check-prefixes=FMA4 |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=FMA3 |
| ; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=FMA3 |
| |
| ; PR173172 |
| |
| define void @fnma(ptr %_0, ptr %a, ptr %b, ptr %c) { |
| ; FMA4-LABEL: fnma: |
| ; FMA4: # %bb.0: |
| ; FMA4-NEXT: vbroadcastf128 {{.*#+}} ymm0 = mem[0,1,0,1] |
| ; FMA4-NEXT: vmovups (%rdx), %xmm1 |
| ; FMA4-NEXT: vmovups (%rcx), %xmm2 |
| ; FMA4-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm3 |
| ; FMA4-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 |
| ; FMA4-NEXT: vfnmaddps {{.*#+}} ymm0 = -(ymm0 * ymm3) + ymm1 |
| ; FMA4-NEXT: vmovups %ymm0, (%rdi) |
| ; FMA4-NEXT: vzeroupper |
| ; FMA4-NEXT: retq |
| ; |
| ; FMA3-LABEL: fnma: |
| ; FMA3: # %bb.0: |
| ; FMA3-NEXT: vbroadcastf128 {{.*#+}} ymm0 = mem[0,1,0,1] |
| ; FMA3-NEXT: vmovups (%rdx), %xmm1 |
| ; FMA3-NEXT: vmovups (%rcx), %xmm2 |
| ; FMA3-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm3 |
| ; FMA3-NEXT: vinsertf128 $1, %xmm1, %ymm2, %ymm1 |
| ; FMA3-NEXT: vfnmadd231ps {{.*#+}} ymm1 = -(ymm0 * ymm3) + ymm1 |
| ; FMA3-NEXT: vmovups %ymm1, (%rdi) |
| ; FMA3-NEXT: vzeroupper |
| ; FMA3-NEXT: retq |
| %i = load <4 x float>, ptr %a, align 4 |
| %i1 = fneg <4 x float> %i |
| %i2 = shufflevector <4 x float> %i1, <4 x float> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3> |
| %i3 = load <4 x float>, ptr %b, align 4 |
| %i4 = load <4 x float>, ptr %c, align 4 |
| %i5 = shufflevector <4 x float> %i3, <4 x float> %i4, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> |
| %i6 = shufflevector <4 x float> %i4, <4 x float> %i3, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> |
| %i7 = tail call <8 x float> @llvm.fma.v8f32(<8 x float> %i2, <8 x float> %i5, <8 x float> %i6) |
| store <8 x float> %i7, ptr %_0, align 4 |
| ret void |
| } |
| |
| define void @fnma2(ptr %_0, ptr %a, ptr %b, ptr %c) { |
| ; FMA4-LABEL: fnma2: |
| ; FMA4: # %bb.0: |
| ; FMA4-NEXT: vmovups (%rsi), %xmm0 |
| ; FMA4-NEXT: vmovups (%rdx), %xmm1 |
| ; FMA4-NEXT: vmovups (%rcx), %xmm2 |
| ; FMA4-NEXT: vfnmaddps {{.*#+}} xmm3 = -(xmm0 * xmm2) + xmm1 |
| ; FMA4-NEXT: vfnmaddps {{.*#+}} xmm0 = -(xmm0 * xmm1) + xmm2 |
| ; FMA4-NEXT: vmovups %xmm0, (%rdi) |
| ; FMA4-NEXT: vmovups %xmm3, 16(%rdi) |
| ; FMA4-NEXT: retq |
| ; |
| ; FMA3-LABEL: fnma2: |
| ; FMA3: # %bb.0: |
| ; FMA3-NEXT: vmovups (%rsi), %xmm0 |
| ; FMA3-NEXT: vmovups (%rdx), %xmm1 |
| ; FMA3-NEXT: vmovups (%rcx), %xmm2 |
| ; FMA3-NEXT: vmovaps %xmm2, %xmm3 |
| ; FMA3-NEXT: vfnmadd213ps {{.*#+}} xmm3 = -(xmm0 * xmm3) + xmm1 |
| ; FMA3-NEXT: vfnmadd213ps {{.*#+}} xmm1 = -(xmm0 * xmm1) + xmm2 |
| ; FMA3-NEXT: vmovups %xmm1, (%rdi) |
| ; FMA3-NEXT: vmovups %xmm3, 16(%rdi) |
| ; FMA3-NEXT: retq |
| %va = load <4 x float>, ptr %a, align 4 |
| %vb = load <4 x float>, ptr %b, align 4 |
| %vc = load <4 x float>, ptr %c, align 4 |
| %i = fneg <4 x float> %va |
| %i1 = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %i, <4 x float> %vc, <4 x float> %vb) |
| %i2 = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %i, <4 x float> %vb, <4 x float> %vc) |
| store <4 x float> %i2, ptr %_0, align 4 |
| %i3 = getelementptr inbounds nuw i8, ptr %_0, i64 16 |
| store <4 x float> %i1, ptr %i3, align 4 |
| ret void |
| } |
| |
| define void @fnma3(ptr %_0, ptr %a, ptr %b, ptr %c) { |
| ; FMA4-LABEL: fnma3: |
| ; FMA4: # %bb.0: |
| ; FMA4-NEXT: vmovups (%rdx), %xmm0 |
| ; FMA4-NEXT: vmovups (%rcx), %xmm1 |
| ; FMA4-NEXT: vbroadcastf128 {{.*#+}} ymm2 = mem[0,1,0,1] |
| ; FMA4-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm3 |
| ; FMA4-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 |
| ; FMA4-NEXT: vfnmaddps {{.*#+}} ymm0 = -(ymm2 * ymm3) + ymm0 |
| ; FMA4-NEXT: vmovups %ymm0, (%rdi) |
| ; FMA4-NEXT: vzeroupper |
| ; FMA4-NEXT: retq |
| ; |
| ; FMA3-LABEL: fnma3: |
| ; FMA3: # %bb.0: |
| ; FMA3-NEXT: vmovups (%rdx), %xmm0 |
| ; FMA3-NEXT: vmovups (%rcx), %xmm1 |
| ; FMA3-NEXT: vbroadcastf128 {{.*#+}} ymm2 = mem[0,1,0,1] |
| ; FMA3-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm3 |
| ; FMA3-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 |
| ; FMA3-NEXT: vfnmadd231ps {{.*#+}} ymm0 = -(ymm2 * ymm3) + ymm0 |
| ; FMA3-NEXT: vmovups %ymm0, (%rdi) |
| ; FMA3-NEXT: vzeroupper |
| ; FMA3-NEXT: retq |
| %va = load <4 x float>, ptr %a, align 4 |
| %vb = load <4 x float>, ptr %b, align 4 |
| %vc = load <4 x float>, ptr %c, align 4 |
| %i = fneg <4 x float> %va |
| %i1 = shufflevector <4 x float> %i, <4 x float> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3> |
| %i2 = shufflevector <4 x float> %vb, <4 x float> %vc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> |
| %i3 = shufflevector <4 x float> %vc, <4 x float> %vb, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> |
| %i4 = tail call <8 x float> @llvm.fma.v8f32(<8 x float> %i1, <8 x float> %i2, <8 x float> %i3) |
| store <8 x float> %i4, ptr %_0, align 4 |
| ret void |
| } |