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