1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE2 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefixes=SSE,SSSE3 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE41 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1 6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2 7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512F 8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+fast-variable-perlane-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512F 9; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512BW 10; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-perlane-shuffle | FileCheck %s --check-prefixes=AVX,AVX512,AVX512BW 11 12declare <1 x i8> @llvm.usub.sat.v1i8(<1 x i8>, <1 x i8>) 13declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>) 14declare <4 x i8> @llvm.usub.sat.v4i8(<4 x i8>, <4 x i8>) 15declare <8 x i8> @llvm.usub.sat.v8i8(<8 x i8>, <8 x i8>) 16declare <12 x i8> @llvm.usub.sat.v12i8(<12 x i8>, <12 x i8>) 17declare <16 x i8> @llvm.usub.sat.v16i8(<16 x i8>, <16 x i8>) 18declare <32 x i8> @llvm.usub.sat.v32i8(<32 x i8>, <32 x i8>) 19declare <64 x i8> @llvm.usub.sat.v64i8(<64 x i8>, <64 x i8>) 20 21declare <1 x i16> @llvm.usub.sat.v1i16(<1 x i16>, <1 x i16>) 22declare <2 x i16> @llvm.usub.sat.v2i16(<2 x i16>, <2 x i16>) 23declare <4 x i16> @llvm.usub.sat.v4i16(<4 x i16>, <4 x i16>) 24declare <8 x i16> @llvm.usub.sat.v8i16(<8 x i16>, <8 x i16>) 25declare <12 x i16> @llvm.usub.sat.v12i16(<12 x i16>, <12 x i16>) 26declare <16 x i16> @llvm.usub.sat.v16i16(<16 x i16>, <16 x i16>) 27declare <32 x i16> @llvm.usub.sat.v32i16(<32 x i16>, <32 x i16>) 28 29declare <16 x i1> @llvm.usub.sat.v16i1(<16 x i1>, <16 x i1>) 30declare <16 x i4> @llvm.usub.sat.v16i4(<16 x i4>, <16 x i4>) 31 32declare <2 x i32> @llvm.usub.sat.v2i32(<2 x i32>, <2 x i32>) 33declare <4 x i32> @llvm.usub.sat.v4i32(<4 x i32>, <4 x i32>) 34declare <8 x i32> @llvm.usub.sat.v8i32(<8 x i32>, <8 x i32>) 35declare <16 x i32> @llvm.usub.sat.v16i32(<16 x i32>, <16 x i32>) 36declare <2 x i64> @llvm.usub.sat.v2i64(<2 x i64>, <2 x i64>) 37declare <4 x i64> @llvm.usub.sat.v4i64(<4 x i64>, <4 x i64>) 38declare <8 x i64> @llvm.usub.sat.v8i64(<8 x i64>, <8 x i64>) 39 40declare <4 x i24> @llvm.usub.sat.v4i24(<4 x i24>, <4 x i24>) 41declare <2 x i128> @llvm.usub.sat.v2i128(<2 x i128>, <2 x i128>) 42 43; Legal types, depending on architecture. 44 45define <16 x i8> @v16i8(<16 x i8> %x, <16 x i8> %y) nounwind { 46; SSE-LABEL: v16i8: 47; SSE: # %bb.0: 48; SSE-NEXT: psubusb %xmm1, %xmm0 49; SSE-NEXT: retq 50; 51; AVX-LABEL: v16i8: 52; AVX: # %bb.0: 53; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 54; AVX-NEXT: retq 55 %z = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %x, <16 x i8> %y) 56 ret <16 x i8> %z 57} 58 59define <32 x i8> @v32i8(<32 x i8> %x, <32 x i8> %y) nounwind { 60; SSE-LABEL: v32i8: 61; SSE: # %bb.0: 62; SSE-NEXT: psubusb %xmm2, %xmm0 63; SSE-NEXT: psubusb %xmm3, %xmm1 64; SSE-NEXT: retq 65; 66; AVX1-LABEL: v32i8: 67; AVX1: # %bb.0: 68; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 69; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 70; AVX1-NEXT: vpsubusb %xmm2, %xmm3, %xmm2 71; AVX1-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 72; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 73; AVX1-NEXT: retq 74; 75; AVX2-LABEL: v32i8: 76; AVX2: # %bb.0: 77; AVX2-NEXT: vpsubusb %ymm1, %ymm0, %ymm0 78; AVX2-NEXT: retq 79; 80; AVX512-LABEL: v32i8: 81; AVX512: # %bb.0: 82; AVX512-NEXT: vpsubusb %ymm1, %ymm0, %ymm0 83; AVX512-NEXT: retq 84 %z = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %x, <32 x i8> %y) 85 ret <32 x i8> %z 86} 87 88define <64 x i8> @v64i8(<64 x i8> %x, <64 x i8> %y) nounwind { 89; SSE-LABEL: v64i8: 90; SSE: # %bb.0: 91; SSE-NEXT: psubusb %xmm4, %xmm0 92; SSE-NEXT: psubusb %xmm5, %xmm1 93; SSE-NEXT: psubusb %xmm6, %xmm2 94; SSE-NEXT: psubusb %xmm7, %xmm3 95; SSE-NEXT: retq 96; 97; AVX1-LABEL: v64i8: 98; AVX1: # %bb.0: 99; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 100; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 101; AVX1-NEXT: vpsubusb %xmm4, %xmm5, %xmm4 102; AVX1-NEXT: vpsubusb %xmm2, %xmm0, %xmm0 103; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 104; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 105; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 106; AVX1-NEXT: vpsubusb %xmm2, %xmm4, %xmm2 107; AVX1-NEXT: vpsubusb %xmm3, %xmm1, %xmm1 108; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 109; AVX1-NEXT: retq 110; 111; AVX2-LABEL: v64i8: 112; AVX2: # %bb.0: 113; AVX2-NEXT: vpsubusb %ymm2, %ymm0, %ymm0 114; AVX2-NEXT: vpsubusb %ymm3, %ymm1, %ymm1 115; AVX2-NEXT: retq 116; 117; AVX512F-LABEL: v64i8: 118; AVX512F: # %bb.0: 119; AVX512F-NEXT: vextracti64x4 $1, %zmm1, %ymm2 120; AVX512F-NEXT: vextracti64x4 $1, %zmm0, %ymm3 121; AVX512F-NEXT: vpsubusb %ymm2, %ymm3, %ymm2 122; AVX512F-NEXT: vpsubusb %ymm1, %ymm0, %ymm0 123; AVX512F-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0 124; AVX512F-NEXT: retq 125; 126; AVX512BW-LABEL: v64i8: 127; AVX512BW: # %bb.0: 128; AVX512BW-NEXT: vpsubusb %zmm1, %zmm0, %zmm0 129; AVX512BW-NEXT: retq 130 %z = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %x, <64 x i8> %y) 131 ret <64 x i8> %z 132} 133 134define <8 x i16> @v8i16(<8 x i16> %x, <8 x i16> %y) nounwind { 135; SSE-LABEL: v8i16: 136; SSE: # %bb.0: 137; SSE-NEXT: psubusw %xmm1, %xmm0 138; SSE-NEXT: retq 139; 140; AVX-LABEL: v8i16: 141; AVX: # %bb.0: 142; AVX-NEXT: vpsubusw %xmm1, %xmm0, %xmm0 143; AVX-NEXT: retq 144 %z = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %x, <8 x i16> %y) 145 ret <8 x i16> %z 146} 147 148define <16 x i16> @v16i16(<16 x i16> %x, <16 x i16> %y) nounwind { 149; SSE-LABEL: v16i16: 150; SSE: # %bb.0: 151; SSE-NEXT: psubusw %xmm2, %xmm0 152; SSE-NEXT: psubusw %xmm3, %xmm1 153; SSE-NEXT: retq 154; 155; AVX1-LABEL: v16i16: 156; AVX1: # %bb.0: 157; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 158; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 159; AVX1-NEXT: vpsubusw %xmm2, %xmm3, %xmm2 160; AVX1-NEXT: vpsubusw %xmm1, %xmm0, %xmm0 161; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 162; AVX1-NEXT: retq 163; 164; AVX2-LABEL: v16i16: 165; AVX2: # %bb.0: 166; AVX2-NEXT: vpsubusw %ymm1, %ymm0, %ymm0 167; AVX2-NEXT: retq 168; 169; AVX512-LABEL: v16i16: 170; AVX512: # %bb.0: 171; AVX512-NEXT: vpsubusw %ymm1, %ymm0, %ymm0 172; AVX512-NEXT: retq 173 %z = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %x, <16 x i16> %y) 174 ret <16 x i16> %z 175} 176 177define <32 x i16> @v32i16(<32 x i16> %x, <32 x i16> %y) nounwind { 178; SSE-LABEL: v32i16: 179; SSE: # %bb.0: 180; SSE-NEXT: psubusw %xmm4, %xmm0 181; SSE-NEXT: psubusw %xmm5, %xmm1 182; SSE-NEXT: psubusw %xmm6, %xmm2 183; SSE-NEXT: psubusw %xmm7, %xmm3 184; SSE-NEXT: retq 185; 186; AVX1-LABEL: v32i16: 187; AVX1: # %bb.0: 188; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 189; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 190; AVX1-NEXT: vpsubusw %xmm4, %xmm5, %xmm4 191; AVX1-NEXT: vpsubusw %xmm2, %xmm0, %xmm0 192; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 193; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 194; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 195; AVX1-NEXT: vpsubusw %xmm2, %xmm4, %xmm2 196; AVX1-NEXT: vpsubusw %xmm3, %xmm1, %xmm1 197; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 198; AVX1-NEXT: retq 199; 200; AVX2-LABEL: v32i16: 201; AVX2: # %bb.0: 202; AVX2-NEXT: vpsubusw %ymm2, %ymm0, %ymm0 203; AVX2-NEXT: vpsubusw %ymm3, %ymm1, %ymm1 204; AVX2-NEXT: retq 205; 206; AVX512F-LABEL: v32i16: 207; AVX512F: # %bb.0: 208; AVX512F-NEXT: vextracti64x4 $1, %zmm1, %ymm2 209; AVX512F-NEXT: vextracti64x4 $1, %zmm0, %ymm3 210; AVX512F-NEXT: vpsubusw %ymm2, %ymm3, %ymm2 211; AVX512F-NEXT: vpsubusw %ymm1, %ymm0, %ymm0 212; AVX512F-NEXT: vinserti64x4 $1, %ymm2, %zmm0, %zmm0 213; AVX512F-NEXT: retq 214; 215; AVX512BW-LABEL: v32i16: 216; AVX512BW: # %bb.0: 217; AVX512BW-NEXT: vpsubusw %zmm1, %zmm0, %zmm0 218; AVX512BW-NEXT: retq 219 %z = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %x, <32 x i16> %y) 220 ret <32 x i16> %z 221} 222 223; Too narrow vectors, legalized by widening. 224 225define void @v8i8(ptr %px, ptr %py, ptr %pz) nounwind { 226; SSE-LABEL: v8i8: 227; SSE: # %bb.0: 228; SSE-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 229; SSE-NEXT: movq {{.*#+}} xmm1 = mem[0],zero 230; SSE-NEXT: psubusb %xmm1, %xmm0 231; SSE-NEXT: movq %xmm0, (%rdx) 232; SSE-NEXT: retq 233; 234; AVX-LABEL: v8i8: 235; AVX: # %bb.0: 236; AVX-NEXT: vmovq {{.*#+}} xmm0 = mem[0],zero 237; AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 238; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 239; AVX-NEXT: vmovq %xmm0, (%rdx) 240; AVX-NEXT: retq 241 %x = load <8 x i8>, ptr %px 242 %y = load <8 x i8>, ptr %py 243 %z = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %x, <8 x i8> %y) 244 store <8 x i8> %z, ptr %pz 245 ret void 246} 247 248define void @v4i8(ptr %px, ptr %py, ptr %pz) nounwind { 249; SSE-LABEL: v4i8: 250; SSE: # %bb.0: 251; SSE-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 252; SSE-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 253; SSE-NEXT: psubusb %xmm1, %xmm0 254; SSE-NEXT: movd %xmm0, (%rdx) 255; SSE-NEXT: retq 256; 257; AVX-LABEL: v4i8: 258; AVX: # %bb.0: 259; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 260; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 261; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 262; AVX-NEXT: vmovd %xmm0, (%rdx) 263; AVX-NEXT: retq 264 %x = load <4 x i8>, ptr %px 265 %y = load <4 x i8>, ptr %py 266 %z = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %x, <4 x i8> %y) 267 store <4 x i8> %z, ptr %pz 268 ret void 269} 270 271define void @v2i8(ptr %px, ptr %py, ptr %pz) nounwind { 272; SSE2-LABEL: v2i8: 273; SSE2: # %bb.0: 274; SSE2-NEXT: movzwl (%rdi), %eax 275; SSE2-NEXT: movd %eax, %xmm0 276; SSE2-NEXT: movzwl (%rsi), %eax 277; SSE2-NEXT: movd %eax, %xmm1 278; SSE2-NEXT: psubusb %xmm1, %xmm0 279; SSE2-NEXT: movd %xmm0, %eax 280; SSE2-NEXT: movw %ax, (%rdx) 281; SSE2-NEXT: retq 282; 283; SSSE3-LABEL: v2i8: 284; SSSE3: # %bb.0: 285; SSSE3-NEXT: movzwl (%rdi), %eax 286; SSSE3-NEXT: movd %eax, %xmm0 287; SSSE3-NEXT: movzwl (%rsi), %eax 288; SSSE3-NEXT: movd %eax, %xmm1 289; SSSE3-NEXT: psubusb %xmm1, %xmm0 290; SSSE3-NEXT: movd %xmm0, %eax 291; SSSE3-NEXT: movw %ax, (%rdx) 292; SSSE3-NEXT: retq 293; 294; SSE41-LABEL: v2i8: 295; SSE41: # %bb.0: 296; SSE41-NEXT: movzwl (%rdi), %eax 297; SSE41-NEXT: movd %eax, %xmm0 298; SSE41-NEXT: movzwl (%rsi), %eax 299; SSE41-NEXT: movd %eax, %xmm1 300; SSE41-NEXT: psubusb %xmm1, %xmm0 301; SSE41-NEXT: pextrw $0, %xmm0, (%rdx) 302; SSE41-NEXT: retq 303; 304; AVX-LABEL: v2i8: 305; AVX: # %bb.0: 306; AVX-NEXT: movzwl (%rdi), %eax 307; AVX-NEXT: vmovd %eax, %xmm0 308; AVX-NEXT: movzwl (%rsi), %eax 309; AVX-NEXT: vmovd %eax, %xmm1 310; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 311; AVX-NEXT: vpextrw $0, %xmm0, (%rdx) 312; AVX-NEXT: retq 313 %x = load <2 x i8>, ptr %px 314 %y = load <2 x i8>, ptr %py 315 %z = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> %y) 316 store <2 x i8> %z, ptr %pz 317 ret void 318} 319 320define void @v4i16(ptr %px, ptr %py, ptr %pz) nounwind { 321; SSE-LABEL: v4i16: 322; SSE: # %bb.0: 323; SSE-NEXT: movq {{.*#+}} xmm0 = mem[0],zero 324; SSE-NEXT: movq {{.*#+}} xmm1 = mem[0],zero 325; SSE-NEXT: psubusw %xmm1, %xmm0 326; SSE-NEXT: movq %xmm0, (%rdx) 327; SSE-NEXT: retq 328; 329; AVX-LABEL: v4i16: 330; AVX: # %bb.0: 331; AVX-NEXT: vmovq {{.*#+}} xmm0 = mem[0],zero 332; AVX-NEXT: vmovq {{.*#+}} xmm1 = mem[0],zero 333; AVX-NEXT: vpsubusw %xmm1, %xmm0, %xmm0 334; AVX-NEXT: vmovq %xmm0, (%rdx) 335; AVX-NEXT: retq 336 %x = load <4 x i16>, ptr %px 337 %y = load <4 x i16>, ptr %py 338 %z = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %x, <4 x i16> %y) 339 store <4 x i16> %z, ptr %pz 340 ret void 341} 342 343define void @v2i16(ptr %px, ptr %py, ptr %pz) nounwind { 344; SSE-LABEL: v2i16: 345; SSE: # %bb.0: 346; SSE-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero 347; SSE-NEXT: movd {{.*#+}} xmm1 = mem[0],zero,zero,zero 348; SSE-NEXT: psubusw %xmm1, %xmm0 349; SSE-NEXT: movd %xmm0, (%rdx) 350; SSE-NEXT: retq 351; 352; AVX-LABEL: v2i16: 353; AVX: # %bb.0: 354; AVX-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 355; AVX-NEXT: vmovd {{.*#+}} xmm1 = mem[0],zero,zero,zero 356; AVX-NEXT: vpsubusw %xmm1, %xmm0, %xmm0 357; AVX-NEXT: vmovd %xmm0, (%rdx) 358; AVX-NEXT: retq 359 %x = load <2 x i16>, ptr %px 360 %y = load <2 x i16>, ptr %py 361 %z = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %x, <2 x i16> %y) 362 store <2 x i16> %z, ptr %pz 363 ret void 364} 365 366define <12 x i8> @v12i8(<12 x i8> %x, <12 x i8> %y) nounwind { 367; SSE-LABEL: v12i8: 368; SSE: # %bb.0: 369; SSE-NEXT: psubusb %xmm1, %xmm0 370; SSE-NEXT: retq 371; 372; AVX-LABEL: v12i8: 373; AVX: # %bb.0: 374; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 375; AVX-NEXT: retq 376 %z = call <12 x i8> @llvm.usub.sat.v12i8(<12 x i8> %x, <12 x i8> %y) 377 ret <12 x i8> %z 378} 379 380define void @v12i16(ptr %px, ptr %py, ptr %pz) nounwind { 381; SSE-LABEL: v12i16: 382; SSE: # %bb.0: 383; SSE-NEXT: movdqa (%rdi), %xmm0 384; SSE-NEXT: movdqa 16(%rdi), %xmm1 385; SSE-NEXT: psubusw 16(%rsi), %xmm1 386; SSE-NEXT: psubusw (%rsi), %xmm0 387; SSE-NEXT: movdqa %xmm0, (%rdx) 388; SSE-NEXT: movq %xmm1, 16(%rdx) 389; SSE-NEXT: retq 390; 391; AVX1-LABEL: v12i16: 392; AVX1: # %bb.0: 393; AVX1-NEXT: vmovdqa (%rdi), %xmm0 394; AVX1-NEXT: vmovdqa 16(%rdi), %xmm1 395; AVX1-NEXT: vpsubusw 16(%rsi), %xmm1, %xmm1 396; AVX1-NEXT: vpsubusw (%rsi), %xmm0, %xmm0 397; AVX1-NEXT: vmovdqa %xmm0, (%rdx) 398; AVX1-NEXT: vmovq %xmm1, 16(%rdx) 399; AVX1-NEXT: retq 400; 401; AVX2-LABEL: v12i16: 402; AVX2: # %bb.0: 403; AVX2-NEXT: vmovdqa (%rdi), %ymm0 404; AVX2-NEXT: vpsubusw (%rsi), %ymm0, %ymm0 405; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 406; AVX2-NEXT: vmovq %xmm1, 16(%rdx) 407; AVX2-NEXT: vmovdqa %xmm0, (%rdx) 408; AVX2-NEXT: vzeroupper 409; AVX2-NEXT: retq 410; 411; AVX512-LABEL: v12i16: 412; AVX512: # %bb.0: 413; AVX512-NEXT: vmovdqa (%rdi), %ymm0 414; AVX512-NEXT: vpsubusw (%rsi), %ymm0, %ymm0 415; AVX512-NEXT: vextracti128 $1, %ymm0, %xmm1 416; AVX512-NEXT: vmovq %xmm1, 16(%rdx) 417; AVX512-NEXT: vmovdqa %xmm0, (%rdx) 418; AVX512-NEXT: vzeroupper 419; AVX512-NEXT: retq 420 %x = load <12 x i16>, ptr %px 421 %y = load <12 x i16>, ptr %py 422 %z = call <12 x i16> @llvm.usub.sat.v12i16(<12 x i16> %x, <12 x i16> %y) 423 store <12 x i16> %z, ptr %pz 424 ret void 425} 426 427; Scalarization 428 429define void @v1i8(ptr %px, ptr %py, ptr %pz) nounwind { 430; SSE-LABEL: v1i8: 431; SSE: # %bb.0: 432; SSE-NEXT: movzbl (%rdi), %eax 433; SSE-NEXT: xorl %ecx, %ecx 434; SSE-NEXT: subb (%rsi), %al 435; SSE-NEXT: movzbl %al, %eax 436; SSE-NEXT: cmovbl %ecx, %eax 437; SSE-NEXT: movb %al, (%rdx) 438; SSE-NEXT: retq 439; 440; AVX-LABEL: v1i8: 441; AVX: # %bb.0: 442; AVX-NEXT: movzbl (%rdi), %eax 443; AVX-NEXT: xorl %ecx, %ecx 444; AVX-NEXT: subb (%rsi), %al 445; AVX-NEXT: movzbl %al, %eax 446; AVX-NEXT: cmovbl %ecx, %eax 447; AVX-NEXT: movb %al, (%rdx) 448; AVX-NEXT: retq 449 %x = load <1 x i8>, ptr %px 450 %y = load <1 x i8>, ptr %py 451 %z = call <1 x i8> @llvm.usub.sat.v1i8(<1 x i8> %x, <1 x i8> %y) 452 store <1 x i8> %z, ptr %pz 453 ret void 454} 455 456define void @v1i16(ptr %px, ptr %py, ptr %pz) nounwind { 457; SSE-LABEL: v1i16: 458; SSE: # %bb.0: 459; SSE-NEXT: movzwl (%rdi), %eax 460; SSE-NEXT: xorl %ecx, %ecx 461; SSE-NEXT: subw (%rsi), %ax 462; SSE-NEXT: cmovbl %ecx, %eax 463; SSE-NEXT: movw %ax, (%rdx) 464; SSE-NEXT: retq 465; 466; AVX-LABEL: v1i16: 467; AVX: # %bb.0: 468; AVX-NEXT: movzwl (%rdi), %eax 469; AVX-NEXT: xorl %ecx, %ecx 470; AVX-NEXT: subw (%rsi), %ax 471; AVX-NEXT: cmovbl %ecx, %eax 472; AVX-NEXT: movw %ax, (%rdx) 473; AVX-NEXT: retq 474 %x = load <1 x i16>, ptr %px 475 %y = load <1 x i16>, ptr %py 476 %z = call <1 x i16> @llvm.usub.sat.v1i16(<1 x i16> %x, <1 x i16> %y) 477 store <1 x i16> %z, ptr %pz 478 ret void 479} 480 481; Promotion 482 483define <16 x i4> @v16i4(<16 x i4> %x, <16 x i4> %y) nounwind { 484; SSE-LABEL: v16i4: 485; SSE: # %bb.0: 486; SSE-NEXT: movdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] 487; SSE-NEXT: pand %xmm2, %xmm1 488; SSE-NEXT: pand %xmm2, %xmm0 489; SSE-NEXT: psubusb %xmm1, %xmm0 490; SSE-NEXT: retq 491; 492; AVX-LABEL: v16i4: 493; AVX: # %bb.0: 494; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15] 495; AVX-NEXT: vpand %xmm2, %xmm1, %xmm1 496; AVX-NEXT: vpand %xmm2, %xmm0, %xmm0 497; AVX-NEXT: vpsubusb %xmm1, %xmm0, %xmm0 498; AVX-NEXT: retq 499 %z = call <16 x i4> @llvm.usub.sat.v16i4(<16 x i4> %x, <16 x i4> %y) 500 ret <16 x i4> %z 501} 502 503define <16 x i1> @v16i1(<16 x i1> %x, <16 x i1> %y) nounwind { 504; SSE-LABEL: v16i1: 505; SSE: # %bb.0: 506; SSE-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 507; SSE-NEXT: andps %xmm1, %xmm0 508; SSE-NEXT: retq 509; 510; AVX1-LABEL: v16i1: 511; AVX1: # %bb.0: 512; AVX1-NEXT: vxorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 513; AVX1-NEXT: vandps %xmm1, %xmm0, %xmm0 514; AVX1-NEXT: retq 515; 516; AVX2-LABEL: v16i1: 517; AVX2: # %bb.0: 518; AVX2-NEXT: vxorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 519; AVX2-NEXT: vandps %xmm1, %xmm0, %xmm0 520; AVX2-NEXT: retq 521; 522; AVX512F-LABEL: v16i1: 523; AVX512F: # %bb.0: 524; AVX512F-NEXT: vxorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 525; AVX512F-NEXT: vandps %xmm1, %xmm0, %xmm0 526; AVX512F-NEXT: retq 527; 528; AVX512BW-LABEL: v16i1: 529; AVX512BW: # %bb.0: 530; AVX512BW-NEXT: vpternlogq $96, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0 531; AVX512BW-NEXT: retq 532 %z = call <16 x i1> @llvm.usub.sat.v16i1(<16 x i1> %x, <16 x i1> %y) 533 ret <16 x i1> %z 534} 535 536; Expanded 537 538define <2 x i32> @v2i32(<2 x i32> %x, <2 x i32> %y) nounwind { 539; SSE2-LABEL: v2i32: 540; SSE2: # %bb.0: 541; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] 542; SSE2-NEXT: movdqa %xmm1, %xmm3 543; SSE2-NEXT: pxor %xmm2, %xmm3 544; SSE2-NEXT: pxor %xmm0, %xmm2 545; SSE2-NEXT: pcmpgtd %xmm3, %xmm2 546; SSE2-NEXT: psubd %xmm1, %xmm0 547; SSE2-NEXT: pand %xmm2, %xmm0 548; SSE2-NEXT: retq 549; 550; SSSE3-LABEL: v2i32: 551; SSSE3: # %bb.0: 552; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] 553; SSSE3-NEXT: movdqa %xmm1, %xmm3 554; SSSE3-NEXT: pxor %xmm2, %xmm3 555; SSSE3-NEXT: pxor %xmm0, %xmm2 556; SSSE3-NEXT: pcmpgtd %xmm3, %xmm2 557; SSSE3-NEXT: psubd %xmm1, %xmm0 558; SSSE3-NEXT: pand %xmm2, %xmm0 559; SSSE3-NEXT: retq 560; 561; SSE41-LABEL: v2i32: 562; SSE41: # %bb.0: 563; SSE41-NEXT: pmaxud %xmm1, %xmm0 564; SSE41-NEXT: psubd %xmm1, %xmm0 565; SSE41-NEXT: retq 566; 567; AVX-LABEL: v2i32: 568; AVX: # %bb.0: 569; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0 570; AVX-NEXT: vpsubd %xmm1, %xmm0, %xmm0 571; AVX-NEXT: retq 572 %z = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %x, <2 x i32> %y) 573 ret <2 x i32> %z 574} 575 576define <4 x i32> @v4i32(<4 x i32> %x, <4 x i32> %y) nounwind { 577; SSE2-LABEL: v4i32: 578; SSE2: # %bb.0: 579; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] 580; SSE2-NEXT: movdqa %xmm1, %xmm3 581; SSE2-NEXT: pxor %xmm2, %xmm3 582; SSE2-NEXT: pxor %xmm0, %xmm2 583; SSE2-NEXT: pcmpgtd %xmm3, %xmm2 584; SSE2-NEXT: psubd %xmm1, %xmm0 585; SSE2-NEXT: pand %xmm2, %xmm0 586; SSE2-NEXT: retq 587; 588; SSSE3-LABEL: v4i32: 589; SSSE3: # %bb.0: 590; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] 591; SSSE3-NEXT: movdqa %xmm1, %xmm3 592; SSSE3-NEXT: pxor %xmm2, %xmm3 593; SSSE3-NEXT: pxor %xmm0, %xmm2 594; SSSE3-NEXT: pcmpgtd %xmm3, %xmm2 595; SSSE3-NEXT: psubd %xmm1, %xmm0 596; SSSE3-NEXT: pand %xmm2, %xmm0 597; SSSE3-NEXT: retq 598; 599; SSE41-LABEL: v4i32: 600; SSE41: # %bb.0: 601; SSE41-NEXT: pmaxud %xmm1, %xmm0 602; SSE41-NEXT: psubd %xmm1, %xmm0 603; SSE41-NEXT: retq 604; 605; AVX-LABEL: v4i32: 606; AVX: # %bb.0: 607; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0 608; AVX-NEXT: vpsubd %xmm1, %xmm0, %xmm0 609; AVX-NEXT: retq 610 %z = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %x, <4 x i32> %y) 611 ret <4 x i32> %z 612} 613 614define <8 x i32> @v8i32(<8 x i32> %x, <8 x i32> %y) nounwind { 615; SSE2-LABEL: v8i32: 616; SSE2: # %bb.0: 617; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648] 618; SSE2-NEXT: movdqa %xmm0, %xmm5 619; SSE2-NEXT: psubd %xmm2, %xmm0 620; SSE2-NEXT: pxor %xmm4, %xmm2 621; SSE2-NEXT: pxor %xmm4, %xmm5 622; SSE2-NEXT: pcmpgtd %xmm2, %xmm5 623; SSE2-NEXT: pand %xmm5, %xmm0 624; SSE2-NEXT: movdqa %xmm3, %xmm2 625; SSE2-NEXT: pxor %xmm4, %xmm2 626; SSE2-NEXT: pxor %xmm1, %xmm4 627; SSE2-NEXT: pcmpgtd %xmm2, %xmm4 628; SSE2-NEXT: psubd %xmm3, %xmm1 629; SSE2-NEXT: pand %xmm4, %xmm1 630; SSE2-NEXT: retq 631; 632; SSSE3-LABEL: v8i32: 633; SSSE3: # %bb.0: 634; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [2147483648,2147483648,2147483648,2147483648] 635; SSSE3-NEXT: movdqa %xmm0, %xmm5 636; SSSE3-NEXT: psubd %xmm2, %xmm0 637; SSSE3-NEXT: pxor %xmm4, %xmm2 638; SSSE3-NEXT: pxor %xmm4, %xmm5 639; SSSE3-NEXT: pcmpgtd %xmm2, %xmm5 640; SSSE3-NEXT: pand %xmm5, %xmm0 641; SSSE3-NEXT: movdqa %xmm3, %xmm2 642; SSSE3-NEXT: pxor %xmm4, %xmm2 643; SSSE3-NEXT: pxor %xmm1, %xmm4 644; SSSE3-NEXT: pcmpgtd %xmm2, %xmm4 645; SSSE3-NEXT: psubd %xmm3, %xmm1 646; SSSE3-NEXT: pand %xmm4, %xmm1 647; SSSE3-NEXT: retq 648; 649; SSE41-LABEL: v8i32: 650; SSE41: # %bb.0: 651; SSE41-NEXT: pmaxud %xmm2, %xmm0 652; SSE41-NEXT: psubd %xmm2, %xmm0 653; SSE41-NEXT: pmaxud %xmm3, %xmm1 654; SSE41-NEXT: psubd %xmm3, %xmm1 655; SSE41-NEXT: retq 656; 657; AVX1-LABEL: v8i32: 658; AVX1: # %bb.0: 659; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 660; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 661; AVX1-NEXT: vpmaxud %xmm2, %xmm3, %xmm3 662; AVX1-NEXT: vpsubd %xmm2, %xmm3, %xmm2 663; AVX1-NEXT: vpmaxud %xmm1, %xmm0, %xmm0 664; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 665; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 666; AVX1-NEXT: retq 667; 668; AVX2-LABEL: v8i32: 669; AVX2: # %bb.0: 670; AVX2-NEXT: vpmaxud %ymm1, %ymm0, %ymm0 671; AVX2-NEXT: vpsubd %ymm1, %ymm0, %ymm0 672; AVX2-NEXT: retq 673; 674; AVX512-LABEL: v8i32: 675; AVX512: # %bb.0: 676; AVX512-NEXT: vpmaxud %ymm1, %ymm0, %ymm0 677; AVX512-NEXT: vpsubd %ymm1, %ymm0, %ymm0 678; AVX512-NEXT: retq 679 %z = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %x, <8 x i32> %y) 680 ret <8 x i32> %z 681} 682 683define <16 x i32> @v16i32(<16 x i32> %x, <16 x i32> %y) nounwind { 684; SSE2-LABEL: v16i32: 685; SSE2: # %bb.0: 686; SSE2-NEXT: movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648] 687; SSE2-NEXT: movdqa %xmm0, %xmm9 688; SSE2-NEXT: psubd %xmm4, %xmm0 689; SSE2-NEXT: pxor %xmm8, %xmm4 690; SSE2-NEXT: pxor %xmm8, %xmm9 691; SSE2-NEXT: pcmpgtd %xmm4, %xmm9 692; SSE2-NEXT: pand %xmm9, %xmm0 693; SSE2-NEXT: movdqa %xmm1, %xmm4 694; SSE2-NEXT: psubd %xmm5, %xmm1 695; SSE2-NEXT: pxor %xmm8, %xmm5 696; SSE2-NEXT: pxor %xmm8, %xmm4 697; SSE2-NEXT: pcmpgtd %xmm5, %xmm4 698; SSE2-NEXT: pand %xmm4, %xmm1 699; SSE2-NEXT: movdqa %xmm2, %xmm4 700; SSE2-NEXT: psubd %xmm6, %xmm2 701; SSE2-NEXT: pxor %xmm8, %xmm6 702; SSE2-NEXT: pxor %xmm8, %xmm4 703; SSE2-NEXT: pcmpgtd %xmm6, %xmm4 704; SSE2-NEXT: pand %xmm4, %xmm2 705; SSE2-NEXT: movdqa %xmm7, %xmm4 706; SSE2-NEXT: pxor %xmm8, %xmm4 707; SSE2-NEXT: pxor %xmm3, %xmm8 708; SSE2-NEXT: pcmpgtd %xmm4, %xmm8 709; SSE2-NEXT: psubd %xmm7, %xmm3 710; SSE2-NEXT: pand %xmm8, %xmm3 711; SSE2-NEXT: retq 712; 713; SSSE3-LABEL: v16i32: 714; SSSE3: # %bb.0: 715; SSSE3-NEXT: movdqa {{.*#+}} xmm8 = [2147483648,2147483648,2147483648,2147483648] 716; SSSE3-NEXT: movdqa %xmm0, %xmm9 717; SSSE3-NEXT: psubd %xmm4, %xmm0 718; SSSE3-NEXT: pxor %xmm8, %xmm4 719; SSSE3-NEXT: pxor %xmm8, %xmm9 720; SSSE3-NEXT: pcmpgtd %xmm4, %xmm9 721; SSSE3-NEXT: pand %xmm9, %xmm0 722; SSSE3-NEXT: movdqa %xmm1, %xmm4 723; SSSE3-NEXT: psubd %xmm5, %xmm1 724; SSSE3-NEXT: pxor %xmm8, %xmm5 725; SSSE3-NEXT: pxor %xmm8, %xmm4 726; SSSE3-NEXT: pcmpgtd %xmm5, %xmm4 727; SSSE3-NEXT: pand %xmm4, %xmm1 728; SSSE3-NEXT: movdqa %xmm2, %xmm4 729; SSSE3-NEXT: psubd %xmm6, %xmm2 730; SSSE3-NEXT: pxor %xmm8, %xmm6 731; SSSE3-NEXT: pxor %xmm8, %xmm4 732; SSSE3-NEXT: pcmpgtd %xmm6, %xmm4 733; SSSE3-NEXT: pand %xmm4, %xmm2 734; SSSE3-NEXT: movdqa %xmm7, %xmm4 735; SSSE3-NEXT: pxor %xmm8, %xmm4 736; SSSE3-NEXT: pxor %xmm3, %xmm8 737; SSSE3-NEXT: pcmpgtd %xmm4, %xmm8 738; SSSE3-NEXT: psubd %xmm7, %xmm3 739; SSSE3-NEXT: pand %xmm8, %xmm3 740; SSSE3-NEXT: retq 741; 742; SSE41-LABEL: v16i32: 743; SSE41: # %bb.0: 744; SSE41-NEXT: pmaxud %xmm4, %xmm0 745; SSE41-NEXT: psubd %xmm4, %xmm0 746; SSE41-NEXT: pmaxud %xmm5, %xmm1 747; SSE41-NEXT: psubd %xmm5, %xmm1 748; SSE41-NEXT: pmaxud %xmm6, %xmm2 749; SSE41-NEXT: psubd %xmm6, %xmm2 750; SSE41-NEXT: pmaxud %xmm7, %xmm3 751; SSE41-NEXT: psubd %xmm7, %xmm3 752; SSE41-NEXT: retq 753; 754; AVX1-LABEL: v16i32: 755; AVX1: # %bb.0: 756; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 757; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 758; AVX1-NEXT: vpmaxud %xmm4, %xmm5, %xmm5 759; AVX1-NEXT: vpsubd %xmm4, %xmm5, %xmm4 760; AVX1-NEXT: vpmaxud %xmm2, %xmm0, %xmm0 761; AVX1-NEXT: vpsubd %xmm2, %xmm0, %xmm0 762; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 763; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 764; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 765; AVX1-NEXT: vpmaxud %xmm2, %xmm4, %xmm4 766; AVX1-NEXT: vpsubd %xmm2, %xmm4, %xmm2 767; AVX1-NEXT: vpmaxud %xmm3, %xmm1, %xmm1 768; AVX1-NEXT: vpsubd %xmm3, %xmm1, %xmm1 769; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 770; AVX1-NEXT: retq 771; 772; AVX2-LABEL: v16i32: 773; AVX2: # %bb.0: 774; AVX2-NEXT: vpmaxud %ymm2, %ymm0, %ymm0 775; AVX2-NEXT: vpsubd %ymm2, %ymm0, %ymm0 776; AVX2-NEXT: vpmaxud %ymm3, %ymm1, %ymm1 777; AVX2-NEXT: vpsubd %ymm3, %ymm1, %ymm1 778; AVX2-NEXT: retq 779; 780; AVX512-LABEL: v16i32: 781; AVX512: # %bb.0: 782; AVX512-NEXT: vpmaxud %zmm1, %zmm0, %zmm0 783; AVX512-NEXT: vpsubd %zmm1, %zmm0, %zmm0 784; AVX512-NEXT: retq 785 %z = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %x, <16 x i32> %y) 786 ret <16 x i32> %z 787} 788 789define <2 x i64> @v2i64(<2 x i64> %x, <2 x i64> %y) nounwind { 790; SSE-LABEL: v2i64: 791; SSE: # %bb.0: 792; SSE-NEXT: movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456] 793; SSE-NEXT: movdqa %xmm1, %xmm3 794; SSE-NEXT: pxor %xmm2, %xmm3 795; SSE-NEXT: pxor %xmm0, %xmm2 796; SSE-NEXT: movdqa %xmm2, %xmm4 797; SSE-NEXT: pcmpgtd %xmm3, %xmm4 798; SSE-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2] 799; SSE-NEXT: pcmpeqd %xmm3, %xmm2 800; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3] 801; SSE-NEXT: pand %xmm5, %xmm2 802; SSE-NEXT: pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3] 803; SSE-NEXT: por %xmm2, %xmm3 804; SSE-NEXT: psubq %xmm1, %xmm0 805; SSE-NEXT: pand %xmm3, %xmm0 806; SSE-NEXT: retq 807; 808; AVX1-LABEL: v2i64: 809; AVX1: # %bb.0: 810; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808] 811; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3 812; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2 813; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2 814; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0 815; AVX1-NEXT: vpand %xmm0, %xmm2, %xmm0 816; AVX1-NEXT: retq 817; 818; AVX2-LABEL: v2i64: 819; AVX2: # %bb.0: 820; AVX2-NEXT: vmovdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808] 821; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3 822; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2 823; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2 824; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0 825; AVX2-NEXT: vpand %xmm0, %xmm2, %xmm0 826; AVX2-NEXT: retq 827; 828; AVX512F-LABEL: v2i64: 829; AVX512F: # %bb.0: 830; AVX512F-NEXT: # kill: def $xmm1 killed $xmm1 def $zmm1 831; AVX512F-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0 832; AVX512F-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0 833; AVX512F-NEXT: vpsubq %xmm1, %xmm0, %xmm0 834; AVX512F-NEXT: vzeroupper 835; AVX512F-NEXT: retq 836; 837; AVX512BW-LABEL: v2i64: 838; AVX512BW: # %bb.0: 839; AVX512BW-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0 840; AVX512BW-NEXT: vpsubq %xmm1, %xmm0, %xmm0 841; AVX512BW-NEXT: retq 842 %z = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %x, <2 x i64> %y) 843 ret <2 x i64> %z 844} 845 846define <4 x i64> @v4i64(<4 x i64> %x, <4 x i64> %y) nounwind { 847; SSE-LABEL: v4i64: 848; SSE: # %bb.0: 849; SSE-NEXT: movdqa {{.*#+}} xmm4 = [9223372039002259456,9223372039002259456] 850; SSE-NEXT: movdqa %xmm0, %xmm5 851; SSE-NEXT: psubq %xmm2, %xmm0 852; SSE-NEXT: pxor %xmm4, %xmm2 853; SSE-NEXT: pxor %xmm4, %xmm5 854; SSE-NEXT: movdqa %xmm5, %xmm6 855; SSE-NEXT: pcmpgtd %xmm2, %xmm6 856; SSE-NEXT: pshufd {{.*#+}} xmm7 = xmm6[0,0,2,2] 857; SSE-NEXT: pcmpeqd %xmm2, %xmm5 858; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm5[1,1,3,3] 859; SSE-NEXT: pand %xmm7, %xmm2 860; SSE-NEXT: pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3] 861; SSE-NEXT: por %xmm2, %xmm5 862; SSE-NEXT: pand %xmm5, %xmm0 863; SSE-NEXT: movdqa %xmm3, %xmm2 864; SSE-NEXT: pxor %xmm4, %xmm2 865; SSE-NEXT: pxor %xmm1, %xmm4 866; SSE-NEXT: movdqa %xmm4, %xmm5 867; SSE-NEXT: pcmpgtd %xmm2, %xmm5 868; SSE-NEXT: pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2] 869; SSE-NEXT: pcmpeqd %xmm2, %xmm4 870; SSE-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3] 871; SSE-NEXT: pand %xmm6, %xmm2 872; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm5[1,1,3,3] 873; SSE-NEXT: por %xmm2, %xmm4 874; SSE-NEXT: psubq %xmm3, %xmm1 875; SSE-NEXT: pand %xmm4, %xmm1 876; SSE-NEXT: retq 877; 878; AVX1-LABEL: v4i64: 879; AVX1: # %bb.0: 880; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 881; AVX1-NEXT: vmovdqa {{.*#+}} xmm3 = [9223372036854775808,9223372036854775808] 882; AVX1-NEXT: vpxor %xmm3, %xmm2, %xmm4 883; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 884; AVX1-NEXT: vpxor %xmm3, %xmm5, %xmm6 885; AVX1-NEXT: vpcmpgtq %xmm4, %xmm6, %xmm4 886; AVX1-NEXT: vpsubq %xmm2, %xmm5, %xmm2 887; AVX1-NEXT: vpand %xmm2, %xmm4, %xmm2 888; AVX1-NEXT: vpxor %xmm3, %xmm1, %xmm4 889; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm3 890; AVX1-NEXT: vpcmpgtq %xmm4, %xmm3, %xmm3 891; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0 892; AVX1-NEXT: vpand %xmm0, %xmm3, %xmm0 893; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0 894; AVX1-NEXT: retq 895; 896; AVX2-LABEL: v4i64: 897; AVX2: # %bb.0: 898; AVX2-NEXT: vpbroadcastq {{.*#+}} ymm2 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808] 899; AVX2-NEXT: vpxor %ymm2, %ymm1, %ymm3 900; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm2 901; AVX2-NEXT: vpcmpgtq %ymm3, %ymm2, %ymm2 902; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0 903; AVX2-NEXT: vpand %ymm0, %ymm2, %ymm0 904; AVX2-NEXT: retq 905; 906; AVX512F-LABEL: v4i64: 907; AVX512F: # %bb.0: 908; AVX512F-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 909; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 910; AVX512F-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0 911; AVX512F-NEXT: vpsubq %ymm1, %ymm0, %ymm0 912; AVX512F-NEXT: retq 913; 914; AVX512BW-LABEL: v4i64: 915; AVX512BW: # %bb.0: 916; AVX512BW-NEXT: vpmaxuq %ymm1, %ymm0, %ymm0 917; AVX512BW-NEXT: vpsubq %ymm1, %ymm0, %ymm0 918; AVX512BW-NEXT: retq 919 %z = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %x, <4 x i64> %y) 920 ret <4 x i64> %z 921} 922 923define <8 x i64> @v8i64(<8 x i64> %x, <8 x i64> %y) nounwind { 924; SSE-LABEL: v8i64: 925; SSE: # %bb.0: 926; SSE-NEXT: movdqa {{.*#+}} xmm8 = [9223372039002259456,9223372039002259456] 927; SSE-NEXT: movdqa %xmm0, %xmm9 928; SSE-NEXT: psubq %xmm4, %xmm0 929; SSE-NEXT: pxor %xmm8, %xmm4 930; SSE-NEXT: pxor %xmm8, %xmm9 931; SSE-NEXT: movdqa %xmm9, %xmm10 932; SSE-NEXT: pcmpgtd %xmm4, %xmm10 933; SSE-NEXT: pshufd {{.*#+}} xmm11 = xmm10[0,0,2,2] 934; SSE-NEXT: pcmpeqd %xmm4, %xmm9 935; SSE-NEXT: pshufd {{.*#+}} xmm9 = xmm9[1,1,3,3] 936; SSE-NEXT: pand %xmm11, %xmm9 937; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm10[1,1,3,3] 938; SSE-NEXT: por %xmm9, %xmm4 939; SSE-NEXT: pand %xmm4, %xmm0 940; SSE-NEXT: movdqa %xmm1, %xmm9 941; SSE-NEXT: psubq %xmm5, %xmm1 942; SSE-NEXT: pxor %xmm8, %xmm5 943; SSE-NEXT: pxor %xmm8, %xmm9 944; SSE-NEXT: movdqa %xmm9, %xmm4 945; SSE-NEXT: pcmpgtd %xmm5, %xmm4 946; SSE-NEXT: pshufd {{.*#+}} xmm10 = xmm4[0,0,2,2] 947; SSE-NEXT: pcmpeqd %xmm5, %xmm9 948; SSE-NEXT: pshufd {{.*#+}} xmm5 = xmm9[1,1,3,3] 949; SSE-NEXT: pand %xmm10, %xmm5 950; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3] 951; SSE-NEXT: por %xmm5, %xmm4 952; SSE-NEXT: pand %xmm4, %xmm1 953; SSE-NEXT: movdqa %xmm2, %xmm4 954; SSE-NEXT: psubq %xmm6, %xmm2 955; SSE-NEXT: pxor %xmm8, %xmm6 956; SSE-NEXT: pxor %xmm8, %xmm4 957; SSE-NEXT: movdqa %xmm4, %xmm5 958; SSE-NEXT: pcmpgtd %xmm6, %xmm5 959; SSE-NEXT: pshufd {{.*#+}} xmm9 = xmm5[0,0,2,2] 960; SSE-NEXT: pcmpeqd %xmm6, %xmm4 961; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3] 962; SSE-NEXT: pand %xmm9, %xmm4 963; SSE-NEXT: pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3] 964; SSE-NEXT: por %xmm4, %xmm5 965; SSE-NEXT: pand %xmm5, %xmm2 966; SSE-NEXT: movdqa %xmm7, %xmm4 967; SSE-NEXT: pxor %xmm8, %xmm4 968; SSE-NEXT: pxor %xmm3, %xmm8 969; SSE-NEXT: movdqa %xmm8, %xmm5 970; SSE-NEXT: pcmpgtd %xmm4, %xmm5 971; SSE-NEXT: pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2] 972; SSE-NEXT: pcmpeqd %xmm4, %xmm8 973; SSE-NEXT: pshufd {{.*#+}} xmm4 = xmm8[1,1,3,3] 974; SSE-NEXT: pand %xmm6, %xmm4 975; SSE-NEXT: pshufd {{.*#+}} xmm5 = xmm5[1,1,3,3] 976; SSE-NEXT: por %xmm4, %xmm5 977; SSE-NEXT: psubq %xmm7, %xmm3 978; SSE-NEXT: pand %xmm5, %xmm3 979; SSE-NEXT: retq 980; 981; AVX1-LABEL: v8i64: 982; AVX1: # %bb.0: 983; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm4 984; AVX1-NEXT: vmovdqa {{.*#+}} xmm5 = [9223372036854775808,9223372036854775808] 985; AVX1-NEXT: vpxor %xmm5, %xmm4, %xmm8 986; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm7 987; AVX1-NEXT: vpxor %xmm5, %xmm7, %xmm6 988; AVX1-NEXT: vpcmpgtq %xmm8, %xmm6, %xmm6 989; AVX1-NEXT: vpsubq %xmm4, %xmm7, %xmm4 990; AVX1-NEXT: vpand %xmm4, %xmm6, %xmm4 991; AVX1-NEXT: vpxor %xmm5, %xmm2, %xmm6 992; AVX1-NEXT: vpxor %xmm5, %xmm0, %xmm7 993; AVX1-NEXT: vpcmpgtq %xmm6, %xmm7, %xmm6 994; AVX1-NEXT: vpsubq %xmm2, %xmm0, %xmm0 995; AVX1-NEXT: vpand %xmm0, %xmm6, %xmm0 996; AVX1-NEXT: vinsertf128 $1, %xmm4, %ymm0, %ymm0 997; AVX1-NEXT: vextractf128 $1, %ymm3, %xmm2 998; AVX1-NEXT: vpxor %xmm5, %xmm2, %xmm4 999; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm6 1000; AVX1-NEXT: vpxor %xmm5, %xmm6, %xmm7 1001; AVX1-NEXT: vpcmpgtq %xmm4, %xmm7, %xmm4 1002; AVX1-NEXT: vpsubq %xmm2, %xmm6, %xmm2 1003; AVX1-NEXT: vpand %xmm2, %xmm4, %xmm2 1004; AVX1-NEXT: vpxor %xmm5, %xmm3, %xmm4 1005; AVX1-NEXT: vpxor %xmm5, %xmm1, %xmm5 1006; AVX1-NEXT: vpcmpgtq %xmm4, %xmm5, %xmm4 1007; AVX1-NEXT: vpsubq %xmm3, %xmm1, %xmm1 1008; AVX1-NEXT: vpand %xmm1, %xmm4, %xmm1 1009; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm1, %ymm1 1010; AVX1-NEXT: retq 1011; 1012; AVX2-LABEL: v8i64: 1013; AVX2: # %bb.0: 1014; AVX2-NEXT: vpbroadcastq {{.*#+}} ymm4 = [9223372036854775808,9223372036854775808,9223372036854775808,9223372036854775808] 1015; AVX2-NEXT: vpxor %ymm4, %ymm2, %ymm5 1016; AVX2-NEXT: vpxor %ymm4, %ymm0, %ymm6 1017; AVX2-NEXT: vpcmpgtq %ymm5, %ymm6, %ymm5 1018; AVX2-NEXT: vpsubq %ymm2, %ymm0, %ymm0 1019; AVX2-NEXT: vpand %ymm0, %ymm5, %ymm0 1020; AVX2-NEXT: vpxor %ymm4, %ymm3, %ymm2 1021; AVX2-NEXT: vpxor %ymm4, %ymm1, %ymm4 1022; AVX2-NEXT: vpcmpgtq %ymm2, %ymm4, %ymm2 1023; AVX2-NEXT: vpsubq %ymm3, %ymm1, %ymm1 1024; AVX2-NEXT: vpand %ymm1, %ymm2, %ymm1 1025; AVX2-NEXT: retq 1026; 1027; AVX512-LABEL: v8i64: 1028; AVX512: # %bb.0: 1029; AVX512-NEXT: vpmaxuq %zmm1, %zmm0, %zmm0 1030; AVX512-NEXT: vpsubq %zmm1, %zmm0, %zmm0 1031; AVX512-NEXT: retq 1032 %z = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %x, <8 x i64> %y) 1033 ret <8 x i64> %z 1034} 1035 1036define <2 x i128> @v2i128(<2 x i128> %x, <2 x i128> %y) nounwind { 1037; SSE-LABEL: v2i128: 1038; SSE: # %bb.0: 1039; SSE-NEXT: movq %rdi, %rax 1040; SSE-NEXT: xorl %edi, %edi 1041; SSE-NEXT: subq %r9, %rsi 1042; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx 1043; SSE-NEXT: cmovbq %rdi, %rsi 1044; SSE-NEXT: cmovbq %rdi, %rdx 1045; SSE-NEXT: subq {{[0-9]+}}(%rsp), %rcx 1046; SSE-NEXT: sbbq {{[0-9]+}}(%rsp), %r8 1047; SSE-NEXT: cmovbq %rdi, %r8 1048; SSE-NEXT: cmovbq %rdi, %rcx 1049; SSE-NEXT: movq %r8, 24(%rax) 1050; SSE-NEXT: movq %rcx, 16(%rax) 1051; SSE-NEXT: movq %rdx, 8(%rax) 1052; SSE-NEXT: movq %rsi, (%rax) 1053; SSE-NEXT: retq 1054; 1055; AVX-LABEL: v2i128: 1056; AVX: # %bb.0: 1057; AVX-NEXT: movq %rdi, %rax 1058; AVX-NEXT: xorl %edi, %edi 1059; AVX-NEXT: subq %r9, %rsi 1060; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %rdx 1061; AVX-NEXT: cmovbq %rdi, %rsi 1062; AVX-NEXT: cmovbq %rdi, %rdx 1063; AVX-NEXT: subq {{[0-9]+}}(%rsp), %rcx 1064; AVX-NEXT: sbbq {{[0-9]+}}(%rsp), %r8 1065; AVX-NEXT: cmovbq %rdi, %r8 1066; AVX-NEXT: cmovbq %rdi, %rcx 1067; AVX-NEXT: movq %r8, 24(%rax) 1068; AVX-NEXT: movq %rcx, 16(%rax) 1069; AVX-NEXT: movq %rdx, 8(%rax) 1070; AVX-NEXT: movq %rsi, (%rax) 1071; AVX-NEXT: retq 1072 %z = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %x, <2 x i128> %y) 1073 ret <2 x i128> %z 1074} 1075 1076define void @PR48223(ptr %p0) { 1077; SSE-LABEL: PR48223: 1078; SSE: # %bb.0: 1079; SSE-NEXT: movdqa (%rdi), %xmm0 1080; SSE-NEXT: movdqa 16(%rdi), %xmm1 1081; SSE-NEXT: movdqa 32(%rdi), %xmm2 1082; SSE-NEXT: movdqa 48(%rdi), %xmm3 1083; SSE-NEXT: movdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64] 1084; SSE-NEXT: psubusw %xmm4, %xmm1 1085; SSE-NEXT: psubusw %xmm4, %xmm0 1086; SSE-NEXT: psubusw %xmm4, %xmm3 1087; SSE-NEXT: psubusw %xmm4, %xmm2 1088; SSE-NEXT: movdqa %xmm2, 32(%rdi) 1089; SSE-NEXT: movdqa %xmm3, 48(%rdi) 1090; SSE-NEXT: movdqa %xmm0, (%rdi) 1091; SSE-NEXT: movdqa %xmm1, 16(%rdi) 1092; SSE-NEXT: retq 1093; 1094; AVX1-LABEL: PR48223: 1095; AVX1: # %bb.0: 1096; AVX1-NEXT: vmovdqa (%rdi), %xmm0 1097; AVX1-NEXT: vmovdqa 16(%rdi), %xmm1 1098; AVX1-NEXT: vmovdqa 32(%rdi), %xmm2 1099; AVX1-NEXT: vmovdqa 48(%rdi), %xmm3 1100; AVX1-NEXT: vmovdqa {{.*#+}} xmm4 = [64,64,64,64,64,64,64,64] 1101; AVX1-NEXT: vpsubusw %xmm4, %xmm3, %xmm3 1102; AVX1-NEXT: vpsubusw %xmm4, %xmm2, %xmm2 1103; AVX1-NEXT: vpsubusw %xmm4, %xmm1, %xmm1 1104; AVX1-NEXT: vpsubusw %xmm4, %xmm0, %xmm0 1105; AVX1-NEXT: vmovdqa %xmm0, (%rdi) 1106; AVX1-NEXT: vmovdqa %xmm1, 16(%rdi) 1107; AVX1-NEXT: vmovdqa %xmm2, 32(%rdi) 1108; AVX1-NEXT: vmovdqa %xmm3, 48(%rdi) 1109; AVX1-NEXT: retq 1110; 1111; AVX2-LABEL: PR48223: 1112; AVX2: # %bb.0: 1113; AVX2-NEXT: vmovdqa (%rdi), %ymm0 1114; AVX2-NEXT: vmovdqa 32(%rdi), %ymm1 1115; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] 1116; AVX2-NEXT: vpsubusw %ymm2, %ymm1, %ymm1 1117; AVX2-NEXT: vpsubusw %ymm2, %ymm0, %ymm0 1118; AVX2-NEXT: vmovdqa %ymm0, (%rdi) 1119; AVX2-NEXT: vmovdqa %ymm1, 32(%rdi) 1120; AVX2-NEXT: vzeroupper 1121; AVX2-NEXT: retq 1122; 1123; AVX512F-LABEL: PR48223: 1124; AVX512F: # %bb.0: 1125; AVX512F-NEXT: vmovdqa (%rdi), %ymm0 1126; AVX512F-NEXT: vmovdqa 32(%rdi), %ymm1 1127; AVX512F-NEXT: vmovdqa {{.*#+}} ymm2 = [64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64] 1128; AVX512F-NEXT: vpsubusw %ymm2, %ymm1, %ymm1 1129; AVX512F-NEXT: vpsubusw %ymm2, %ymm0, %ymm0 1130; AVX512F-NEXT: vmovdqa %ymm0, (%rdi) 1131; AVX512F-NEXT: vmovdqa %ymm1, 32(%rdi) 1132; AVX512F-NEXT: vzeroupper 1133; AVX512F-NEXT: retq 1134; 1135; AVX512BW-LABEL: PR48223: 1136; AVX512BW: # %bb.0: 1137; AVX512BW-NEXT: vmovdqa64 (%rdi), %zmm0 1138; AVX512BW-NEXT: vpsubusw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm0, %zmm0 1139; AVX512BW-NEXT: vmovdqa64 %zmm0, (%rdi) 1140; AVX512BW-NEXT: vzeroupper 1141; AVX512BW-NEXT: retq 1142 %1 = load <32 x i16>, ptr %p0, align 64 1143 %2 = icmp ugt <32 x i16> %1, <i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63, i16 63> 1144 %3 = add <32 x i16> %1, <i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64, i16 -64> 1145 %4 = select <32 x i1> %2, <32 x i16> %3, <32 x i16> zeroinitializer 1146 store <32 x i16> %4, ptr %p0, align 64 1147 ret void 1148} 1149