Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -8408,6 +8408,45 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } +static Value *EmitX86Pack(CodeGenFunction &CGF, ArrayRef Ops, + bool IsUnsigned) { + Value *A = Ops[0]; + Value *B = Ops[1]; + + llvm::Type *Ty = A->getType(); + int EltSize = Ty->getScalarSizeInBits(); + llvm::APInt MinVal, MaxVal; + if (IsUnsigned) { + MinVal = llvm::APInt::getMinValue(EltSize / 2).zext(EltSize); + MaxVal = llvm::APInt::getMaxValue(EltSize / 2).zext(EltSize); + } else { + MinVal = llvm::APInt::getSignedMinValue(EltSize / 2).sext(EltSize); + MaxVal = llvm::APInt::getSignedMaxValue(EltSize / 2).sext(EltSize); + } + + SmallVector ShuffleMask; + unsigned NumElts = Ty->getVectorNumElements(); + unsigned NumLanes = NumElts * Ty->getScalarSizeInBits() / 128; + unsigned NumEltsPerLane = 128 / EltSize; + + for (unsigned Lane = 0; Lane != NumLanes; ++Lane) { + for (unsigned Elt = 0; Elt != NumEltsPerLane; ++Elt) + ShuffleMask.push_back(Elt + (Lane * NumEltsPerLane)); + for (unsigned Elt = 0; Elt != NumEltsPerLane; ++Elt) + ShuffleMask.push_back(Elt + (Lane * NumEltsPerLane) + NumElts); + } + + Value *Res = CGF.Builder.CreateShuffleVector(A, B, ShuffleMask); + llvm::Type *RTy = Res->getType(); + Value *MinVec = llvm::ConstantInt::get(RTy, MinVal); + Value *MaxVec = llvm::ConstantInt::get(RTy, MaxVal); + Res = EmitX86MinMax(CGF, ICmpInst::ICMP_SLT, {Res, MaxVec}); + Res = EmitX86MinMax(CGF, ICmpInst::ICMP_SGT, {Res, MinVec}); + llvm::Type *VTy = llvm::VectorType::get(CGF.Builder.getIntNTy(EltSize / 2), + NumElts * 2); + return CGF.Builder.CreateTrunc(Res, VTy); +} + Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); @@ -9475,6 +9514,22 @@ Load->setVolatile(true); return Load; } + + // Packing intrinsics. + case X86::BI__builtin_ia32_packsswb128: + case X86::BI__builtin_ia32_packssdw128: + case X86::BI__builtin_ia32_packsswb256: + case X86::BI__builtin_ia32_packssdw256: + case X86::BI__builtin_ia32_packsswb512: + case X86::BI__builtin_ia32_packssdw512: + return EmitX86Pack(*this, Ops, false /*IsUnsigned*/); + case X86::BI__builtin_ia32_packuswb128: + case X86::BI__builtin_ia32_packusdw128: + case X86::BI__builtin_ia32_packuswb256: + case X86::BI__builtin_ia32_packusdw256: + case X86::BI__builtin_ia32_packuswb512: + case X86::BI__builtin_ia32_packusdw512: + return EmitX86Pack(*this, Ops, true /*IsUnsigned*/); } } Index: clang/test/CodeGen/avx2-builtins.c =================================================================== --- clang/test/CodeGen/avx2-builtins.c +++ clang/test/CodeGen/avx2-builtins.c @@ -889,25 +889,45 @@ __m256i test_mm256_packs_epi16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_packs_epi16 - // CHECK: call <32 x i8> @llvm.x86.avx2.packsswb(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> return _mm256_packs_epi16(a, b); } __m256i test_mm256_packs_epi32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_packs_epi32 - // CHECK: call <16 x i16> @llvm.x86.avx2.packssdw(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> return _mm256_packs_epi32(a, b); } __m256i test_mm256_packs_epu16(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_packs_epu16 - // CHECK: call <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> return _mm256_packus_epi16(a, b); } __m256i test_mm256_packs_epu32(__m256i a, __m256i b) { // CHECK-LABEL: test_mm256_packs_epu32 - // CHECK: call <16 x i16> @llvm.x86.avx2.packusdw(<8 x i32> %{{.*}}, <8 x i32> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> return _mm256_packus_epi32(a, b); } Index: clang/test/CodeGen/avx512bw-builtins.c =================================================================== --- clang/test/CodeGen/avx512bw-builtins.c +++ clang/test/CodeGen/avx512bw-builtins.c @@ -526,69 +526,129 @@ } __m512i test_mm512_packs_epi32(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_packs_epi32 - // CHECK: @llvm.x86.avx512.packssdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> return _mm512_packs_epi32(__A,__B); } __m512i test_mm512_maskz_packs_epi32(__mmask32 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_packs_epi32 - // CHECK: @llvm.x86.avx512.packssdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_packs_epi32(__M,__A,__B); } __m512i test_mm512_mask_packs_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_packs_epi32 - // CHECK: @llvm.x86.avx512.packssdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_packs_epi32(__W,__M,__A,__B); } __m512i test_mm512_packs_epi16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_packs_epi16 - // CHECK: @llvm.x86.avx512.packsswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> return _mm512_packs_epi16(__A,__B); } __m512i test_mm512_mask_packs_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_packs_epi16 - // CHECK: @llvm.x86.avx512.packsswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_packs_epi16(__W,__M,__A,__B); } __m512i test_mm512_maskz_packs_epi16(__mmask64 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_packs_epi16 - // CHECK: @llvm.x86.avx512.packsswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_packs_epi16(__M,__A,__B); } __m512i test_mm512_packus_epi32(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_packus_epi32 - // CHECK: @llvm.x86.avx512.packusdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> return _mm512_packus_epi32(__A,__B); } __m512i test_mm512_maskz_packus_epi32(__mmask32 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_packus_epi32 - // CHECK: @llvm.x86.avx512.packusdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_maskz_packus_epi32(__M,__A,__B); } __m512i test_mm512_mask_packus_epi32(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_packus_epi32 - // CHECK: @llvm.x86.avx512.packusdw.512 + // CHECK: %{{.*}} = shufflevector <16 x i32> %{{.*}}, <16 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp sgt <32 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i32> %{{.*}}, <32 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i32> %{{.*}} to <32 x i16> // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}} return _mm512_mask_packus_epi32(__W,__M,__A,__B); } __m512i test_mm512_packus_epi16(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_packus_epi16 - // CHECK: @llvm.x86.avx512.packuswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> return _mm512_packus_epi16(__A,__B); } __m512i test_mm512_mask_packus_epi16(__m512i __W, __mmask64 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_mask_packus_epi16 - // CHECK: @llvm.x86.avx512.packuswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_mask_packus_epi16(__W,__M,__A,__B); } __m512i test_mm512_maskz_packus_epi16(__mmask64 __M, __m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_maskz_packus_epi16 - // CHECK: @llvm.x86.avx512.packuswb.512 + // CHECK: %{{.*}} = shufflevector <32 x i16> %{{.*}}, <32 x i16> %{{.*}}, <64 x i32> + // CHECK: %{{.*}} = icmp slt <64 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> + // CHECK: %{{.*}} = icmp sgt <64 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i16> %{{.*}}, <64 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <64 x i16> %{{.*}} to <64 x i8> // CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} return _mm512_maskz_packus_epi16(__M,__A,__B); } Index: clang/test/CodeGen/avx512vlbw-builtins.c =================================================================== --- clang/test/CodeGen/avx512vlbw-builtins.c +++ clang/test/CodeGen/avx512vlbw-builtins.c @@ -970,105 +970,185 @@ __m128i test_mm_maskz_packs_epi32(__mmask8 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_packs_epi32 - // CHECK: @llvm.x86.sse2.packssdw + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_packs_epi32(__M,__A,__B); } __m128i test_mm_mask_packs_epi32(__m128i __W, __mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_packs_epi32 - // CHECK: @llvm.x86.sse2.packssdw + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_packs_epi32(__W,__M,__A,__B); } __m256i test_mm256_maskz_packs_epi32(__mmask16 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_packs_epi32 - // CHECK: @llvm.x86.avx2.packssdw + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_packs_epi32(__M,__A,__B); } __m256i test_mm256_mask_packs_epi32(__m256i __W, __mmask16 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_packs_epi32 - // CHECK: @llvm.x86.avx2.packssdw + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_packs_epi32(__W,__M,__A,__B); } __m128i test_mm_maskz_packs_epi16(__mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_packs_epi16 - // CHECK: @llvm.x86.sse2.packsswb + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_packs_epi16(__M,__A,__B); } __m128i test_mm_mask_packs_epi16(__m128i __W, __mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_packs_epi16 - // CHECK: @llvm.x86.sse2.packsswb + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_packs_epi16(__W,__M,__A,__B); } __m256i test_mm256_maskz_packs_epi16(__mmask32 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_packs_epi16 - // CHECK: @llvm.x86.avx2.packsswb + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_packs_epi16(__M,__A,__B); } __m256i test_mm256_mask_packs_epi16(__m256i __W, __mmask32 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_packs_epi16 - // CHECK: @llvm.x86.avx2.packsswb + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_packs_epi16(__W,__M,__A,__B); } __m128i test_mm_mask_packus_epi32(__m128i __W, __mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_packus_epi32 - // CHECK: @llvm.x86.sse41.packusdw + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_mask_packus_epi32(__W,__M,__A,__B); } __m128i test_mm_maskz_packus_epi32(__mmask8 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_packus_epi32 - // CHECK: @llvm.x86.sse41.packusdw + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}} return _mm_maskz_packus_epi32(__M,__A,__B); } __m256i test_mm256_maskz_packus_epi32(__mmask16 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_packus_epi32 - // CHECK: @llvm.x86.avx2.packusdw + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_maskz_packus_epi32(__M,__A,__B); } __m256i test_mm256_mask_packus_epi32(__m256i __W, __mmask16 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_packus_epi32 - // CHECK: @llvm.x86.avx2.packusdw + // CHECK: %{{.*}} = shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp sgt <16 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i32> %{{.*}} to <16 x i16> // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}} return _mm256_mask_packus_epi32(__W,__M,__A,__B); } __m128i test_mm_maskz_packus_epi16(__mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_maskz_packus_epi16 - // CHECK: @llvm.x86.sse2.packuswb + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_maskz_packus_epi16(__M,__A,__B); } __m128i test_mm_mask_packus_epi16(__m128i __W, __mmask16 __M, __m128i __A, __m128i __B) { // CHECK-LABEL: @test_mm_mask_packus_epi16 - // CHECK: @llvm.x86.sse2.packuswb + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> // CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} return _mm_mask_packus_epi16(__W,__M,__A,__B); } __m256i test_mm256_maskz_packus_epi16(__mmask32 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_maskz_packus_epi16 - // CHECK: @llvm.x86.avx2.packuswb + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_maskz_packus_epi16(__M,__A,__B); } __m256i test_mm256_mask_packus_epi16(__m256i __W, __mmask32 __M, __m256i __A, __m256i __B) { // CHECK-LABEL: @test_mm256_mask_packus_epi16 - // CHECK: @llvm.x86.avx2.packuswb + // CHECK: %{{.*}} = shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <32 x i32> + // CHECK: %{{.*}} = icmp slt <32 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> + // CHECK: %{{.*}} = icmp sgt <32 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <32 x i16> %{{.*}} to <32 x i8> // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} return _mm256_mask_packus_epi16(__W,__M,__A,__B); } Index: clang/test/CodeGen/sse2-builtins.c =================================================================== --- clang/test/CodeGen/sse2-builtins.c +++ clang/test/CodeGen/sse2-builtins.c @@ -869,19 +869,34 @@ __m128i test_mm_packs_epi16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_packs_epi16 - // CHECK: call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> return _mm_packs_epi16(A, B); } __m128i test_mm_packs_epi32(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_packs_epi32 - // CHECK: call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> return _mm_packs_epi32(A, B); } __m128i test_mm_packus_epi16(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_packus_epi16 - // CHECK: call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <16 x i32> + // CHECK: %{{.*}} = icmp slt <16 x i16> %{{.*}}, + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> + // CHECK: %{{.*}} = icmp sgt <16 x i16> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> zeroinitializer + // CHECK: %{{.*}} = trunc <16 x i16> %{{.*}} to <16 x i8> return _mm_packus_epi16(A, B); } Index: clang/test/CodeGen/sse41-builtins.c =================================================================== --- clang/test/CodeGen/sse41-builtins.c +++ clang/test/CodeGen/sse41-builtins.c @@ -328,7 +328,12 @@ __m128i test_mm_packus_epi32(__m128i x, __m128i y) { // CHECK-LABEL: test_mm_packus_epi32 - // CHECK: call <8 x i16> @llvm.x86.sse41.packusdw(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}) + // CHECK: %{{.*}} = shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp slt <8 x i32> %{{.*}}, + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> + // CHECK: %{{.*}} = icmp sgt <8 x i32> %{{.*}}, zeroinitializer + // CHECK: %{{.*}} = select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> zeroinitializer + // CHECK: %{{.*}} = trunc <8 x i32> %{{.*}} to <8 x i16> return _mm_packus_epi32(x, y); }