289 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX4 5;6; NOTE: this is generated by utils/update_llc_test_checks.py but we can't check NAN types (PR30443),7; so we need to edit it to remove the NAN constant comments8;9 10; copysign(x, c1) -> fabs(x) iff ispos(c1)11define <4 x float> @combine_vec_fcopysign_pos_constant0(<4 x float> %x) {12; SSE-LABEL: combine_vec_fcopysign_pos_constant0:13; SSE: # %bb.0:14; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm015; SSE-NEXT: retq16;17; AVX-LABEL: combine_vec_fcopysign_pos_constant0:18; AVX: # %bb.0:19; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]20; AVX-NEXT: vandps %xmm1, %xmm0, %xmm021; AVX-NEXT: retq22 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> <float 2.0, float 2.0, float 2.0, float 2.0>)23 ret <4 x float> %124}25 26define <4 x float> @combine_vec_fcopysign_pos_constant1(<4 x float> %x) {27; SSE-LABEL: combine_vec_fcopysign_pos_constant1:28; SSE: # %bb.0:29; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm030; SSE-NEXT: retq31;32; AVX-LABEL: combine_vec_fcopysign_pos_constant1:33; AVX: # %bb.0:34; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]35; AVX-NEXT: vandps %xmm1, %xmm0, %xmm036; AVX-NEXT: retq37 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> <float 0.0, float 2.0, float 4.0, float 8.0>)38 ret <4 x float> %139}40 41define <4 x float> @combine_vec_fcopysign_fabs_sgn(<4 x float> %x, <4 x float> %y) {42; SSE-LABEL: combine_vec_fcopysign_fabs_sgn:43; SSE: # %bb.0:44; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm045; SSE-NEXT: retq46;47; AVX-LABEL: combine_vec_fcopysign_fabs_sgn:48; AVX: # %bb.0:49; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]50; AVX-NEXT: vandps %xmm1, %xmm0, %xmm051; AVX-NEXT: retq52 %1 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %y)53 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> %1)54 ret <4 x float> %255}56 57; copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1)58define <4 x float> @combine_vec_fcopysign_neg_constant0(<4 x float> %x) {59; SSE-LABEL: combine_vec_fcopysign_neg_constant0:60; SSE: # %bb.0:61; SSE-NEXT: orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm062; SSE-NEXT: retq63;64; AVX-LABEL: combine_vec_fcopysign_neg_constant0:65; AVX: # %bb.0:66; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]67; AVX-NEXT: vorps %xmm1, %xmm0, %xmm068; AVX-NEXT: retq69 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> <float -2.0, float -2.0, float -2.0, float -2.0>)70 ret <4 x float> %171}72 73define <4 x float> @combine_vec_fcopysign_neg_constant1(<4 x float> %x) {74; SSE-LABEL: combine_vec_fcopysign_neg_constant1:75; SSE: # %bb.0:76; SSE-NEXT: orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm077; SSE-NEXT: retq78;79; AVX-LABEL: combine_vec_fcopysign_neg_constant1:80; AVX: # %bb.0:81; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]82; AVX-NEXT: vorps %xmm1, %xmm0, %xmm083; AVX-NEXT: retq84 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> <float -0.0, float -2.0, float -4.0, float -8.0>)85 ret <4 x float> %186}87 88define <4 x float> @combine_vec_fcopysign_fneg_fabs_sgn(<4 x float> %x, <4 x float> %y) {89; SSE-LABEL: combine_vec_fcopysign_fneg_fabs_sgn:90; SSE: # %bb.0:91; SSE-NEXT: orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm092; SSE-NEXT: retq93;94; AVX-LABEL: combine_vec_fcopysign_fneg_fabs_sgn:95; AVX: # %bb.0:96; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]97; AVX-NEXT: vorps %xmm1, %xmm0, %xmm098; AVX-NEXT: retq99 %1 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %y)100 %2 = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %1101 %3 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> %2)102 ret <4 x float> %3103}104 105; copysign(fabs(x), y) -> copysign(x, y)106define <4 x float> @combine_vec_fcopysign_fabs_mag(<4 x float> %x, <4 x float> %y) {107; SSE-LABEL: combine_vec_fcopysign_fabs_mag:108; SSE: # %bb.0:109; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1110; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0111; SSE-NEXT: orps %xmm1, %xmm0112; SSE-NEXT: retq113;114; AVX-LABEL: combine_vec_fcopysign_fabs_mag:115; AVX: # %bb.0:116; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]117; AVX-NEXT: vandps %xmm2, %xmm1, %xmm1118; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]119; AVX-NEXT: vandps %xmm2, %xmm0, %xmm0120; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0121; AVX-NEXT: retq122 %1 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)123 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %1, <4 x float> %y)124 ret <4 x float> %2125}126 127; copysign(fneg(x), y) -> copysign(x, y)128define <4 x float> @combine_vec_fcopysign_fneg_mag(<4 x float> %x, <4 x float> %y) {129; SSE-LABEL: combine_vec_fcopysign_fneg_mag:130; SSE: # %bb.0:131; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1132; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0133; SSE-NEXT: orps %xmm1, %xmm0134; SSE-NEXT: retq135;136; AVX-LABEL: combine_vec_fcopysign_fneg_mag:137; AVX: # %bb.0:138; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]139; AVX-NEXT: vandps %xmm2, %xmm1, %xmm1140; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]141; AVX-NEXT: vandps %xmm2, %xmm0, %xmm0142; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0143; AVX-NEXT: retq144 %1 = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %x145 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %1, <4 x float> %y)146 ret <4 x float> %2147}148 149; copysign(copysign(x,z), y) -> copysign(x, y)150define <4 x float> @combine_vec_fcopysign_fcopysign_mag(<4 x float> %x, <4 x float> %y, <4 x float> %z) {151; SSE-LABEL: combine_vec_fcopysign_fcopysign_mag:152; SSE: # %bb.0:153; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1154; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0155; SSE-NEXT: orps %xmm1, %xmm0156; SSE-NEXT: retq157;158; AVX-LABEL: combine_vec_fcopysign_fcopysign_mag:159; AVX: # %bb.0:160; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]161; AVX-NEXT: vandps %xmm2, %xmm1, %xmm1162; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]163; AVX-NEXT: vandps %xmm2, %xmm0, %xmm0164; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0165; AVX-NEXT: retq166 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> %z)167 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %1, <4 x float> %y)168 ret <4 x float> %2169}170 171; copysign(x, copysign(y,z)) -> copysign(x, z)172define <4 x float> @combine_vec_fcopysign_fcopysign_sgn(<4 x float> %x, <4 x float> %y, <4 x float> %z) {173; SSE-LABEL: combine_vec_fcopysign_fcopysign_sgn:174; SSE: # %bb.0:175; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2176; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0177; SSE-NEXT: orps %xmm2, %xmm0178; SSE-NEXT: retq179;180; AVX-LABEL: combine_vec_fcopysign_fcopysign_sgn:181; AVX: # %bb.0:182; AVX-NEXT: vbroadcastss {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]183; AVX-NEXT: vandps %xmm1, %xmm2, %xmm1184; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]185; AVX-NEXT: vandps %xmm2, %xmm0, %xmm0186; AVX-NEXT: vorps %xmm1, %xmm0, %xmm0187; AVX-NEXT: retq188 %1 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %y, <4 x float> %z)189 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> %1)190 ret <4 x float> %2191}192 193; copysign(x, fp_extend(y)) -> copysign(x, y)194define <4 x double> @combine_vec_fcopysign_fpext_sgn(<4 x double> %x, <4 x float> %y) {195; SSE-LABEL: combine_vec_fcopysign_fpext_sgn:196; SSE: # %bb.0:197; SSE-NEXT: cvtps2pd %xmm2, %xmm3198; SSE-NEXT: movhlps {{.*#+}} xmm2 = xmm2[1,1]199; SSE-NEXT: cvtps2pd %xmm2, %xmm2200; SSE-NEXT: movaps {{.*#+}} xmm4 = [NaN,NaN]201; SSE-NEXT: andps %xmm4, %xmm0202; SSE-NEXT: movaps %xmm4, %xmm5203; SSE-NEXT: andnps %xmm3, %xmm5204; SSE-NEXT: orps %xmm5, %xmm0205; SSE-NEXT: andps %xmm4, %xmm1206; SSE-NEXT: andnps %xmm2, %xmm4207; SSE-NEXT: orps %xmm4, %xmm1208; SSE-NEXT: retq209;210; AVX-LABEL: combine_vec_fcopysign_fpext_sgn:211; AVX: # %bb.0:212; AVX-NEXT: vcvtps2pd %xmm1, %ymm1213; AVX-NEXT: vbroadcastsd {{.*#+}} ymm2 = [NaN,NaN,NaN,NaN]214; AVX-NEXT: vandps %ymm2, %ymm0, %ymm0215; AVX-NEXT: vbroadcastsd {{.*#+}} ymm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]216; AVX-NEXT: vandps %ymm2, %ymm1, %ymm1217; AVX-NEXT: vorps %ymm1, %ymm0, %ymm0218; AVX-NEXT: retq219 %1 = fpext <4 x float> %y to <4 x double>220 %2 = call <4 x double> @llvm.copysign.v4f64(<4 x double> %x, <4 x double> %1)221 ret <4 x double> %2222}223 224; copysign(x, fp_round(y)) -> copysign(x, y)225define <4 x float> @combine_vec_fcopysign_fptrunc_sgn(<4 x float> %x, <4 x double> %y) {226; SSE-LABEL: combine_vec_fcopysign_fptrunc_sgn:227; SSE: # %bb.0:228; SSE-NEXT: cvtpd2ps %xmm2, %xmm2229; SSE-NEXT: cvtpd2ps %xmm1, %xmm1230; SSE-NEXT: unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0]231; SSE-NEXT: andpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1232; SSE-NEXT: andpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0233; SSE-NEXT: orpd %xmm1, %xmm0234; SSE-NEXT: retq235;236; AVX-LABEL: combine_vec_fcopysign_fptrunc_sgn:237; AVX: # %bb.0:238; AVX-NEXT: vcvtpd2ps %ymm1, %xmm1239; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]240; AVX-NEXT: vandpd %xmm2, %xmm0, %xmm0241; AVX-NEXT: vbroadcastss {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]242; AVX-NEXT: vandpd %xmm2, %xmm1, %xmm1243; AVX-NEXT: vorpd %xmm1, %xmm0, %xmm0244; AVX-NEXT: vzeroupper245; AVX-NEXT: retq246 %1 = fptrunc <4 x double> %y to <4 x float>247 %2 = call <4 x float> @llvm.copysign.v4f32(<4 x float> %x, <4 x float> %1)248 ret <4 x float> %2249}250 251define double @PR136368(double %x) {252; SSE-LABEL: PR136368:253; SSE: # %bb.0:254; SSE-NEXT: movapd {{.*#+}} xmm1 = [NaN,NaN]255; SSE-NEXT: movapd %xmm0, %xmm2256; SSE-NEXT: andpd %xmm1, %xmm2257; SSE-NEXT: movsd {{.*#+}} xmm3 = [1.5707963267948966E+0,0.0E+0]258; SSE-NEXT: movapd %xmm3, %xmm4259; SSE-NEXT: cmpltsd %xmm2, %xmm4260; SSE-NEXT: andpd %xmm3, %xmm4261; SSE-NEXT: andpd %xmm1, %xmm4262; SSE-NEXT: andnpd %xmm0, %xmm1263; SSE-NEXT: orpd %xmm4, %xmm1264; SSE-NEXT: movapd %xmm1, %xmm0265; SSE-NEXT: retq266;267; AVX-LABEL: PR136368:268; AVX: # %bb.0:269; AVX-NEXT: vmovddup {{.*#+}} xmm1 = [NaN,NaN]270; AVX-NEXT: # xmm1 = mem[0,0]271; AVX-NEXT: vandpd %xmm1, %xmm0, %xmm2272; AVX-NEXT: vmovsd {{.*#+}} xmm3 = [1.5707963267948966E+0,0.0E+0]273; AVX-NEXT: vcmpltsd %xmm2, %xmm3, %xmm2274; AVX-NEXT: vandpd %xmm3, %xmm2, %xmm2275; AVX-NEXT: vandnpd %xmm0, %xmm1, %xmm0276; AVX-NEXT: vandpd %xmm1, %xmm2, %xmm1277; AVX-NEXT: vorpd %xmm0, %xmm1, %xmm0278; AVX-NEXT: retq279 %fabs = tail call double @llvm.fabs.f64(double %x)280 %cmp = fcmp ogt double %fabs, 0x3FF921FB54442D18281 %cond = select i1 %cmp, double 0x3FF921FB54442D18, double 0.000000e+00282 %res = tail call double @llvm.copysign.f64(double %cond, double %x)283 ret double %res284}285 286declare <4 x float> @llvm.fabs.v4f32(<4 x float> %p)287declare <4 x float> @llvm.copysign.v4f32(<4 x float> %Mag, <4 x float> %Sgn)288declare <4 x double> @llvm.copysign.v4f64(<4 x double> %Mag, <4 x double> %Sgn)289