998 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4declare float @llvm.fma.f32(float, float, float)5declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>)6declare <3 x float> @llvm.fma.v3f32(<3 x float>, <3 x float>, <3 x float>)7declare <8 x half> @llvm.fma.v8f16(<8 x half>, <8 x half>, <8 x half>)8declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>)9 10declare float @llvm.fmuladd.f32(float, float, float)11declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>)12declare float @llvm.fabs.f32(float)13declare <2 x double> @llvm.sqrt.v2f64(<2 x double>)14declare void @use_vec(<2 x float>)15declare void @use_vec3(<3 x float>)16 17@external = external global i3218 19define float @fma_fneg_x_fneg_y(float %x, float %y, float %z) {20; CHECK-LABEL: @fma_fneg_x_fneg_y(21; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])22; CHECK-NEXT: ret float [[FMA]]23;24 %x.fneg = fsub float -0.0, %x25 %y.fneg = fsub float -0.0, %y26 %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)27 ret float %fma28}29 30define float @fma_unary_fneg_x_unary_fneg_y(float %x, float %y, float %z) {31; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y(32; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])33; CHECK-NEXT: ret float [[FMA]]34;35 %x.fneg = fneg float %x36 %y.fneg = fneg float %y37 %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)38 ret float %fma39}40 41define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {42; CHECK-LABEL: @fma_fneg_x_fneg_y_vec(43; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])44; CHECK-NEXT: ret <2 x float> [[FMA]]45;46 %xn = fsub <2 x float> <float -0.0, float -0.0>, %x47 %yn = fsub <2 x float> <float -0.0, float -0.0>, %y48 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)49 ret <2 x float> %fma50}51 52define <2 x float> @fma_unary_fneg_x_unary_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {53; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y_vec(54; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])55; CHECK-NEXT: ret <2 x float> [[FMA]]56;57 %xn = fneg <2 x float> %x58 %yn = fneg <2 x float> %y59 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)60 ret <2 x float> %fma61}62 63define <2 x float> @fma_fneg_x_fneg_y_vec_poison(<2 x float> %x, <2 x float> %y, <2 x float> %z) {64; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_poison(65; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])66; CHECK-NEXT: ret <2 x float> [[FMA]]67;68 %xn = fsub <2 x float> <float -0.0, float poison>, %x69 %yn = fsub <2 x float> <float poison, float -0.0>, %y70 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)71 ret <2 x float> %fma72}73 74define float @fma_fneg_x_fneg_y_fast(float %x, float %y, float %z) {75; CHECK-LABEL: @fma_fneg_x_fneg_y_fast(76; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])77; CHECK-NEXT: ret float [[FMA]]78;79 %x.fneg = fsub float -0.0, %x80 %y.fneg = fsub float -0.0, %y81 %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)82 ret float %fma83}84 85define float @fma_unary_fneg_x_unary_fneg_y_fast(float %x, float %y, float %z) {86; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y_fast(87; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])88; CHECK-NEXT: ret float [[FMA]]89;90 %x.fneg = fneg float %x91 %y.fneg = fneg float %y92 %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)93 ret float %fma94}95 96define float @fma_fneg_const_fneg_y(float %y, float %z) {97; CHECK-LABEL: @fma_fneg_const_fneg_y(98; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])99; CHECK-NEXT: ret float [[FMA]]100;101 %y.fneg = fsub float -0.0, %y102 %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)103 %fma = call float @llvm.fma.f32(float %fsub, float %y.fneg, float %z)104 ret float %fma105}106 107define float @fma_unary_fneg_const_unary_fneg_y(float %y, float %z) {108; CHECK-LABEL: @fma_unary_fneg_const_unary_fneg_y(109; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])110; CHECK-NEXT: ret float [[FMA]]111;112 %y.fneg = fneg float %y113 %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)114 %fma = call float @llvm.fma.f32(float %external.fneg, float %y.fneg, float %z)115 ret float %fma116}117 118define float @fma_fneg_x_fneg_const(float %x, float %z) {119; CHECK-LABEL: @fma_fneg_x_fneg_const(120; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])121; CHECK-NEXT: ret float [[FMA]]122;123 %x.fneg = fsub float -0.0, %x124 %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)125 %fma = call float @llvm.fma.f32(float %x.fneg, float %fsub, float %z)126 ret float %fma127}128 129define float @fma_unary_fneg_x_unary_fneg_const(float %x, float %z) {130; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_const(131; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])132; CHECK-NEXT: ret float [[FMA]]133;134 %x.fneg = fneg float %x135 %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)136 %fma = call float @llvm.fma.f32(float %x.fneg, float %external.fneg, float %z)137 ret float %fma138}139 140define float @fma_fabs_x_fabs_y(float %x, float %y, float %z) {141; CHECK-LABEL: @fma_fabs_x_fabs_y(142; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])143; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])144; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])145; CHECK-NEXT: ret float [[FMA]]146;147 %x.fabs = call float @llvm.fabs.f32(float %x)148 %y.fabs = call float @llvm.fabs.f32(float %y)149 %fma = call float @llvm.fma.f32(float %x.fabs, float %y.fabs, float %z)150 ret float %fma151}152 153define float @fma_fabs_x_fabs_x(float %x, float %z) {154; CHECK-LABEL: @fma_fabs_x_fabs_x(155; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])156; CHECK-NEXT: ret float [[FMA]]157;158 %x.fabs = call float @llvm.fabs.f32(float %x)159 %fma = call float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)160 ret float %fma161}162 163define float @fma_fabs_x_fabs_x_fast(float %x, float %z) {164; CHECK-LABEL: @fma_fabs_x_fabs_x_fast(165; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])166; CHECK-NEXT: ret float [[FMA]]167;168 %x.fabs = call float @llvm.fabs.f32(float %x)169 %fma = call fast float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)170 ret float %fma171}172 173define float @fmuladd_fneg_x_fneg_y(float %x, float %y, float %z) {174; CHECK-LABEL: @fmuladd_fneg_x_fneg_y(175; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])176; CHECK-NEXT: ret float [[FMULADD]]177;178 %x.fneg = fsub float -0.0, %x179 %y.fneg = fsub float -0.0, %y180 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)181 ret float %fmuladd182}183 184define float @fmuladd_unary_fneg_x_unary_fneg_y(float %x, float %y, float %z) {185; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y(186; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])187; CHECK-NEXT: ret float [[FMULADD]]188;189 %x.fneg = fneg float %x190 %y.fneg = fneg float %y191 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)192 ret float %fmuladd193}194 195define float @fmuladd_fneg_x_fneg_y_fast(float %x, float %y, float %z) {196; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_fast(197; CHECK-NEXT: [[FMULADD:%.*]] = call fast float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])198; CHECK-NEXT: ret float [[FMULADD]]199;200 %x.fneg = fsub float -0.0, %x201 %y.fneg = fsub float -0.0, %y202 %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)203 ret float %fmuladd204}205 206define float @fmuladd_unfold(float %x, float %y, float %z) {207; CHECK-LABEL: @fmuladd_unfold(208; CHECK-NEXT: [[FMULADD:%.*]] = call reassoc contract float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])209; CHECK-NEXT: ret float [[FMULADD]]210;211 %fmuladd = call reassoc contract float @llvm.fmuladd.f32(float %x, float %y, float %z)212 ret float %fmuladd213}214 215define <8 x half> @fmuladd_unfold_vec(<8 x half> %x, <8 x half> %y, <8 x half> %z) {216; CHECK-LABEL: @fmuladd_unfold_vec(217; CHECK-NEXT: [[FMULADD:%.*]] = call reassoc contract <8 x half> @llvm.fmuladd.v8f16(<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]], <8 x half> [[Z:%.*]])218; CHECK-NEXT: ret <8 x half> [[FMULADD]]219;220 %fmuladd = call reassoc contract <8 x half> @llvm.fmuladd.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> %z)221 ret <8 x half> %fmuladd222}223 224define float @fmuladd_unary_fneg_x_unary_fneg_y_fast(float %x, float %y, float %z) {225; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y_fast(226; CHECK-NEXT: [[FMULADD:%.*]] = call fast float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])227; CHECK-NEXT: ret float [[FMULADD]]228;229 %x.fneg = fneg float %x230 %y.fneg = fneg float %y231 %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)232 ret float %fmuladd233}234 235define float @fmuladd_fneg_const_fneg_y(float %y, float %z) {236; CHECK-LABEL: @fmuladd_fneg_const_fneg_y(237; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])238; CHECK-NEXT: ret float [[FMULADD]]239;240 %y.fneg = fsub float -0.0, %y241 %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)242 %fmuladd = call float @llvm.fmuladd.f32(float %fsub, float %y.fneg, float %z)243 ret float %fmuladd244}245 246define float @fmuladd_unary_fneg_const_unary_fneg_y(float %y, float %z) {247; CHECK-LABEL: @fmuladd_unary_fneg_const_unary_fneg_y(248; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])249; CHECK-NEXT: ret float [[FMULADD]]250;251 %y.fneg = fneg float %y252 %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)253 %fmuladd = call float @llvm.fmuladd.f32(float %external.fneg, float %y.fneg, float %z)254 ret float %fmuladd255}256 257define float @fmuladd_fneg_x_fneg_const(float %x, float %z) {258; CHECK-LABEL: @fmuladd_fneg_x_fneg_const(259; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])260; CHECK-NEXT: ret float [[FMULADD]]261;262 %x.fneg = fsub float -0.0, %x263 %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)264 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %fsub, float %z)265 ret float %fmuladd266}267 268define float @fmuladd_unary_fneg_x_unary_fneg_const(float %x, float %z) {269; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_const(270; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])271; CHECK-NEXT: ret float [[FMULADD]]272;273 %x.fneg = fneg float %x274 %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)275 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %external.fneg, float %z)276 ret float %fmuladd277}278 279define float @fmuladd_fabs_x_fabs_y(float %x, float %y, float %z) {280; CHECK-LABEL: @fmuladd_fabs_x_fabs_y(281; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])282; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])283; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])284; CHECK-NEXT: ret float [[FMULADD]]285;286 %x.fabs = call float @llvm.fabs.f32(float %x)287 %y.fabs = call float @llvm.fabs.f32(float %y)288 %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %y.fabs, float %z)289 ret float %fmuladd290}291 292define float @fmuladd_fabs_x_fabs_x(float %x, float %z) {293; CHECK-LABEL: @fmuladd_fabs_x_fabs_x(294; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])295; CHECK-NEXT: ret float [[FMULADD]]296;297 %x.fabs = call float @llvm.fabs.f32(float %x)298 %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)299 ret float %fmuladd300}301 302define float @fmuladd_fabs_x_fabs_x_fast(float %x, float %z) {303; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_fast(304; CHECK-NEXT: [[FMULADD:%.*]] = call fast float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])305; CHECK-NEXT: ret float [[FMULADD]]306;307 %x.fabs = call float @llvm.fabs.f32(float %x)308 %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)309 ret float %fmuladd310}311 312define float @fma_k_y_z(float %y, float %z) {313; CHECK-LABEL: @fma_k_y_z(314; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])315; CHECK-NEXT: ret float [[FMA]]316;317 %fma = call float @llvm.fma.f32(float 4.0, float %y, float %z)318 ret float %fma319}320 321define float @fma_k_y_z_fast(float %y, float %z) {322; CHECK-LABEL: @fma_k_y_z_fast(323; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])324; CHECK-NEXT: ret float [[FMA]]325;326 %fma = call fast float @llvm.fma.f32(float 4.0, float %y, float %z)327 ret float %fma328}329 330; Treat fmuladd like an fma intrinsic331define float @fmuladd_k_y_z_fast(float %y, float %z) {332; CHECK-LABEL: @fmuladd_k_y_z_fast(333; CHECK-NEXT: [[FMULADD:%.*]] = call fast float @llvm.fmuladd.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])334; CHECK-NEXT: ret float [[FMULADD]]335;336 %fmuladd = call fast float @llvm.fmuladd.f32(float 4.0, float %y, float %z)337 ret float %fmuladd338}339 340define float @fma_1_y_z(float %y, float %z) {341; CHECK-LABEL: @fma_1_y_z(342; CHECK-NEXT: [[FMA:%.*]] = fadd float [[Y:%.*]], [[Z:%.*]]343; CHECK-NEXT: ret float [[FMA]]344;345 %fma = call float @llvm.fma.f32(float 1.0, float %y, float %z)346 ret float %fma347}348 349define float @fma_x_1_z(float %x, float %z) {350; CHECK-LABEL: @fma_x_1_z(351; CHECK-NEXT: [[FMA:%.*]] = fadd float [[X:%.*]], [[Z:%.*]]352; CHECK-NEXT: ret float [[FMA]]353;354 %fma = call float @llvm.fma.f32(float %x, float 1.0, float %z)355 ret float %fma356}357 358define <2 x float> @fma_x_1_z_v2f32(<2 x float> %x, <2 x float> %z) {359; CHECK-LABEL: @fma_x_1_z_v2f32(360; CHECK-NEXT: [[FMA:%.*]] = fadd <2 x float> [[X:%.*]], [[Z:%.*]]361; CHECK-NEXT: ret <2 x float> [[FMA]]362;363 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>, <2 x float> %z)364 ret <2 x float> %fma365}366 367define <2 x float> @fma_x_1_2_z_v2f32(<2 x float> %x, <2 x float> %z) {368; CHECK-LABEL: @fma_x_1_2_z_v2f32(369; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float> [[Z:%.*]])370; CHECK-NEXT: ret <2 x float> [[FMA]]371;372 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 2.0>, <2 x float> %z)373 ret <2 x float> %fma374}375 376define float @fma_x_1_z_fast(float %x, float %z) {377; CHECK-LABEL: @fma_x_1_z_fast(378; CHECK-NEXT: [[FMA:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]379; CHECK-NEXT: ret float [[FMA]]380;381 %fma = call fast float @llvm.fma.f32(float %x, float 1.0, float %z)382 ret float %fma383}384 385define float @fma_1_1_z(float %z) {386; CHECK-LABEL: @fma_1_1_z(387; CHECK-NEXT: [[FMA:%.*]] = fadd float [[Z:%.*]], 1.000000e+00388; CHECK-NEXT: ret float [[FMA]]389;390 %fma = call float @llvm.fma.f32(float 1.0, float 1.0, float %z)391 ret float %fma392}393 394define float @fma_x_y_0(float %x, float %y) {395; CHECK-LABEL: @fma_x_y_0(396; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float 0.000000e+00)397; CHECK-NEXT: ret float [[FMA]]398;399 %fma = call float @llvm.fma.f32(float %x, float %y, float 0.0)400 ret float %fma401}402 403define float @fma_x_y_0_nsz(float %x, float %y) {404; CHECK-LABEL: @fma_x_y_0_nsz(405; CHECK-NEXT: [[FMA:%.*]] = fmul nsz float [[X:%.*]], [[Y:%.*]]406; CHECK-NEXT: ret float [[FMA]]407;408 %fma = call nsz float @llvm.fma.f32(float %x, float %y, float 0.0)409 ret float %fma410}411 412define <8 x half> @fma_x_y_0_v(<8 x half> %x, <8 x half> %y) {413; CHECK-LABEL: @fma_x_y_0_v(414; CHECK-NEXT: [[FMA:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]], <8 x half> zeroinitializer)415; CHECK-NEXT: ret <8 x half> [[FMA]]416;417 %fma = call <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> zeroinitializer)418 ret <8 x half> %fma419}420 421define <8 x half> @fma_x_y_0_nsz_v(<8 x half> %x, <8 x half> %y) {422; CHECK-LABEL: @fma_x_y_0_nsz_v(423; CHECK-NEXT: [[FMA:%.*]] = fmul nsz <8 x half> [[X:%.*]], [[Y:%.*]]424; CHECK-NEXT: ret <8 x half> [[FMA]]425;426 %fma = call nsz <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> zeroinitializer)427 ret <8 x half> %fma428}429 430define float @fmuladd_x_y_0(float %x, float %y) {431; CHECK-LABEL: @fmuladd_x_y_0(432; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float 0.000000e+00)433; CHECK-NEXT: ret float [[FMA]]434;435 %fma = call float @llvm.fmuladd.f32(float %x, float %y, float 0.0)436 ret float %fma437}438 439define float @fmuladd_x_y_0_nsz(float %x, float %y) {440; CHECK-LABEL: @fmuladd_x_y_0_nsz(441; CHECK-NEXT: [[FMA:%.*]] = fmul nsz float [[X:%.*]], [[Y:%.*]]442; CHECK-NEXT: ret float [[FMA]]443;444 %fma = call nsz float @llvm.fmuladd.f32(float %x, float %y, float 0.0)445 ret float %fma446}447 448define float @fma_x_y_m0(float %x, float %y) {449; CHECK-LABEL: @fma_x_y_m0(450; CHECK-NEXT: [[FMA:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]451; CHECK-NEXT: ret float [[FMA]]452;453 %fma = call float @llvm.fma.f32(float %x, float %y, float -0.0)454 ret float %fma455}456 457define <8 x half> @fma_x_y_m0_v(<8 x half> %x, <8 x half> %y) {458; CHECK-LABEL: @fma_x_y_m0_v(459; CHECK-NEXT: [[FMA:%.*]] = fmul <8 x half> [[X:%.*]], [[Y:%.*]]460; CHECK-NEXT: ret <8 x half> [[FMA]]461;462 %fma = call <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> <half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0>)463 ret <8 x half> %fma464}465 466define float @fmuladd_x_y_m0(float %x, float %y) {467; CHECK-LABEL: @fmuladd_x_y_m0(468; CHECK-NEXT: [[FMA:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]469; CHECK-NEXT: ret float [[FMA]]470;471 %fma = call float @llvm.fmuladd.f32(float %x, float %y, float -0.0)472 ret float %fma473}474 475define float @fmuladd_x_1_z_fast(float %x, float %z) {476; CHECK-LABEL: @fmuladd_x_1_z_fast(477; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]478; CHECK-NEXT: ret float [[FMULADD]]479;480 %fmuladd = call fast float @llvm.fmuladd.f32(float %x, float 1.0, float %z)481 ret float %fmuladd482}483 484define <2 x double> @fmuladd_a_0_b(<2 x double> %a, <2 x double> %b) {485; CHECK-LABEL: @fmuladd_a_0_b(486; CHECK-NEXT: ret <2 x double> [[B:%.*]]487;488 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)489 ret <2 x double> %res490}491 492define <2 x double> @fmuladd_0_a_b(<2 x double> %a, <2 x double> %b) {493; CHECK-LABEL: @fmuladd_0_a_b(494; CHECK-NEXT: ret <2 x double> [[B:%.*]]495;496 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)497 ret <2 x double> %res498}499 500define <2 x double> @fmuladd_a_0_b_missing_flags(<2 x double> %a, <2 x double> %b) {501; CHECK-LABEL: @fmuladd_a_0_b_missing_flags(502; CHECK-NEXT: [[RES:%.*]] = call nnan <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[A:%.*]], <2 x double> zeroinitializer, <2 x double> [[B:%.*]])503; CHECK-NEXT: ret <2 x double> [[RES]]504;505 %res = call nnan <2 x double> @llvm.fmuladd.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)506 ret <2 x double> %res507}508 509define <2 x double> @fma_a_0_b(<2 x double> %a, <2 x double> %b) {510; CHECK-LABEL: @fma_a_0_b(511; CHECK-NEXT: ret <2 x double> [[B:%.*]]512;513 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)514 ret <2 x double> %res515}516 517define <2 x double> @fma_0_a_b(<2 x double> %a, <2 x double> %b) {518; CHECK-LABEL: @fma_0_a_b(519; CHECK-NEXT: ret <2 x double> [[B:%.*]]520;521 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)522 ret <2 x double> %res523}524 525define <2 x double> @fma_0_a_b_missing_flags(<2 x double> %a, <2 x double> %b) {526; CHECK-LABEL: @fma_0_a_b_missing_flags(527; CHECK-NEXT: [[RES:%.*]] = call nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[A:%.*]], <2 x double> zeroinitializer, <2 x double> [[B:%.*]])528; CHECK-NEXT: ret <2 x double> [[RES]]529;530 %res = call nsz <2 x double> @llvm.fma.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)531 ret <2 x double> %res532}533 534define <2 x double> @fma_sqrt(<2 x double> %a, <2 x double> %b) {535; CHECK-LABEL: @fma_sqrt(536; CHECK-NEXT: [[RES:%.*]] = fadd fast <2 x double> [[A:%.*]], [[B:%.*]]537; CHECK-NEXT: ret <2 x double> [[RES]]538;539 %sqrt = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> %a)540 %res = call fast <2 x double> @llvm.fma.v2f64(<2 x double> %sqrt, <2 x double> %sqrt, <2 x double> %b)541 ret <2 x double> %res542}543 544; We do not fold constant multiplies in FMAs, as they could require rounding, unless either constant is 0.0 or 1.0.545define <2 x double> @fma_const_fmul(<2 x double> %b) {546; CHECK-LABEL: @fma_const_fmul(547; CHECK-NEXT: [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x4131233302898702, double 0x40C387800000D6C0>, <2 x double> <double 1.291820e-08, double 9.123000e-06>, <2 x double> [[B:%.*]])548; CHECK-NEXT: ret <2 x double> [[RES]]549;550 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)551 ret <2 x double> %res552}553 554define <2 x double> @fma_const_fmul_zero(<2 x double> %b) {555; CHECK-LABEL: @fma_const_fmul_zero(556; CHECK-NEXT: ret <2 x double> [[B:%.*]]557;558 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0, double 0.0>, <2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> %b)559 ret <2 x double> %res560}561 562define <2 x double> @fma_const_fmul_zero2(<2 x double> %b) {563; CHECK-LABEL: @fma_const_fmul_zero2(564; CHECK-NEXT: ret <2 x double> [[B:%.*]]565;566 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0, double 0.0>, <2 x double> %b)567 ret <2 x double> %res568}569 570define <2 x double> @fma_const_fmul_one(<2 x double> %b) {571; CHECK-LABEL: @fma_const_fmul_one(572; CHECK-NEXT: [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x4131233302898702, double 0x40C387800000D6C0>573; CHECK-NEXT: ret <2 x double> [[RES]]574;575 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> %b)576 ret <2 x double> %res577}578 579define <2 x double> @fma_const_fmul_one2(<2 x double> %b) {580; CHECK-LABEL: @fma_const_fmul_one2(581; CHECK-NEXT: [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x4131233302898702, double 0x40C387800000D6C0>582; CHECK-NEXT: ret <2 x double> [[RES]]583;584 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 1.0, double 1.0>, <2 x double> %b)585 ret <2 x double> %res586}587 588define <2 x double> @fma_nan_and_const_0(<2 x double> %b) {589; CHECK-LABEL: @fma_nan_and_const_0(590; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)591;592 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)593 ret <2 x double> %res594}595 596define <2 x double> @fma_nan_and_const_1(<2 x double> %b) {597; CHECK-LABEL: @fma_nan_and_const_1(598; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)599;600 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b)601 ret <2 x double> %res602}603 604define <2 x double> @fma_nan_and_const_2(<2 x double> %b) {605; CHECK-LABEL: @fma_nan_and_const_2(606; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)607;608 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)609 ret <2 x double> %res610}611 612define <2 x double> @fma_undef_0(<2 x double> %b, <2 x double> %c) {613; CHECK-LABEL: @fma_undef_0(614; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)615;616 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double undef, double undef>, <2 x double> %b, <2 x double> %c)617 ret <2 x double> %res618}619 620define <2 x double> @fma_undef_1(<2 x double> %b, <2 x double> %c) {621; CHECK-LABEL: @fma_undef_1(622; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)623;624 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double undef, double undef>, <2 x double> %c)625 ret <2 x double> %res626}627 628define <2 x double> @fma_undef_2(<2 x double> %b, <2 x double> %c) {629; CHECK-LABEL: @fma_undef_2(630; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)631;632 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double undef, double undef>)633 ret <2 x double> %res634}635 636define <2 x double> @fma_partial_undef_0(<2 x double> %b, <2 x double> %c) {637; CHECK-LABEL: @fma_partial_undef_0(638; CHECK-NEXT: [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> <double undef, double 0x4068E00A137F38C5>, <2 x double> [[C:%.*]])639; CHECK-NEXT: ret <2 x double> [[RES]]640;641 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double undef, double 199.00123>, <2 x double> %b, <2 x double> %c)642 ret <2 x double> %res643}644 645define <2 x double> @fma_partial_undef_1(<2 x double> %b, <2 x double> %c) {646; CHECK-LABEL: @fma_partial_undef_1(647; CHECK-NEXT: [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> <double 0x4068E00A137F38C5, double undef>, <2 x double> [[C:%.*]])648; CHECK-NEXT: ret <2 x double> [[RES]]649;650 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double 199.00123, double undef>, <2 x double> %c)651 ret <2 x double> %res652}653 654define <2 x double> @fma_partial_undef_2(<2 x double> %b, <2 x double> %c) {655; CHECK-LABEL: @fma_partial_undef_2(656; CHECK-NEXT: [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> [[C:%.*]], <2 x double> <double 0x4068E00A137F38C5, double undef>)657; CHECK-NEXT: ret <2 x double> [[RES]]658;659 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 199.00123, double undef>)660 ret <2 x double> %res661}662 663 664define <2 x double> @fma_nan_0(<2 x double> %b, <2 x double> %c) {665; CHECK-LABEL: @fma_nan_0(666; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)667;668 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b, <2 x double> %c)669 ret <2 x double> %res670}671define <2 x double> @fma_nan_1(<2 x double> %b, <2 x double> %c) {672; CHECK-LABEL: @fma_nan_1(673; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)674;675 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %c)676 ret <2 x double> %res677}678 679define <2 x double> @fma_nan_2(<2 x double> %b, <2 x double> %c) {680; CHECK-LABEL: @fma_nan_2(681; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)682;683 %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)684 ret <2 x double> %res685}686 687define <2 x double> @fmuladd_const_fmul(<2 x double> %b) {688; CHECK-LABEL: @fmuladd_const_fmul(689; CHECK-NEXT: [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x3F8DB6C076AD949B, double 0x3FB75A405B6E6D69>690; CHECK-NEXT: ret <2 x double> [[RES]]691;692 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)693 ret <2 x double> %res694}695 696define <2 x double> @fmuladd_nan_and_const_0(<2 x double> %b) {697; CHECK-LABEL: @fmuladd_nan_and_const_0(698; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)699;700 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)701 ret <2 x double> %res702}703 704define <2 x double> @fmuladd_nan_and_const_1(<2 x double> %b) {705; CHECK-LABEL: @fmuladd_nan_and_const_1(706; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)707;708 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b)709 ret <2 x double> %res710}711 712define <2 x double> @fmuladd_nan_and_const_2(<2 x double> %b) {713; CHECK-LABEL: @fmuladd_nan_and_const_2(714; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)715;716 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)717 ret <2 x double> %res718}719 720define <2 x double> @fmuladd_nan_0(<2 x double> %b, <2 x double> %c) {721; CHECK-LABEL: @fmuladd_nan_0(722; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)723;724 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b, <2 x double> %c)725 ret <2 x double> %res726}727 728define <2 x double> @fmuladd_nan_1(<2 x double> %b, <2 x double> %c) {729; CHECK-LABEL: @fmuladd_nan_1(730; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)731;732 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %c)733 ret <2 x double> %res734}735 736define <2 x double> @fmuladd_undef_0(<2 x double> %b, <2 x double> %c) {737; CHECK-LABEL: @fmuladd_undef_0(738; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)739;740 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double undef, double undef>, <2 x double> %b, <2 x double> %c)741 ret <2 x double> %res742}743 744define <2 x double> @fmuladd_undef_1(<2 x double> %b, <2 x double> %c) {745; CHECK-LABEL: @fmuladd_undef_1(746; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)747;748 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> <double undef, double undef>, <2 x double> %c)749 ret <2 x double> %res750}751 752define <2 x double> @fmuladd_undef_2(<2 x double> %b, <2 x double> %c) {753; CHECK-LABEL: @fmuladd_undef_2(754; CHECK-NEXT: ret <2 x double> splat (double 0x7FF8000000000000)755;756 %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)757 ret <2 x double> %res758}759 760define <2 x float> @fma_unary_shuffle_ops(<2 x float> %x, <2 x float> %y, <2 x float> %z) {761; CHECK-LABEL: @fma_unary_shuffle_ops(762; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])763; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>764; CHECK-NEXT: ret <2 x float> [[R]]765;766 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>767 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>768 %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>769 %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)770 ret <2 x float> %r771}772 773define <3 x float> @fma_unary_shuffle_ops_widening(<2 x float> %x, <2 x float> %y, <2 x float> %z) {774; CHECK-LABEL: @fma_unary_shuffle_ops_widening(775; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>776; CHECK-NEXT: call void @use_vec3(<3 x float> [[A]])777; CHECK-NEXT: [[TMP1:%.*]] = call fast <2 x float> @llvm.fma.v2f32(<2 x float> [[X]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])778; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>779; CHECK-NEXT: ret <3 x float> [[R]]780;781 %a = shufflevector <2 x float> %x, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>782 call void @use_vec3(<3 x float> %a)783 %b = shufflevector <2 x float> %y, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>784 %c = shufflevector <2 x float> %z, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>785 %r = call fast <3 x float> @llvm.fma.v3f32(<3 x float> %a, <3 x float> %b, <3 x float> %c)786 ret <3 x float> %r787}788 789define <2 x float> @fma_unary_shuffle_ops_narrowing(<3 x float> %x, <3 x float> %y, <3 x float> %z) {790; CHECK-LABEL: @fma_unary_shuffle_ops_narrowing(791; CHECK-NEXT: [[B:%.*]] = shufflevector <3 x float> [[Y:%.*]], <3 x float> poison, <2 x i32> <i32 1, i32 0>792; CHECK-NEXT: call void @use_vec(<2 x float> [[B]])793; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <3 x float> @llvm.fma.v3f32(<3 x float> [[X:%.*]], <3 x float> [[Y]], <3 x float> [[Z:%.*]])794; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[TMP1]], <3 x float> poison, <2 x i32> <i32 1, i32 0>795; CHECK-NEXT: ret <2 x float> [[R]]796;797 %a = shufflevector <3 x float> %x, <3 x float> poison, <2 x i32> <i32 1, i32 0>798 %b = shufflevector <3 x float> %y, <3 x float> poison, <2 x i32> <i32 1, i32 0>799 call void @use_vec(<2 x float> %b)800 %c = shufflevector <3 x float> %z, <3 x float> poison, <2 x i32> <i32 1, i32 0>801 %r = call nnan nsz <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)802 ret <2 x float> %r803}804 805define <2 x float> @fma_unary_shuffle_ops_1_const(<2 x float> %x, <2 x float> %y) {806; CHECK-LABEL: @fma_unary_shuffle_ops_1_const(807; CHECK-NEXT: [[Y:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 1.000000e+00>, <2 x float> [[Y1:%.*]])808; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y]], <2 x float> poison, <2 x i32> <i32 1, i32 0>809; CHECK-NEXT: ret <2 x float> [[B]]810;811 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>812 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>813 %r = call <2 x float> @llvm.fma(<2 x float> %a, <2 x float> <float 1.0, float 2.0>, <2 x float> %b)814 ret <2 x float> %r815}816 817define <2 x float> @fma_unary_shuffle_ops_2_const(<2 x float> %x) {818; CHECK-LABEL: @fma_unary_shuffle_ops_2_const(819; CHECK-NEXT: [[X:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> <float 2.000000e+00, float 1.000000e+00>, <2 x float> <float 2.000000e+00, float 1.000000e+00>, <2 x float> [[X1:%.*]])820; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X]], <2 x float> poison, <2 x i32> <i32 1, i32 0>821; CHECK-NEXT: ret <2 x float> [[A]]822;823 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>824 %r = call <2 x float> @llvm.fma(<2 x float> <float 1.0, float 2.0>, <2 x float> <float 1.0, float 2.0>, <2 x float> %a)825 ret <2 x float> %r826}827 828define <vscale x 2 x float> @fma_unary_shuffle_ops_1_const_scalable(<vscale x 2 x float> %x, <vscale x 2 x float> %y) {829; CHECK-LABEL: @fma_unary_shuffle_ops_1_const_scalable(830; CHECK-NEXT: [[R:%.*]] = call <vscale x 2 x float> @llvm.fma.nxv2f32(<vscale x 2 x float> [[A:%.*]], <vscale x 2 x float> splat (float 4.200000e+01), <vscale x 2 x float> [[B:%.*]])831; CHECK-NEXT: [[R1:%.*]] = shufflevector <vscale x 2 x float> [[R]], <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer832; CHECK-NEXT: ret <vscale x 2 x float> [[R1]]833;834 %a = shufflevector <vscale x 2 x float> %x, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer835 %b = shufflevector <vscale x 2 x float> %y, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer836 %r = call <vscale x 2 x float> @llvm.fma(<vscale x 2 x float> %a, <vscale x 2 x float> splat (float 42.0), <vscale x 2 x float> %b)837 ret <vscale x 2 x float> %r838}839 840define <vscale x 2 x float> @fma_unary_shuffle_ops_2_const_scalable(<vscale x 2 x float> %x) {841; CHECK-LABEL: @fma_unary_shuffle_ops_2_const_scalable(842; CHECK-NEXT: [[X:%.*]] = call <vscale x 2 x float> @llvm.fma.nxv2f32(<vscale x 2 x float> splat (float 4.200000e+01), <vscale x 2 x float> splat (float 4.200000e+01), <vscale x 2 x float> [[X1:%.*]])843; CHECK-NEXT: [[A:%.*]] = shufflevector <vscale x 2 x float> [[X]], <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer844; CHECK-NEXT: ret <vscale x 2 x float> [[A]]845;846 %a = shufflevector <vscale x 2 x float> %x, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer847 %r = call <vscale x 2 x float> @llvm.fma(<vscale x 2 x float> splat (float 42.0), <vscale x 2 x float> splat (float 42.0), <vscale x 2 x float> %a)848 ret <vscale x 2 x float> %r849}850 851define <3 x float> @fma_unary_shuffle_ops_widening_1_const(<2 x float> %x, <2 x float> %y) {852; CHECK-LABEL: @fma_unary_shuffle_ops_widening_1_const(853; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 poison>854; CHECK-NEXT: call void @use_vec3(<3 x float> [[A]])855; CHECK-NEXT: [[Y:%.*]] = call fast <2 x float> @llvm.fma.v2f32(<2 x float> [[X]], <2 x float> splat (float 4.200000e+01), <2 x float> [[Y1:%.*]])856; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 poison>857; CHECK-NEXT: ret <3 x float> [[B]]858;859 %a = shufflevector <2 x float> %x, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 poison>860 call void @use_vec3(<3 x float> %a)861 %b = shufflevector <2 x float> %y, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 poison>862 %r = call fast <3 x float> @llvm.fma(<3 x float> %a, <3 x float> splat (float 42.0), <3 x float> %b)863 ret <3 x float> %r864}865 866; negative test - must have 3 shuffles867 868define <2 x float> @fma_unary_shuffle_ops_unshuffled(<2 x float> %x, <2 x float> %y, <2 x float> %z) {869; CHECK-LABEL: @fma_unary_shuffle_ops_unshuffled(870; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>871; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>872; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[Z:%.*]])873; CHECK-NEXT: ret <2 x float> [[R]]874;875 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>876 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>877 %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %z)878 ret <2 x float> %r879}880 881; negative test - must have identical masks882 883define <2 x float> @fma_unary_shuffle_ops_wrong_mask(<2 x float> %x, <2 x float> %y, <2 x float> %z) {884; CHECK-LABEL: @fma_unary_shuffle_ops_wrong_mask(885; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>886; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> zeroinitializer887; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>888; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])889; CHECK-NEXT: ret <2 x float> [[R]]890;891 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>892 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 0, i32 0>893 %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>894 %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)895 ret <2 x float> %r896}897 898; negative test - too many uses899 900define <2 x float> @fma_unary_shuffle_ops_uses(<2 x float> %x, <2 x float> %y, <2 x float> %z) {901; CHECK-LABEL: @fma_unary_shuffle_ops_uses(902; CHECK-NEXT: [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>903; CHECK-NEXT: call void @use_vec(<2 x float> [[A]])904; CHECK-NEXT: [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>905; CHECK-NEXT: call void @use_vec(<2 x float> [[B]])906; CHECK-NEXT: [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>907; CHECK-NEXT: call void @use_vec(<2 x float> [[C]])908; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])909; CHECK-NEXT: ret <2 x float> [[R]]910;911 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>912 call void @use_vec(<2 x float> %a)913 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>914 call void @use_vec(<2 x float> %b)915 %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>916 call void @use_vec(<2 x float> %c)917 %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)918 ret <2 x float> %r919}920 921define half @fma_negone(half %x, half %y) {922; CHECK-LABEL: @fma_negone(923; CHECK-NEXT: [[SUB:%.*]] = fsub half [[Y:%.*]], [[X:%.*]]924; CHECK-NEXT: ret half [[SUB]]925;926 %sub = call half @llvm.fma.f16(half %x, half -1.0, half %y)927 ret half %sub928}929 930define half @fmuladd_negone(half %x, half %y) {931; CHECK-LABEL: @fmuladd_negone(932; CHECK-NEXT: [[SUB:%.*]] = fsub half [[Y:%.*]], [[X:%.*]]933; CHECK-NEXT: ret half [[SUB]]934;935 %sub = call half @llvm.fmuladd.f16(half %x, half -1.0, half %y)936 ret half %sub937}938 939define half @fma_negone_fmf(half %x, half %y) {940; CHECK-LABEL: @fma_negone_fmf(941; CHECK-NEXT: [[SUB:%.*]] = fsub nnan ninf nsz half [[Y:%.*]], [[X:%.*]]942; CHECK-NEXT: ret half [[SUB]]943;944 %sub = call nnan ninf nsz half @llvm.fma.f16(half %x, half -1.0, half %y)945 ret half %sub946}947 948define half @fmuladd_negone_fmf(half %x, half %y) {949; CHECK-LABEL: @fmuladd_negone_fmf(950; CHECK-NEXT: [[SUB:%.*]] = fsub nnan ninf nsz half [[Y:%.*]], [[X:%.*]]951; CHECK-NEXT: ret half [[SUB]]952;953 %sub = call nnan ninf nsz half @llvm.fmuladd.f16(half %x, half -1.0, half %y)954 ret half %sub955}956 957define <2 x half> @fma_negone_vec(<2 x half> %x, <2 x half> %y) {958; CHECK-LABEL: @fma_negone_vec(959; CHECK-NEXT: [[SUB:%.*]] = fsub <2 x half> [[Y:%.*]], [[X:%.*]]960; CHECK-NEXT: ret <2 x half> [[SUB]]961;962 %sub = call <2 x half> @llvm.fma.v2f16(<2 x half> %x, <2 x half> splat(half -1.0), <2 x half> %y)963 ret <2 x half> %sub964}965 966define <2 x half> @fma_negone_vec_partial_undef(<2 x half> %x, <2 x half> %y) {967; CHECK-LABEL: @fma_negone_vec_partial_undef(968; CHECK-NEXT: [[SUB:%.*]] = call <2 x half> @llvm.fma.v2f16(<2 x half> [[X:%.*]], <2 x half> <half undef, half 0xHBC00>, <2 x half> [[Y:%.*]])969; CHECK-NEXT: ret <2 x half> [[SUB]]970;971 %sub = call <2 x half> @llvm.fma.v2f16(<2 x half> %x, <2 x half> <half undef, half -1.0>, <2 x half> %y)972 ret <2 x half> %sub973}974 975define <2 x float> @fmuladd_unary_shuffle_ops(<2 x float> %x, <2 x float> %y, <2 x float> %z) {976; CHECK-LABEL: @fmuladd_unary_shuffle_ops(977; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]], <2 x float> [[C:%.*]])978; CHECK-NEXT: [[R1:%.*]] = shufflevector <2 x float> [[R]], <2 x float> poison, <2 x i32> <i32 1, i32 0>979; CHECK-NEXT: ret <2 x float> [[R1]]980;981 %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>982 %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>983 %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>984 %r = call <2 x float> @llvm.fmuladd(<2 x float> %a, <2 x float> %b, <2 x float> %c)985 ret <2 x float> %r986}987 988; negative tests989 990define half @fma_non_negone(half %x, half %y) {991; CHECK-LABEL: @fma_non_negone(992; CHECK-NEXT: [[SUB:%.*]] = call half @llvm.fma.f16(half [[X:%.*]], half 0xHBE00, half [[Y:%.*]])993; CHECK-NEXT: ret half [[SUB]]994;995 %sub = call half @llvm.fma.f16(half %x, half -1.5, half %y)996 ret half %sub997}998