1; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=core-avx2 -mattr=avx2,+fma -fp-contract=fast | FileCheck %s 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=bdver2 -mattr=-fma4 -fp-contract=fast | FileCheck %s 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=bdver1 -fp-contract=fast | FileCheck %s --check-prefix=CHECK_FMA4 4 5; CHECK: test_x86_fmadd_ps 6; CHECK: vfmadd213ps %xmm2, %xmm1, %xmm0 7; CHECK: ret 8; CHECK_FMA4: test_x86_fmadd_ps 9; CHECK_FMA4: vfmaddps %xmm2, %xmm1, %xmm0, %xmm0 10; CHECK_FMA4: ret 11define <4 x float> @test_x86_fmadd_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 12 %x = fmul <4 x float> %a0, %a1 13 %res = fadd <4 x float> %x, %a2 14 ret <4 x float> %res 15} 16 17; CHECK: test_x86_fmsub_ps 18; CHECK: fmsub213ps %xmm2, %xmm1, %xmm0 19; CHECK: ret 20; CHECK_FMA4: test_x86_fmsub_ps 21; CHECK_FMA4: vfmsubps %xmm2, %xmm1, %xmm0, %xmm0 22; CHECK_FMA4: ret 23define <4 x float> @test_x86_fmsub_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 24 %x = fmul <4 x float> %a0, %a1 25 %res = fsub <4 x float> %x, %a2 26 ret <4 x float> %res 27} 28 29; CHECK: test_x86_fnmadd_ps 30; CHECK: fnmadd213ps %xmm2, %xmm1, %xmm0 31; CHECK: ret 32; CHECK_FMA4: test_x86_fnmadd_ps 33; CHECK_FMA4: vfnmaddps %xmm2, %xmm1, %xmm0, %xmm0 34; CHECK_FMA4: ret 35define <4 x float> @test_x86_fnmadd_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 36 %x = fmul <4 x float> %a0, %a1 37 %res = fsub <4 x float> %a2, %x 38 ret <4 x float> %res 39} 40 41; CHECK: test_x86_fnmsub_ps 42; CHECK: fnmsub213ps %xmm2, %xmm1, %xmm0 43; CHECK: ret 44; CHECK_FMA4: test_x86_fnmsub_ps 45; CHECK_FMA4: fnmsubps %xmm2, %xmm1, %xmm0, %xmm0 46; CHECK_FMA4: ret 47define <4 x float> @test_x86_fnmsub_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 48 %x = fmul <4 x float> %a0, %a1 49 %y = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %x 50 %res = fsub <4 x float> %y, %a2 51 ret <4 x float> %res 52} 53 54; CHECK: test_x86_fmadd_ps_y 55; CHECK: vfmadd213ps %ymm2, %ymm1, %ymm0 56; CHECK: ret 57; CHECK_FMA4: test_x86_fmadd_ps_y 58; CHECK_FMA4: vfmaddps %ymm2, %ymm1, %ymm0, %ymm0 59; CHECK_FMA4: ret 60define <8 x float> @test_x86_fmadd_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 61 %x = fmul <8 x float> %a0, %a1 62 %res = fadd <8 x float> %x, %a2 63 ret <8 x float> %res 64} 65 66; CHECK: test_x86_fmsub_ps_y 67; CHECK: vfmsub213ps %ymm2, %ymm1, %ymm0 68; CHECK: ret 69; CHECK_FMA4: test_x86_fmsub_ps_y 70; CHECK_FMA4: vfmsubps %ymm2, %ymm1, %ymm0, %ymm0 71; CHECK_FMA4: ret 72define <8 x float> @test_x86_fmsub_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 73 %x = fmul <8 x float> %a0, %a1 74 %res = fsub <8 x float> %x, %a2 75 ret <8 x float> %res 76} 77 78; CHECK: test_x86_fnmadd_ps_y 79; CHECK: vfnmadd213ps %ymm2, %ymm1, %ymm0 80; CHECK: ret 81; CHECK_FMA4: test_x86_fnmadd_ps_y 82; CHECK_FMA4: vfnmaddps %ymm2, %ymm1, %ymm0, %ymm0 83; CHECK_FMA4: ret 84define <8 x float> @test_x86_fnmadd_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 85 %x = fmul <8 x float> %a0, %a1 86 %res = fsub <8 x float> %a2, %x 87 ret <8 x float> %res 88} 89 90; CHECK: test_x86_fnmsub_ps_y 91; CHECK: vfnmsub213ps %ymm2, %ymm1, %ymm0 92; CHECK: ret 93define <8 x float> @test_x86_fnmsub_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 94 %x = fmul <8 x float> %a0, %a1 95 %y = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %x 96 %res = fsub <8 x float> %y, %a2 97 ret <8 x float> %res 98} 99 100; CHECK: test_x86_fmadd_pd_y 101; CHECK: vfmadd213pd %ymm2, %ymm1, %ymm0 102; CHECK: ret 103; CHECK_FMA4: test_x86_fmadd_pd_y 104; CHECK_FMA4: vfmaddpd %ymm2, %ymm1, %ymm0, %ymm0 105; CHECK_FMA4: ret 106define <4 x double> @test_x86_fmadd_pd_y(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2) { 107 %x = fmul <4 x double> %a0, %a1 108 %res = fadd <4 x double> %x, %a2 109 ret <4 x double> %res 110} 111 112; CHECK: test_x86_fmsub_pd_y 113; CHECK: vfmsub213pd %ymm2, %ymm1, %ymm0 114; CHECK: ret 115; CHECK_FMA4: test_x86_fmsub_pd_y 116; CHECK_FMA4: vfmsubpd %ymm2, %ymm1, %ymm0, %ymm0 117; CHECK_FMA4: ret 118define <4 x double> @test_x86_fmsub_pd_y(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2) { 119 %x = fmul <4 x double> %a0, %a1 120 %res = fsub <4 x double> %x, %a2 121 ret <4 x double> %res 122} 123 124; CHECK: test_x86_fmsub_pd 125; CHECK: vfmsub213pd %xmm2, %xmm1, %xmm0 126; CHECK: ret 127; CHECK_FMA4: test_x86_fmsub_pd 128; CHECK_FMA4: vfmsubpd %xmm2, %xmm1, %xmm0, %xmm0 129; CHECK_FMA4: ret 130define <2 x double> @test_x86_fmsub_pd(<2 x double> %a0, <2 x double> %a1, <2 x double> %a2) { 131 %x = fmul <2 x double> %a0, %a1 132 %res = fsub <2 x double> %x, %a2 133 ret <2 x double> %res 134} 135 136; CHECK: test_x86_fnmadd_ss 137; CHECK: vfnmadd213ss %xmm2, %xmm1, %xmm0 138; CHECK: ret 139; CHECK_FMA4: test_x86_fnmadd_ss 140; CHECK_FMA4: vfnmaddss %xmm2, %xmm1, %xmm0, %xmm0 141; CHECK_FMA4: ret 142define float @test_x86_fnmadd_ss(float %a0, float %a1, float %a2) { 143 %x = fmul float %a0, %a1 144 %res = fsub float %a2, %x 145 ret float %res 146} 147 148; CHECK: test_x86_fnmadd_sd 149; CHECK: vfnmadd213sd %xmm2, %xmm1, %xmm0 150; CHECK: ret 151; CHECK_FMA4: test_x86_fnmadd_sd 152; CHECK_FMA4: vfnmaddsd %xmm2, %xmm1, %xmm0, %xmm0 153; CHECK_FMA4: ret 154define double @test_x86_fnmadd_sd(double %a0, double %a1, double %a2) { 155 %x = fmul double %a0, %a1 156 %res = fsub double %a2, %x 157 ret double %res 158} 159 160; CHECK: test_x86_fmsub_sd 161; CHECK: vfmsub213sd %xmm2, %xmm1, %xmm0 162; CHECK: ret 163; CHECK_FMA4: test_x86_fmsub_sd 164; CHECK_FMA4: vfmsubsd %xmm2, %xmm1, %xmm0, %xmm0 165; CHECK_FMA4: ret 166define double @test_x86_fmsub_sd(double %a0, double %a1, double %a2) { 167 %x = fmul double %a0, %a1 168 %res = fsub double %x, %a2 169 ret double %res 170} 171 172; CHECK: test_x86_fnmsub_ss 173; CHECK: vfnmsub213ss %xmm2, %xmm1, %xmm0 174; CHECK: ret 175; CHECK_FMA4: test_x86_fnmsub_ss 176; CHECK_FMA4: vfnmsubss %xmm2, %xmm1, %xmm0, %xmm0 177; CHECK_FMA4: ret 178define float @test_x86_fnmsub_ss(float %a0, float %a1, float %a2) { 179 %x = fsub float -0.000000e+00, %a0 180 %y = fmul float %x, %a1 181 %res = fsub float %y, %a2 182 ret float %res 183} 184 185; CHECK: test_x86_fmadd_ps_load 186; CHECK: vmovaps (%rdi), %xmm2 187; CHECK: vfmadd213ps %xmm1, %xmm0, %xmm2 188; CHECK: ret 189; CHECK_FMA4: test_x86_fmadd_ps_load 190; CHECK_FMA4: vfmaddps %xmm1, (%rdi), %xmm0, %xmm0 191; CHECK_FMA4: ret 192define <4 x float> @test_x86_fmadd_ps_load(<4 x float>* %a0, <4 x float> %a1, <4 x float> %a2) { 193 %x = load <4 x float>* %a0 194 %y = fmul <4 x float> %x, %a1 195 %res = fadd <4 x float> %y, %a2 196 ret <4 x float> %res 197} 198 199; CHECK: test_x86_fmsub_ps_load 200; CHECK: vmovaps (%rdi), %xmm2 201; CHECK: fmsub213ps %xmm1, %xmm0, %xmm2 202; CHECK: ret 203; CHECK_FMA4: test_x86_fmsub_ps_load 204; CHECK_FMA4: vfmsubps %xmm1, (%rdi), %xmm0, %xmm0 205; CHECK_FMA4: ret 206define <4 x float> @test_x86_fmsub_ps_load(<4 x float>* %a0, <4 x float> %a1, <4 x float> %a2) { 207 %x = load <4 x float>* %a0 208 %y = fmul <4 x float> %x, %a1 209 %res = fsub <4 x float> %y, %a2 210 ret <4 x float> %res 211} 212 213