367 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512bw | FileCheck %s --check-prefixes=AVX512,AVX512BW3; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512dq | FileCheck %s --check-prefixes=AVX512,AVX512DQ4 5;6; trunc(abs(sub(zext(a),zext(b)))) -> abdu(a,b)7;8 9define <64 x i8> @abd_ext_v64i8(<64 x i8> %a, <64 x i8> %b) nounwind {10; AVX512BW-LABEL: abd_ext_v64i8:11; AVX512BW: # %bb.0:12; AVX512BW-NEXT: vpminub %zmm1, %zmm0, %zmm213; AVX512BW-NEXT: vpmaxub %zmm1, %zmm0, %zmm014; AVX512BW-NEXT: vpsubb %zmm2, %zmm0, %zmm015; AVX512BW-NEXT: retq16;17; AVX512DQ-LABEL: abd_ext_v64i8:18; AVX512DQ: # %bb.0:19; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm220; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm321; AVX512DQ-NEXT: vpminub %ymm2, %ymm3, %ymm422; AVX512DQ-NEXT: vpmaxub %ymm2, %ymm3, %ymm223; AVX512DQ-NEXT: vpsubb %ymm4, %ymm2, %ymm224; AVX512DQ-NEXT: vpminub %ymm1, %ymm0, %ymm325; AVX512DQ-NEXT: vpmaxub %ymm1, %ymm0, %ymm026; AVX512DQ-NEXT: vpsubb %ymm3, %ymm0, %ymm027; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm028; AVX512DQ-NEXT: retq29 %aext = zext <64 x i8> %a to <64 x i64>30 %bext = zext <64 x i8> %b to <64 x i64>31 %sub = sub <64 x i64> %aext, %bext32 %abs = call <64 x i64> @llvm.abs.v64i64(<64 x i64> %sub, i1 false)33 %trunc = trunc <64 x i64> %abs to <64 x i8>34 ret <64 x i8> %trunc35}36 37define <64 x i8> @abd_ext_v64i8_undef(<64 x i8> %a, <64 x i8> %b) nounwind {38; AVX512BW-LABEL: abd_ext_v64i8_undef:39; AVX512BW: # %bb.0:40; AVX512BW-NEXT: vpminub %zmm1, %zmm0, %zmm241; AVX512BW-NEXT: vpmaxub %zmm1, %zmm0, %zmm042; AVX512BW-NEXT: vpsubb %zmm2, %zmm0, %zmm043; AVX512BW-NEXT: retq44;45; AVX512DQ-LABEL: abd_ext_v64i8_undef:46; AVX512DQ: # %bb.0:47; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm248; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm349; AVX512DQ-NEXT: vpminub %ymm2, %ymm3, %ymm450; AVX512DQ-NEXT: vpmaxub %ymm2, %ymm3, %ymm251; AVX512DQ-NEXT: vpsubb %ymm4, %ymm2, %ymm252; AVX512DQ-NEXT: vpminub %ymm1, %ymm0, %ymm353; AVX512DQ-NEXT: vpmaxub %ymm1, %ymm0, %ymm054; AVX512DQ-NEXT: vpsubb %ymm3, %ymm0, %ymm055; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm056; AVX512DQ-NEXT: retq57 %aext = zext <64 x i8> %a to <64 x i64>58 %bext = zext <64 x i8> %b to <64 x i64>59 %sub = sub <64 x i64> %aext, %bext60 %abs = call <64 x i64> @llvm.abs.v64i64(<64 x i64> %sub, i1 true)61 %trunc = trunc <64 x i64> %abs to <64 x i8>62 ret <64 x i8> %trunc63}64 65define <32 x i16> @abd_ext_v32i16(<32 x i16> %a, <32 x i16> %b) nounwind {66; AVX512BW-LABEL: abd_ext_v32i16:67; AVX512BW: # %bb.0:68; AVX512BW-NEXT: vpminuw %zmm1, %zmm0, %zmm269; AVX512BW-NEXT: vpmaxuw %zmm1, %zmm0, %zmm070; AVX512BW-NEXT: vpsubw %zmm2, %zmm0, %zmm071; AVX512BW-NEXT: retq72;73; AVX512DQ-LABEL: abd_ext_v32i16:74; AVX512DQ: # %bb.0:75; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm276; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm377; AVX512DQ-NEXT: vpminuw %ymm2, %ymm3, %ymm478; AVX512DQ-NEXT: vpmaxuw %ymm2, %ymm3, %ymm279; AVX512DQ-NEXT: vpsubw %ymm4, %ymm2, %ymm280; AVX512DQ-NEXT: vpminuw %ymm1, %ymm0, %ymm381; AVX512DQ-NEXT: vpmaxuw %ymm1, %ymm0, %ymm082; AVX512DQ-NEXT: vpsubw %ymm3, %ymm0, %ymm083; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm084; AVX512DQ-NEXT: retq85 %aext = zext <32 x i16> %a to <32 x i64>86 %bext = zext <32 x i16> %b to <32 x i64>87 %sub = sub <32 x i64> %aext, %bext88 %abs = call <32 x i64> @llvm.abs.v32i64(<32 x i64> %sub, i1 false)89 %trunc = trunc <32 x i64> %abs to <32 x i16>90 ret <32 x i16> %trunc91}92 93define <32 x i16> @abd_ext_v32i16_undef(<32 x i16> %a, <32 x i16> %b) nounwind {94; AVX512BW-LABEL: abd_ext_v32i16_undef:95; AVX512BW: # %bb.0:96; AVX512BW-NEXT: vpminuw %zmm1, %zmm0, %zmm297; AVX512BW-NEXT: vpmaxuw %zmm1, %zmm0, %zmm098; AVX512BW-NEXT: vpsubw %zmm2, %zmm0, %zmm099; AVX512BW-NEXT: retq100;101; AVX512DQ-LABEL: abd_ext_v32i16_undef:102; AVX512DQ: # %bb.0:103; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm2104; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm3105; AVX512DQ-NEXT: vpminuw %ymm2, %ymm3, %ymm4106; AVX512DQ-NEXT: vpmaxuw %ymm2, %ymm3, %ymm2107; AVX512DQ-NEXT: vpsubw %ymm4, %ymm2, %ymm2108; AVX512DQ-NEXT: vpminuw %ymm1, %ymm0, %ymm3109; AVX512DQ-NEXT: vpmaxuw %ymm1, %ymm0, %ymm0110; AVX512DQ-NEXT: vpsubw %ymm3, %ymm0, %ymm0111; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0112; AVX512DQ-NEXT: retq113 %aext = zext <32 x i16> %a to <32 x i64>114 %bext = zext <32 x i16> %b to <32 x i64>115 %sub = sub <32 x i64> %aext, %bext116 %abs = call <32 x i64> @llvm.abs.v32i64(<32 x i64> %sub, i1 true)117 %trunc = trunc <32 x i64> %abs to <32 x i16>118 ret <32 x i16> %trunc119}120 121define <16 x i32> @abd_ext_v16i32(<16 x i32> %a, <16 x i32> %b) nounwind {122; AVX512-LABEL: abd_ext_v16i32:123; AVX512: # %bb.0:124; AVX512-NEXT: vpminud %zmm1, %zmm0, %zmm2125; AVX512-NEXT: vpmaxud %zmm1, %zmm0, %zmm0126; AVX512-NEXT: vpsubd %zmm2, %zmm0, %zmm0127; AVX512-NEXT: retq128 %aext = zext <16 x i32> %a to <16 x i64>129 %bext = zext <16 x i32> %b to <16 x i64>130 %sub = sub <16 x i64> %aext, %bext131 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 false)132 %trunc = trunc <16 x i64> %abs to <16 x i32>133 ret <16 x i32> %trunc134}135 136define <16 x i32> @abd_ext_v16i32_undef(<16 x i32> %a, <16 x i32> %b) nounwind {137; AVX512-LABEL: abd_ext_v16i32_undef:138; AVX512: # %bb.0:139; AVX512-NEXT: vpminud %zmm1, %zmm0, %zmm2140; AVX512-NEXT: vpmaxud %zmm1, %zmm0, %zmm0141; AVX512-NEXT: vpsubd %zmm2, %zmm0, %zmm0142; AVX512-NEXT: retq143 %aext = zext <16 x i32> %a to <16 x i64>144 %bext = zext <16 x i32> %b to <16 x i64>145 %sub = sub <16 x i64> %aext, %bext146 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 true)147 %trunc = trunc <16 x i64> %abs to <16 x i32>148 ret <16 x i32> %trunc149}150 151define <8 x i64> @abd_ext_v8i64(<8 x i64> %a, <8 x i64> %b) nounwind {152; AVX512-LABEL: abd_ext_v8i64:153; AVX512: # %bb.0:154; AVX512-NEXT: vpminuq %zmm1, %zmm0, %zmm2155; AVX512-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0156; AVX512-NEXT: vpsubq %zmm2, %zmm0, %zmm0157; AVX512-NEXT: retq158 %aext = zext <8 x i64> %a to <8 x i128>159 %bext = zext <8 x i64> %b to <8 x i128>160 %sub = sub <8 x i128> %aext, %bext161 %abs = call <8 x i128> @llvm.abs.v8i128(<8 x i128> %sub, i1 false)162 %trunc = trunc <8 x i128> %abs to <8 x i64>163 ret <8 x i64> %trunc164}165 166define <8 x i64> @abd_ext_v8i64_undef(<8 x i64> %a, <8 x i64> %b) nounwind {167; AVX512-LABEL: abd_ext_v8i64_undef:168; AVX512: # %bb.0:169; AVX512-NEXT: vpminuq %zmm1, %zmm0, %zmm2170; AVX512-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0171; AVX512-NEXT: vpsubq %zmm2, %zmm0, %zmm0172; AVX512-NEXT: retq173 %aext = zext <8 x i64> %a to <8 x i128>174 %bext = zext <8 x i64> %b to <8 x i128>175 %sub = sub <8 x i128> %aext, %bext176 %abs = call <8 x i128> @llvm.abs.v8i128(<8 x i128> %sub, i1 true)177 %trunc = trunc <8 x i128> %abs to <8 x i64>178 ret <8 x i64> %trunc179}180 181;182; sub(umax(a,b),umin(a,b)) -> abdu(a,b)183;184 185define <64 x i8> @abd_minmax_v64i8(<64 x i8> %a, <64 x i8> %b) nounwind {186; AVX512BW-LABEL: abd_minmax_v64i8:187; AVX512BW: # %bb.0:188; AVX512BW-NEXT: vpminub %zmm1, %zmm0, %zmm2189; AVX512BW-NEXT: vpmaxub %zmm1, %zmm0, %zmm0190; AVX512BW-NEXT: vpsubb %zmm2, %zmm0, %zmm0191; AVX512BW-NEXT: retq192;193; AVX512DQ-LABEL: abd_minmax_v64i8:194; AVX512DQ: # %bb.0:195; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm2196; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm3197; AVX512DQ-NEXT: vpminub %ymm2, %ymm3, %ymm4198; AVX512DQ-NEXT: vpmaxub %ymm2, %ymm3, %ymm2199; AVX512DQ-NEXT: vpsubb %ymm4, %ymm2, %ymm2200; AVX512DQ-NEXT: vpminub %ymm1, %ymm0, %ymm3201; AVX512DQ-NEXT: vpmaxub %ymm1, %ymm0, %ymm0202; AVX512DQ-NEXT: vpsubb %ymm3, %ymm0, %ymm0203; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0204; AVX512DQ-NEXT: retq205 %min = call <64 x i8> @llvm.umin.v64i8(<64 x i8> %a, <64 x i8> %b)206 %max = call <64 x i8> @llvm.umax.v64i8(<64 x i8> %a, <64 x i8> %b)207 %sub = sub <64 x i8> %max, %min208 ret <64 x i8> %sub209}210 211define <32 x i16> @abd_minmax_v32i16(<32 x i16> %a, <32 x i16> %b) nounwind {212; AVX512BW-LABEL: abd_minmax_v32i16:213; AVX512BW: # %bb.0:214; AVX512BW-NEXT: vpminuw %zmm1, %zmm0, %zmm2215; AVX512BW-NEXT: vpmaxuw %zmm1, %zmm0, %zmm0216; AVX512BW-NEXT: vpsubw %zmm2, %zmm0, %zmm0217; AVX512BW-NEXT: retq218;219; AVX512DQ-LABEL: abd_minmax_v32i16:220; AVX512DQ: # %bb.0:221; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm2222; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm3223; AVX512DQ-NEXT: vpminuw %ymm2, %ymm3, %ymm4224; AVX512DQ-NEXT: vpmaxuw %ymm2, %ymm3, %ymm2225; AVX512DQ-NEXT: vpsubw %ymm4, %ymm2, %ymm2226; AVX512DQ-NEXT: vpminuw %ymm1, %ymm0, %ymm3227; AVX512DQ-NEXT: vpmaxuw %ymm1, %ymm0, %ymm0228; AVX512DQ-NEXT: vpsubw %ymm3, %ymm0, %ymm0229; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0230; AVX512DQ-NEXT: retq231 %min = call <32 x i16> @llvm.umin.v32i16(<32 x i16> %a, <32 x i16> %b)232 %max = call <32 x i16> @llvm.umax.v32i16(<32 x i16> %a, <32 x i16> %b)233 %sub = sub <32 x i16> %max, %min234 ret <32 x i16> %sub235}236 237define <16 x i32> @abd_minmax_v16i32(<16 x i32> %a, <16 x i32> %b) nounwind {238; AVX512-LABEL: abd_minmax_v16i32:239; AVX512: # %bb.0:240; AVX512-NEXT: vpminud %zmm1, %zmm0, %zmm2241; AVX512-NEXT: vpmaxud %zmm1, %zmm0, %zmm0242; AVX512-NEXT: vpsubd %zmm2, %zmm0, %zmm0243; AVX512-NEXT: retq244 %min = call <16 x i32> @llvm.umin.v16i32(<16 x i32> %a, <16 x i32> %b)245 %max = call <16 x i32> @llvm.umax.v16i32(<16 x i32> %a, <16 x i32> %b)246 %sub = sub <16 x i32> %max, %min247 ret <16 x i32> %sub248}249 250define <8 x i64> @abd_minmax_v8i64(<8 x i64> %a, <8 x i64> %b) nounwind {251; AVX512-LABEL: abd_minmax_v8i64:252; AVX512: # %bb.0:253; AVX512-NEXT: vpminuq %zmm1, %zmm0, %zmm2254; AVX512-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0255; AVX512-NEXT: vpsubq %zmm2, %zmm0, %zmm0256; AVX512-NEXT: retq257 %min = call <8 x i64> @llvm.umin.v8i64(<8 x i64> %a, <8 x i64> %b)258 %max = call <8 x i64> @llvm.umax.v8i64(<8 x i64> %a, <8 x i64> %b)259 %sub = sub <8 x i64> %max, %min260 ret <8 x i64> %sub261}262 263;264; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)265;266 267define <64 x i8> @abd_cmp_v64i8(<64 x i8> %a, <64 x i8> %b) nounwind {268; AVX512BW-LABEL: abd_cmp_v64i8:269; AVX512BW: # %bb.0:270; AVX512BW-NEXT: vpminub %zmm1, %zmm0, %zmm2271; AVX512BW-NEXT: vpmaxub %zmm1, %zmm0, %zmm0272; AVX512BW-NEXT: vpsubb %zmm2, %zmm0, %zmm0273; AVX512BW-NEXT: retq274;275; AVX512DQ-LABEL: abd_cmp_v64i8:276; AVX512DQ: # %bb.0:277; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm2278; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm3279; AVX512DQ-NEXT: vpminub %ymm2, %ymm3, %ymm4280; AVX512DQ-NEXT: vpmaxub %ymm2, %ymm3, %ymm2281; AVX512DQ-NEXT: vpsubb %ymm4, %ymm2, %ymm2282; AVX512DQ-NEXT: vpminub %ymm1, %ymm0, %ymm3283; AVX512DQ-NEXT: vpmaxub %ymm1, %ymm0, %ymm0284; AVX512DQ-NEXT: vpsubb %ymm3, %ymm0, %ymm0285; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0286; AVX512DQ-NEXT: retq287 %cmp = icmp ugt <64 x i8> %a, %b288 %ab = sub <64 x i8> %a, %b289 %ba = sub <64 x i8> %b, %a290 %sel = select <64 x i1> %cmp, <64 x i8> %ab, <64 x i8> %ba291 ret <64 x i8> %sel292}293 294define <32 x i16> @abd_cmp_v32i16(<32 x i16> %a, <32 x i16> %b) nounwind {295; AVX512BW-LABEL: abd_cmp_v32i16:296; AVX512BW: # %bb.0:297; AVX512BW-NEXT: vpminuw %zmm1, %zmm0, %zmm2298; AVX512BW-NEXT: vpmaxuw %zmm1, %zmm0, %zmm0299; AVX512BW-NEXT: vpsubw %zmm2, %zmm0, %zmm0300; AVX512BW-NEXT: retq301;302; AVX512DQ-LABEL: abd_cmp_v32i16:303; AVX512DQ: # %bb.0:304; AVX512DQ-NEXT: vextracti64x4 $1, %zmm1, %ymm2305; AVX512DQ-NEXT: vextracti64x4 $1, %zmm0, %ymm3306; AVX512DQ-NEXT: vpminuw %ymm2, %ymm3, %ymm4307; AVX512DQ-NEXT: vpmaxuw %ymm2, %ymm3, %ymm2308; AVX512DQ-NEXT: vpsubw %ymm4, %ymm2, %ymm2309; AVX512DQ-NEXT: vpminuw %ymm1, %ymm0, %ymm3310; AVX512DQ-NEXT: vpmaxuw %ymm1, %ymm0, %ymm0311; AVX512DQ-NEXT: vpsubw %ymm3, %ymm0, %ymm0312; AVX512DQ-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0313; AVX512DQ-NEXT: retq314 %cmp = icmp uge <32 x i16> %a, %b315 %ab = sub <32 x i16> %a, %b316 %ba = sub <32 x i16> %b, %a317 %sel = select <32 x i1> %cmp, <32 x i16> %ab, <32 x i16> %ba318 ret <32 x i16> %sel319}320 321define <16 x i32> @abd_cmp_v16i32(<16 x i32> %a, <16 x i32> %b) nounwind {322; AVX512-LABEL: abd_cmp_v16i32:323; AVX512: # %bb.0:324; AVX512-NEXT: vpminud %zmm1, %zmm0, %zmm2325; AVX512-NEXT: vpmaxud %zmm1, %zmm0, %zmm0326; AVX512-NEXT: vpsubd %zmm2, %zmm0, %zmm0327; AVX512-NEXT: retq328 %cmp = icmp ult <16 x i32> %a, %b329 %ab = sub <16 x i32> %a, %b330 %ba = sub <16 x i32> %b, %a331 %sel = select <16 x i1> %cmp, <16 x i32> %ba, <16 x i32> %ab332 ret <16 x i32> %sel333}334 335define <8 x i64> @abd_cmp_v8i64(<8 x i64> %a, <8 x i64> %b) nounwind {336; AVX512-LABEL: abd_cmp_v8i64:337; AVX512: # %bb.0:338; AVX512-NEXT: vpminuq %zmm1, %zmm0, %zmm2339; AVX512-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0340; AVX512-NEXT: vpsubq %zmm2, %zmm0, %zmm0341; AVX512-NEXT: retq342 %cmp = icmp uge <8 x i64> %a, %b343 %ab = sub <8 x i64> %a, %b344 %ba = sub <8 x i64> %b, %a345 %sel = select <8 x i1> %cmp, <8 x i64> %ab, <8 x i64> %ba346 ret <8 x i64> %sel347}348 349declare <64 x i8> @llvm.abs.v64i8(<64 x i8>, i1)350declare <32 x i16> @llvm.abs.v32i16(<32 x i16>, i1)351declare <16 x i32> @llvm.abs.v16i32(<16 x i32>, i1)352declare <8 x i64> @llvm.abs.v8i64(<8 x i64>, i1)353declare <16 x i64> @llvm.abs.v16i64(<16 x i64>, i1)354declare <32 x i64> @llvm.abs.v32i64(<32 x i64>, i1)355declare <64 x i64> @llvm.abs.v64i64(<64 x i64>, i1)356declare <8 x i128> @llvm.abs.v8i128(<8 x i128>, i1)357 358declare <64 x i8> @llvm.umax.v64i8(<64 x i8>, <64 x i8>)359declare <32 x i16> @llvm.umax.v32i16(<32 x i16>, <32 x i16>)360declare <16 x i32> @llvm.umax.v16i32(<16 x i32>, <16 x i32>)361declare <8 x i64> @llvm.umax.v8i64(<8 x i64>, <8 x i64>)362 363declare <64 x i8> @llvm.umin.v64i8(<64 x i8>, <64 x i8>)364declare <32 x i16> @llvm.umin.v32i16(<32 x i16>, <32 x i16>)365declare <16 x i32> @llvm.umin.v16i32(<16 x i32>, <16 x i32>)366declare <8 x i64> @llvm.umin.v8i64(<8 x i64>, <8 x i64>)367