1; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+fma -fp-contract=fast | FileCheck %s --check-prefix=ALL --check-prefix=CHECK_FMA 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+fma4,+fma -fp-contract=fast | FileCheck %s --check-prefix=ALL --check-prefix=CHECK_FMA 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx,+fma4 -fp-contract=fast | FileCheck %s --check-prefix=ALL --check-prefix=CHECK_FMA4 4 5; 6; Patterns (+ fneg variants): add(mul(x,y),z), sub(mul(x,y),z) 7; 8 9define <4 x float> @test_x86_fmadd_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 10; CHECK_FMA-LABEL: test_x86_fmadd_ps: 11; CHECK_FMA: # BB#0: 12; CHECK_FMA-NEXT: vfmadd213ps %xmm2, %xmm1, %xmm0 13; CHECK_FMA-NEXT: retq 14; 15; CHECK_FMA4-LABEL: test_x86_fmadd_ps: 16; CHECK_FMA4: # BB#0: 17; CHECK_FMA4-NEXT: vfmaddps %xmm2, %xmm1, %xmm0, %xmm0 18; CHECK_FMA4-NEXT: retq 19 %x = fmul <4 x float> %a0, %a1 20 %res = fadd <4 x float> %x, %a2 21 ret <4 x float> %res 22} 23 24define <4 x float> @test_x86_fmsub_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 25; CHECK_FMA-LABEL: test_x86_fmsub_ps: 26; CHECK_FMA: # BB#0: 27; CHECK_FMA-NEXT: vfmsub213ps %xmm2, %xmm1, %xmm0 28; CHECK_FMA-NEXT: retq 29; 30; CHECK_FMA4-LABEL: test_x86_fmsub_ps: 31; CHECK_FMA4: # BB#0: 32; CHECK_FMA4-NEXT: vfmsubps %xmm2, %xmm1, %xmm0, %xmm0 33; CHECK_FMA4-NEXT: retq 34 %x = fmul <4 x float> %a0, %a1 35 %res = fsub <4 x float> %x, %a2 36 ret <4 x float> %res 37} 38 39define <4 x float> @test_x86_fnmadd_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 40; CHECK_FMA-LABEL: test_x86_fnmadd_ps: 41; CHECK_FMA: # BB#0: 42; CHECK_FMA-NEXT: vfnmadd213ps %xmm2, %xmm1, %xmm0 43; CHECK_FMA-NEXT: retq 44; 45; CHECK_FMA4-LABEL: test_x86_fnmadd_ps: 46; CHECK_FMA4: # BB#0: 47; CHECK_FMA4-NEXT: vfnmaddps %xmm2, %xmm1, %xmm0, %xmm0 48; CHECK_FMA4-NEXT: retq 49 %x = fmul <4 x float> %a0, %a1 50 %res = fsub <4 x float> %a2, %x 51 ret <4 x float> %res 52} 53 54define <4 x float> @test_x86_fnmsub_ps(<4 x float> %a0, <4 x float> %a1, <4 x float> %a2) { 55; CHECK_FMA-LABEL: test_x86_fnmsub_ps: 56; CHECK_FMA: # BB#0: 57; CHECK_FMA-NEXT: vfnmsub213ps %xmm2, %xmm1, %xmm0 58; CHECK_FMA-NEXT: retq 59; 60; CHECK_FMA4-LABEL: test_x86_fnmsub_ps: 61; CHECK_FMA4: # BB#0: 62; CHECK_FMA4-NEXT: vfnmsubps %xmm2, %xmm1, %xmm0, %xmm0 63; CHECK_FMA4-NEXT: retq 64 %x = fmul <4 x float> %a0, %a1 65 %y = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %x 66 %res = fsub <4 x float> %y, %a2 67 ret <4 x float> %res 68} 69 70define <8 x float> @test_x86_fmadd_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 71; CHECK_FMA-LABEL: test_x86_fmadd_ps_y: 72; CHECK_FMA: # BB#0: 73; CHECK_FMA-NEXT: vfmadd213ps %ymm2, %ymm1, %ymm0 74; CHECK_FMA-NEXT: retq 75; 76; CHECK_FMA4-LABEL: test_x86_fmadd_ps_y: 77; CHECK_FMA4: # BB#0: 78; CHECK_FMA4-NEXT: vfmaddps %ymm2, %ymm1, %ymm0, %ymm0 79; CHECK_FMA4-NEXT: retq 80 %x = fmul <8 x float> %a0, %a1 81 %res = fadd <8 x float> %x, %a2 82 ret <8 x float> %res 83} 84 85define <8 x float> @test_x86_fmsub_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 86; CHECK_FMA-LABEL: test_x86_fmsub_ps_y: 87; CHECK_FMA: # BB#0: 88; CHECK_FMA-NEXT: vfmsub213ps %ymm2, %ymm1, %ymm0 89; CHECK_FMA-NEXT: retq 90; 91; CHECK_FMA4-LABEL: test_x86_fmsub_ps_y: 92; CHECK_FMA4: # BB#0: 93; CHECK_FMA4-NEXT: vfmsubps %ymm2, %ymm1, %ymm0, %ymm0 94; CHECK_FMA4-NEXT: retq 95 %x = fmul <8 x float> %a0, %a1 96 %res = fsub <8 x float> %x, %a2 97 ret <8 x float> %res 98} 99 100define <8 x float> @test_x86_fnmadd_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 101; CHECK_FMA-LABEL: test_x86_fnmadd_ps_y: 102; CHECK_FMA: # BB#0: 103; CHECK_FMA-NEXT: vfnmadd213ps %ymm2, %ymm1, %ymm0 104; CHECK_FMA-NEXT: retq 105; 106; CHECK_FMA4-LABEL: test_x86_fnmadd_ps_y: 107; CHECK_FMA4: # BB#0: 108; CHECK_FMA4-NEXT: vfnmaddps %ymm2, %ymm1, %ymm0, %ymm0 109; CHECK_FMA4-NEXT: retq 110 %x = fmul <8 x float> %a0, %a1 111 %res = fsub <8 x float> %a2, %x 112 ret <8 x float> %res 113} 114 115define <8 x float> @test_x86_fnmsub_ps_y(<8 x float> %a0, <8 x float> %a1, <8 x float> %a2) { 116; CHECK_FMA-LABEL: test_x86_fnmsub_ps_y: 117; CHECK_FMA: # BB#0: 118; CHECK_FMA-NEXT: vfnmsub213ps %ymm2, %ymm1, %ymm0 119; CHECK_FMA-NEXT: retq 120; 121; CHECK_FMA4-LABEL: test_x86_fnmsub_ps_y: 122; CHECK_FMA4: # BB#0: 123; CHECK_FMA4-NEXT: vfnmsubps %ymm2, %ymm1, %ymm0, %ymm0 124; CHECK_FMA4-NEXT: retq 125 %x = fmul <8 x float> %a0, %a1 126 %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 127 %res = fsub <8 x float> %y, %a2 128 ret <8 x float> %res 129} 130 131define <4 x double> @test_x86_fmadd_pd_y(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2) { 132; CHECK_FMA-LABEL: test_x86_fmadd_pd_y: 133; CHECK_FMA: # BB#0: 134; CHECK_FMA-NEXT: vfmadd213pd %ymm2, %ymm1, %ymm0 135; CHECK_FMA-NEXT: retq 136; 137; CHECK_FMA4-LABEL: test_x86_fmadd_pd_y: 138; CHECK_FMA4: # BB#0: 139; CHECK_FMA4-NEXT: vfmaddpd %ymm2, %ymm1, %ymm0, %ymm0 140; CHECK_FMA4-NEXT: retq 141 %x = fmul <4 x double> %a0, %a1 142 %res = fadd <4 x double> %x, %a2 143 ret <4 x double> %res 144} 145 146define <4 x double> @test_x86_fmsub_pd_y(<4 x double> %a0, <4 x double> %a1, <4 x double> %a2) { 147; CHECK_FMA-LABEL: test_x86_fmsub_pd_y: 148; CHECK_FMA: # BB#0: 149; CHECK_FMA-NEXT: vfmsub213pd %ymm2, %ymm1, %ymm0 150; CHECK_FMA-NEXT: retq 151; 152; CHECK_FMA4-LABEL: test_x86_fmsub_pd_y: 153; CHECK_FMA4: # BB#0: 154; CHECK_FMA4-NEXT: vfmsubpd %ymm2, %ymm1, %ymm0, %ymm0 155; CHECK_FMA4-NEXT: retq 156 %x = fmul <4 x double> %a0, %a1 157 %res = fsub <4 x double> %x, %a2 158 ret <4 x double> %res 159} 160 161define <2 x double> @test_x86_fmsub_pd(<2 x double> %a0, <2 x double> %a1, <2 x double> %a2) { 162; CHECK_FMA-LABEL: test_x86_fmsub_pd: 163; CHECK_FMA: # BB#0: 164; CHECK_FMA-NEXT: vfmsub213pd %xmm2, %xmm1, %xmm0 165; CHECK_FMA-NEXT: retq 166; 167; CHECK_FMA4-LABEL: test_x86_fmsub_pd: 168; CHECK_FMA4: # BB#0: 169; CHECK_FMA4-NEXT: vfmsubpd %xmm2, %xmm1, %xmm0, %xmm0 170; CHECK_FMA4-NEXT: retq 171 %x = fmul <2 x double> %a0, %a1 172 %res = fsub <2 x double> %x, %a2 173 ret <2 x double> %res 174} 175 176define float @test_x86_fnmadd_ss(float %a0, float %a1, float %a2) { 177; CHECK_FMA-LABEL: test_x86_fnmadd_ss: 178; CHECK_FMA: # BB#0: 179; CHECK_FMA-NEXT: vfnmadd213ss %xmm2, %xmm1, %xmm0 180; CHECK_FMA-NEXT: retq 181; 182; CHECK_FMA4-LABEL: test_x86_fnmadd_ss: 183; CHECK_FMA4: # BB#0: 184; CHECK_FMA4-NEXT: vfnmaddss %xmm2, %xmm1, %xmm0, %xmm0 185; CHECK_FMA4-NEXT: retq 186 %x = fmul float %a0, %a1 187 %res = fsub float %a2, %x 188 ret float %res 189} 190 191define double @test_x86_fnmadd_sd(double %a0, double %a1, double %a2) { 192; CHECK_FMA-LABEL: test_x86_fnmadd_sd: 193; CHECK_FMA: # BB#0: 194; CHECK_FMA-NEXT: vfnmadd213sd %xmm2, %xmm1, %xmm0 195; CHECK_FMA-NEXT: retq 196; 197; CHECK_FMA4-LABEL: test_x86_fnmadd_sd: 198; CHECK_FMA4: # BB#0: 199; CHECK_FMA4-NEXT: vfnmaddsd %xmm2, %xmm1, %xmm0, %xmm0 200; CHECK_FMA4-NEXT: retq 201 %x = fmul double %a0, %a1 202 %res = fsub double %a2, %x 203 ret double %res 204} 205 206define double @test_x86_fmsub_sd(double %a0, double %a1, double %a2) { 207; CHECK_FMA-LABEL: test_x86_fmsub_sd: 208; CHECK_FMA: # BB#0: 209; CHECK_FMA-NEXT: vfmsub213sd %xmm2, %xmm1, %xmm0 210; CHECK_FMA-NEXT: retq 211; 212; CHECK_FMA4-LABEL: test_x86_fmsub_sd: 213; CHECK_FMA4: # BB#0: 214; CHECK_FMA4-NEXT: vfmsubsd %xmm2, %xmm1, %xmm0, %xmm0 215; CHECK_FMA4-NEXT: retq 216 %x = fmul double %a0, %a1 217 %res = fsub double %x, %a2 218 ret double %res 219} 220 221define float @test_x86_fnmsub_ss(float %a0, float %a1, float %a2) { 222; CHECK_FMA-LABEL: test_x86_fnmsub_ss: 223; CHECK_FMA: # BB#0: 224; CHECK_FMA-NEXT: vfnmsub213ss %xmm2, %xmm1, %xmm0 225; CHECK_FMA-NEXT: retq 226; 227; CHECK_FMA4-LABEL: test_x86_fnmsub_ss: 228; CHECK_FMA4: # BB#0: 229; CHECK_FMA4-NEXT: vfnmsubss %xmm2, %xmm1, %xmm0, %xmm0 230; CHECK_FMA4-NEXT: retq 231 %x = fsub float -0.000000e+00, %a0 232 %y = fmul float %x, %a1 233 %res = fsub float %y, %a2 234 ret float %res 235} 236 237define <4 x float> @test_x86_fmadd_ps_load(<4 x float>* %a0, <4 x float> %a1, <4 x float> %a2) { 238; CHECK_FMA-LABEL: test_x86_fmadd_ps_load: 239; CHECK_FMA: # BB#0: 240; CHECK_FMA-NEXT: vfmadd132ps (%rdi), %xmm1, %xmm0 241; CHECK_FMA-NEXT: retq 242; 243; CHECK_FMA4-LABEL: test_x86_fmadd_ps_load: 244; CHECK_FMA4: # BB#0: 245; CHECK_FMA4-NEXT: vfmaddps %xmm1, (%rdi), %xmm0, %xmm0 246; CHECK_FMA4-NEXT: retq 247 %x = load <4 x float>, <4 x float>* %a0 248 %y = fmul <4 x float> %x, %a1 249 %res = fadd <4 x float> %y, %a2 250 ret <4 x float> %res 251} 252 253define <4 x float> @test_x86_fmsub_ps_load(<4 x float>* %a0, <4 x float> %a1, <4 x float> %a2) { 254; CHECK_FMA-LABEL: test_x86_fmsub_ps_load: 255; CHECK_FMA: # BB#0: 256; CHECK_FMA-NEXT: vfmsub132ps (%rdi), %xmm1, %xmm0 257; CHECK_FMA-NEXT: retq 258; 259; CHECK_FMA4-LABEL: test_x86_fmsub_ps_load: 260; CHECK_FMA4: # BB#0: 261; CHECK_FMA4-NEXT: vfmsubps %xmm1, (%rdi), %xmm0, %xmm0 262; CHECK_FMA4-NEXT: retq 263 %x = load <4 x float>, <4 x float>* %a0 264 %y = fmul <4 x float> %x, %a1 265 %res = fsub <4 x float> %y, %a2 266 ret <4 x float> %res 267} 268 269; 270; Patterns (+ fneg variants): mul(add(1.0,x),y), mul(sub(1.0,x),y), mul(sub(x,1.0),y) 271; 272 273define <4 x float> @test_v4f32_mul_add_x_one_y(<4 x float> %x, <4 x float> %y) { 274; CHECK_FMA-LABEL: test_v4f32_mul_add_x_one_y: 275; CHECK_FMA: # BB#0: 276; CHECK_FMA-NEXT: vfmadd213ps %xmm1, %xmm1, %xmm0 277; CHECK_FMA-NEXT: retq 278; 279; CHECK_FMA4-LABEL: test_v4f32_mul_add_x_one_y: 280; CHECK_FMA4: # BB#0: 281; CHECK_FMA4-NEXT: vfmaddps %xmm1, %xmm1, %xmm0, %xmm0 282; CHECK_FMA4-NEXT: retq 283 %a = fadd <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0> 284 %m = fmul <4 x float> %a, %y 285 ret <4 x float> %m 286} 287 288define <4 x float> @test_v4f32_mul_y_add_x_one(<4 x float> %x, <4 x float> %y) { 289; CHECK_FMA-LABEL: test_v4f32_mul_y_add_x_one: 290; CHECK_FMA: # BB#0: 291; CHECK_FMA-NEXT: vfmadd213ps %xmm1, %xmm1, %xmm0 292; CHECK_FMA-NEXT: retq 293; 294; CHECK_FMA4-LABEL: test_v4f32_mul_y_add_x_one: 295; CHECK_FMA4: # BB#0: 296; CHECK_FMA4-NEXT: vfmaddps %xmm1, %xmm1, %xmm0, %xmm0 297; CHECK_FMA4-NEXT: retq 298 %a = fadd <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0> 299 %m = fmul <4 x float> %y, %a 300 ret <4 x float> %m 301} 302 303define <4 x float> @test_v4f32_mul_add_x_negone_y(<4 x float> %x, <4 x float> %y) { 304; CHECK_FMA-LABEL: test_v4f32_mul_add_x_negone_y: 305; CHECK_FMA: # BB#0: 306; CHECK_FMA-NEXT: vfmsub213ps %xmm1, %xmm1, %xmm0 307; CHECK_FMA-NEXT: retq 308; 309; CHECK_FMA4-LABEL: test_v4f32_mul_add_x_negone_y: 310; CHECK_FMA4: # BB#0: 311; CHECK_FMA4-NEXT: vfmsubps %xmm1, %xmm1, %xmm0, %xmm0 312; CHECK_FMA4-NEXT: retq 313 %a = fadd <4 x float> %x, <float -1.0, float -1.0, float -1.0, float -1.0> 314 %m = fmul <4 x float> %a, %y 315 ret <4 x float> %m 316} 317 318define <4 x float> @test_v4f32_mul_y_add_x_negone(<4 x float> %x, <4 x float> %y) { 319; CHECK_FMA-LABEL: test_v4f32_mul_y_add_x_negone: 320; CHECK_FMA: # BB#0: 321; CHECK_FMA-NEXT: vfmsub213ps %xmm1, %xmm1, %xmm0 322; CHECK_FMA-NEXT: retq 323; 324; CHECK_FMA4-LABEL: test_v4f32_mul_y_add_x_negone: 325; CHECK_FMA4: # BB#0: 326; CHECK_FMA4-NEXT: vfmsubps %xmm1, %xmm1, %xmm0, %xmm0 327; CHECK_FMA4-NEXT: retq 328 %a = fadd <4 x float> %x, <float -1.0, float -1.0, float -1.0, float -1.0> 329 %m = fmul <4 x float> %y, %a 330 ret <4 x float> %m 331} 332 333define <4 x float> @test_v4f32_mul_sub_one_x_y(<4 x float> %x, <4 x float> %y) { 334; CHECK_FMA-LABEL: test_v4f32_mul_sub_one_x_y: 335; CHECK_FMA: # BB#0: 336; CHECK_FMA-NEXT: vfnmadd213ps %xmm1, %xmm1, %xmm0 337; CHECK_FMA-NEXT: retq 338; 339; CHECK_FMA4-LABEL: test_v4f32_mul_sub_one_x_y: 340; CHECK_FMA4: # BB#0: 341; CHECK_FMA4-NEXT: vfnmaddps %xmm1, %xmm1, %xmm0, %xmm0 342; CHECK_FMA4-NEXT: retq 343 %s = fsub <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %x 344 %m = fmul <4 x float> %s, %y 345 ret <4 x float> %m 346} 347 348define <4 x float> @test_v4f32_mul_y_sub_one_x(<4 x float> %x, <4 x float> %y) { 349; CHECK_FMA-LABEL: test_v4f32_mul_y_sub_one_x: 350; CHECK_FMA: # BB#0: 351; CHECK_FMA-NEXT: vfnmadd213ps %xmm1, %xmm1, %xmm0 352; CHECK_FMA-NEXT: retq 353; 354; CHECK_FMA4-LABEL: test_v4f32_mul_y_sub_one_x: 355; CHECK_FMA4: # BB#0: 356; CHECK_FMA4-NEXT: vfnmaddps %xmm1, %xmm1, %xmm0, %xmm0 357; CHECK_FMA4-NEXT: retq 358 %s = fsub <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %x 359 %m = fmul <4 x float> %y, %s 360 ret <4 x float> %m 361} 362 363define <4 x float> @test_v4f32_mul_sub_negone_x_y(<4 x float> %x, <4 x float> %y) { 364; CHECK_FMA-LABEL: test_v4f32_mul_sub_negone_x_y: 365; CHECK_FMA: # BB#0: 366; CHECK_FMA-NEXT: vfnmsub213ps %xmm1, %xmm1, %xmm0 367; CHECK_FMA-NEXT: retq 368; 369; CHECK_FMA4-LABEL: test_v4f32_mul_sub_negone_x_y: 370; CHECK_FMA4: # BB#0: 371; CHECK_FMA4-NEXT: vfnmsubps %xmm1, %xmm1, %xmm0, %xmm0 372; CHECK_FMA4-NEXT: retq 373 %s = fsub <4 x float> <float -1.0, float -1.0, float -1.0, float -1.0>, %x 374 %m = fmul <4 x float> %s, %y 375 ret <4 x float> %m 376} 377 378define <4 x float> @test_v4f32_mul_y_sub_negone_x(<4 x float> %x, <4 x float> %y) { 379; CHECK_FMA-LABEL: test_v4f32_mul_y_sub_negone_x: 380; CHECK_FMA: # BB#0: 381; CHECK_FMA-NEXT: vfnmsub213ps %xmm1, %xmm1, %xmm0 382; CHECK_FMA-NEXT: retq 383; 384; CHECK_FMA4-LABEL: test_v4f32_mul_y_sub_negone_x: 385; CHECK_FMA4: # BB#0: 386; CHECK_FMA4-NEXT: vfnmsubps %xmm1, %xmm1, %xmm0, %xmm0 387; CHECK_FMA4-NEXT: retq 388 %s = fsub <4 x float> <float -1.0, float -1.0, float -1.0, float -1.0>, %x 389 %m = fmul <4 x float> %y, %s 390 ret <4 x float> %m 391} 392 393define <4 x float> @test_v4f32_mul_sub_x_one_y(<4 x float> %x, <4 x float> %y) { 394; CHECK_FMA-LABEL: test_v4f32_mul_sub_x_one_y: 395; CHECK_FMA: # BB#0: 396; CHECK_FMA-NEXT: vfmsub213ps %xmm1, %xmm1, %xmm0 397; CHECK_FMA-NEXT: retq 398; 399; CHECK_FMA4-LABEL: test_v4f32_mul_sub_x_one_y: 400; CHECK_FMA4: # BB#0: 401; CHECK_FMA4-NEXT: vfmsubps %xmm1, %xmm1, %xmm0, %xmm0 402; CHECK_FMA4-NEXT: retq 403 %s = fsub <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0> 404 %m = fmul <4 x float> %s, %y 405 ret <4 x float> %m 406} 407 408define <4 x float> @test_v4f32_mul_y_sub_x_one(<4 x float> %x, <4 x float> %y) { 409; CHECK_FMA-LABEL: test_v4f32_mul_y_sub_x_one: 410; CHECK_FMA: # BB#0: 411; CHECK_FMA-NEXT: vfmsub213ps %xmm1, %xmm1, %xmm0 412; CHECK_FMA-NEXT: retq 413; 414; CHECK_FMA4-LABEL: test_v4f32_mul_y_sub_x_one: 415; CHECK_FMA4: # BB#0: 416; CHECK_FMA4-NEXT: vfmsubps %xmm1, %xmm1, %xmm0, %xmm0 417; CHECK_FMA4-NEXT: retq 418 %s = fsub <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0> 419 %m = fmul <4 x float> %y, %s 420 ret <4 x float> %m 421} 422 423define <4 x float> @test_v4f32_mul_sub_x_negone_y(<4 x float> %x, <4 x float> %y) { 424; CHECK_FMA-LABEL: test_v4f32_mul_sub_x_negone_y: 425; CHECK_FMA: # BB#0: 426; CHECK_FMA-NEXT: vfmadd213ps %xmm1, %xmm1, %xmm0 427; CHECK_FMA-NEXT: retq 428; 429; CHECK_FMA4-LABEL: test_v4f32_mul_sub_x_negone_y: 430; CHECK_FMA4: # BB#0: 431; CHECK_FMA4-NEXT: vfmaddps %xmm1, %xmm1, %xmm0, %xmm0 432; CHECK_FMA4-NEXT: retq 433 %s = fsub <4 x float> %x, <float -1.0, float -1.0, float -1.0, float -1.0> 434 %m = fmul <4 x float> %s, %y 435 ret <4 x float> %m 436} 437 438define <4 x float> @test_v4f32_mul_y_sub_x_negone(<4 x float> %x, <4 x float> %y) { 439; CHECK_FMA-LABEL: test_v4f32_mul_y_sub_x_negone: 440; CHECK_FMA: # BB#0: 441; CHECK_FMA-NEXT: vfmadd213ps %xmm1, %xmm1, %xmm0 442; CHECK_FMA-NEXT: retq 443; 444; CHECK_FMA4-LABEL: test_v4f32_mul_y_sub_x_negone: 445; CHECK_FMA4: # BB#0: 446; CHECK_FMA4-NEXT: vfmaddps %xmm1, %xmm1, %xmm0, %xmm0 447; CHECK_FMA4-NEXT: retq 448 %s = fsub <4 x float> %x, <float -1.0, float -1.0, float -1.0, float -1.0> 449 %m = fmul <4 x float> %y, %s 450 ret <4 x float> %m 451} 452 453; 454; Interpolation Patterns: add(mul(x,t),mul(sub(1.0,t),y)) 455; 456 457define float @test_f32_interp(float %x, float %y, float %t) { 458; CHECK_FMA-LABEL: test_f32_interp: 459; CHECK_FMA: # BB#0: 460; CHECK_FMA-NEXT: vfnmadd213ss %xmm1, %xmm2, %xmm1 461; CHECK_FMA-NEXT: vfmadd213ss %xmm1, %xmm2, %xmm0 462; CHECK_FMA-NEXT: retq 463; 464; CHECK_FMA4-LABEL: test_f32_interp: 465; CHECK_FMA4: # BB#0: 466; CHECK_FMA4-NEXT: vfnmaddss %xmm1, %xmm1, %xmm2, %xmm1 467; CHECK_FMA4-NEXT: vfmaddss %xmm1, %xmm2, %xmm0, %xmm0 468; CHECK_FMA4-NEXT: retq 469 %t1 = fsub float 1.0, %t 470 %tx = fmul float %x, %t 471 %ty = fmul float %y, %t1 472 %r = fadd float %tx, %ty 473 ret float %r 474} 475 476define <4 x float> @test_v4f32_interp(<4 x float> %x, <4 x float> %y, <4 x float> %t) { 477; CHECK_FMA-LABEL: test_v4f32_interp: 478; CHECK_FMA: # BB#0: 479; CHECK_FMA-NEXT: vfnmadd213ps %xmm1, %xmm2, %xmm1 480; CHECK_FMA-NEXT: vfmadd213ps %xmm1, %xmm2, %xmm0 481; CHECK_FMA-NEXT: retq 482; 483; CHECK_FMA4-LABEL: test_v4f32_interp: 484; CHECK_FMA4: # BB#0: 485; CHECK_FMA4-NEXT: vfnmaddps %xmm1, %xmm1, %xmm2, %xmm1 486; CHECK_FMA4-NEXT: vfmaddps %xmm1, %xmm2, %xmm0, %xmm0 487; CHECK_FMA4-NEXT: retq 488 %t1 = fsub <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %t 489 %tx = fmul <4 x float> %x, %t 490 %ty = fmul <4 x float> %y, %t1 491 %r = fadd <4 x float> %tx, %ty 492 ret <4 x float> %r 493} 494 495define <8 x float> @test_v8f32_interp(<8 x float> %x, <8 x float> %y, <8 x float> %t) { 496; CHECK_FMA-LABEL: test_v8f32_interp: 497; CHECK_FMA: # BB#0: 498; CHECK_FMA-NEXT: vfnmadd213ps %ymm1, %ymm2, %ymm1 499; CHECK_FMA-NEXT: vfmadd213ps %ymm1, %ymm2, %ymm0 500; CHECK_FMA-NEXT: retq 501; 502; CHECK_FMA4-LABEL: test_v8f32_interp: 503; CHECK_FMA4: # BB#0: 504; CHECK_FMA4-NEXT: vfnmaddps %ymm1, %ymm1, %ymm2, %ymm1 505; CHECK_FMA4-NEXT: vfmaddps %ymm1, %ymm2, %ymm0, %ymm0 506; CHECK_FMA4-NEXT: retq 507 %t1 = fsub <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %t 508 %tx = fmul <8 x float> %x, %t 509 %ty = fmul <8 x float> %y, %t1 510 %r = fadd <8 x float> %tx, %ty 511 ret <8 x float> %r 512} 513 514define double @test_f64_interp(double %x, double %y, double %t) { 515; CHECK_FMA-LABEL: test_f64_interp: 516; CHECK_FMA: # BB#0: 517; CHECK_FMA-NEXT: vfnmadd213sd %xmm1, %xmm2, %xmm1 518; CHECK_FMA-NEXT: vfmadd213sd %xmm1, %xmm2, %xmm0 519; CHECK_FMA-NEXT: retq 520; 521; CHECK_FMA4-LABEL: test_f64_interp: 522; CHECK_FMA4: # BB#0: 523; CHECK_FMA4-NEXT: vfnmaddsd %xmm1, %xmm1, %xmm2, %xmm1 524; CHECK_FMA4-NEXT: vfmaddsd %xmm1, %xmm2, %xmm0, %xmm0 525; CHECK_FMA4-NEXT: retq 526 %t1 = fsub double 1.0, %t 527 %tx = fmul double %x, %t 528 %ty = fmul double %y, %t1 529 %r = fadd double %tx, %ty 530 ret double %r 531} 532 533define <2 x double> @test_v2f64_interp(<2 x double> %x, <2 x double> %y, <2 x double> %t) { 534; CHECK_FMA-LABEL: test_v2f64_interp: 535; CHECK_FMA: # BB#0: 536; CHECK_FMA-NEXT: vfnmadd213pd %xmm1, %xmm2, %xmm1 537; CHECK_FMA-NEXT: vfmadd213pd %xmm1, %xmm2, %xmm0 538; CHECK_FMA-NEXT: retq 539; 540; CHECK_FMA4-LABEL: test_v2f64_interp: 541; CHECK_FMA4: # BB#0: 542; CHECK_FMA4-NEXT: vfnmaddpd %xmm1, %xmm1, %xmm2, %xmm1 543; CHECK_FMA4-NEXT: vfmaddpd %xmm1, %xmm2, %xmm0, %xmm0 544; CHECK_FMA4-NEXT: retq 545 %t1 = fsub <2 x double> <double 1.0, double 1.0>, %t 546 %tx = fmul <2 x double> %x, %t 547 %ty = fmul <2 x double> %y, %t1 548 %r = fadd <2 x double> %tx, %ty 549 ret <2 x double> %r 550} 551 552define <4 x double> @test_v4f64_interp(<4 x double> %x, <4 x double> %y, <4 x double> %t) { 553; CHECK_FMA-LABEL: test_v4f64_interp: 554; CHECK_FMA: # BB#0: 555; CHECK_FMA-NEXT: vfnmadd213pd %ymm1, %ymm2, %ymm1 556; CHECK_FMA-NEXT: vfmadd213pd %ymm1, %ymm2, %ymm0 557; CHECK_FMA-NEXT: retq 558; 559; CHECK_FMA4-LABEL: test_v4f64_interp: 560; CHECK_FMA4: # BB#0: 561; CHECK_FMA4-NEXT: vfnmaddpd %ymm1, %ymm1, %ymm2, %ymm1 562; CHECK_FMA4-NEXT: vfmaddpd %ymm1, %ymm2, %ymm0, %ymm0 563; CHECK_FMA4-NEXT: retq 564 %t1 = fsub <4 x double> <double 1.0, double 1.0, double 1.0, double 1.0>, %t 565 %tx = fmul <4 x double> %x, %t 566 %ty = fmul <4 x double> %y, %t1 567 %r = fadd <4 x double> %tx, %ty 568 ret <4 x double> %r 569} 570 571; (fma x, c1, (fmul x, c2)) -> (fmul x, c1+c2) 572 573define <4 x float> @test_v4f32_fma_x_c1_fmul_x_c2(<4 x float> %x) #0 { 574; ALL-LABEL: test_v4f32_fma_x_c1_fmul_x_c2: 575; ALL: # BB#0: 576; ALL-NEXT: vmulps {{.*}}(%rip), %xmm0, %xmm0 577; ALL-NEXT: retq 578 %m0 = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 579 %m1 = fmul <4 x float> %x, <float 4.0, float 3.0, float 2.0, float 1.0> 580 %a = fadd <4 x float> %m0, %m1 581 ret <4 x float> %a 582} 583 584; (fma (fmul x, c1), c2, y) -> (fma x, c1*c2, y) 585 586define <4 x float> @test_v4f32_fma_fmul_x_c1_c2_y(<4 x float> %x, <4 x float> %y) #0 { 587; CHECK_FMA-LABEL: test_v4f32_fma_fmul_x_c1_c2_y: 588; CHECK_FMA: # BB#0: 589; CHECK_FMA-NEXT: vfmadd132ps {{.*}}(%rip), %xmm1, %xmm0 590; CHECK_FMA-NEXT: retq 591; 592; CHECK_FMA4-LABEL: test_v4f32_fma_fmul_x_c1_c2_y: 593; CHECK_FMA4: # BB#0: 594; CHECK_FMA4-NEXT: vfmaddps %xmm1, {{.*}}(%rip), %xmm0, %xmm0 595; CHECK_FMA4-NEXT: retq 596 %m0 = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 597 %m1 = fmul <4 x float> %m0, <float 4.0, float 3.0, float 2.0, float 1.0> 598 %a = fadd <4 x float> %m1, %y 599 ret <4 x float> %a 600} 601 602attributes #0 = { "unsafe-fp-math"="true" } 603