Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ 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(); + bool IsDW = Ty->getScalarSizeInBits() == 32; + uint64_t MinVal, MaxVal; + if (IsUnsigned) { + MinVal = (IsDW) ? llvm::APInt::getMinValue(16).getZExtValue() + : llvm::APInt::getMinValue(8).getZExtValue(); + MaxVal = (IsDW) ? llvm::APInt::getMaxValue(16).getZExtValue() + : llvm::APInt::getMaxValue(8).getZExtValue(); + } else { + MinVal = (IsDW) ? llvm::APInt::getSignedMinValue(16).getSExtValue() + : llvm::APInt::getSignedMinValue(8).getSExtValue(); + MaxVal = (IsDW) ? llvm::APInt::getSignedMaxValue(16).getSExtValue() + : llvm::APInt::getSignedMaxValue(8).getSExtValue(); + } + int NumElts = 2 * Ty->getVectorNumElements(); + SmallVector ShuffleMask; + ShuffleMask.clear(); + for (int i = 0, i1 = 0, i2 = 0, d = (IsDW) ? 4 : 8; i < NumElts; ++i) + if ((i / d) & 1) + ShuffleMask.push_back(NumElts / 2 + i2++); + else + ShuffleMask.push_back(i1++); + Value *Res = + CGF.Builder.CreateShuffleVector(A, B, ArrayRef(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( + (IsDW) ? CGF.Builder.getInt16Ty() : CGF.Builder.getInt8Ty(), NumElts); + 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: test/CodeGen/avx2-builtins.c =================================================================== --- test/CodeGen/avx2-builtins.c +++ 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: test/CodeGen/avx512bw-builtins.c =================================================================== --- test/CodeGen/avx512bw-builtins.c +++ 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: test/CodeGen/avx512vlbw-builtins.c =================================================================== --- test/CodeGen/avx512vlbw-builtins.c +++ 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: test/CodeGen/sse2-builtins.c =================================================================== --- test/CodeGen/sse2-builtins.c +++ 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: test/CodeGen/sse41-builtins.c =================================================================== --- test/CodeGen/sse41-builtins.c +++ 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); }