Index: lib/Headers/avx2intrin.h =================================================================== --- lib/Headers/avx2intrin.h +++ lib/Headers/avx2intrin.h @@ -160,7 +160,23 @@ #define _mm256_blend_epi16(V1, V2, M) __extension__ ({ \ __m256i __V1 = (V1); \ __m256i __V2 = (V2); \ - (__m256i)__builtin_ia32_pblendw256((__v16hi)__V1, (__v16hi)__V2, (M)); }) + (__m256d)__builtin_shufflevector((__v16hi)__V1, (__v16hi)__V2, \ + (((M) & 0x01) ? 16 : 0), \ + (((M) & 0x02) ? 17 : 1), \ + (((M) & 0x04) ? 18 : 2), \ + (((M) & 0x08) ? 19 : 3), \ + (((M) & 0x10) ? 20 : 4), \ + (((M) & 0x20) ? 21 : 5), \ + (((M) & 0x40) ? 22 : 6), \ + (((M) & 0x80) ? 23 : 7), \ + (((M) & 0x01) ? 24 : 8), \ + (((M) & 0x02) ? 25 : 9), \ + (((M) & 0x04) ? 26 : 10), \ + (((M) & 0x08) ? 27 : 11), \ + (((M) & 0x10) ? 28 : 12), \ + (((M) & 0x20) ? 29 : 13), \ + (((M) & 0x40) ? 30 : 14), \ + (((M) & 0x80) ? 31 : 15)); }) static __inline__ __m256i __attribute__((__always_inline__, __nodebug__)) _mm256_cmpeq_epi8(__m256i __a, __m256i __b) @@ -761,12 +777,24 @@ #define _mm_blend_epi32(V1, V2, M) __extension__ ({ \ __m128i __V1 = (V1); \ __m128i __V2 = (V2); \ - (__m128i)__builtin_ia32_pblendd128((__v4si)__V1, (__v4si)__V2, (M)); }) + (__m128i)__builtin_shufflevector((__v4si)__V1, (__v4si)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) #define _mm256_blend_epi32(V1, V2, M) __extension__ ({ \ __m256i __V1 = (V1); \ __m256i __V2 = (V2); \ - (__m256i)__builtin_ia32_pblendd256((__v8si)__V1, (__v8si)__V2, (M)); }) + (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) static __inline__ __m256i __attribute__((__always_inline__, __nodebug__)) _mm256_broadcastb_epi8(__m128i __X) Index: lib/Headers/avxintrin.h =================================================================== --- lib/Headers/avxintrin.h +++ lib/Headers/avxintrin.h @@ -308,12 +308,24 @@ #define _mm256_blend_pd(V1, V2, M) __extension__ ({ \ __m256d __V1 = (V1); \ __m256d __V2 = (V2); \ - (__m256d)__builtin_ia32_blendpd256((__v4df)__V1, (__v4df)__V2, (M)); }) + (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) #define _mm256_blend_ps(V1, V2, M) __extension__ ({ \ __m256 __V1 = (V1); \ __m256 __V2 = (V2); \ - (__m256)__builtin_ia32_blendps256((__v8sf)__V1, (__v8sf)__V2, (M)); }) + (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) static __inline __m256d __attribute__((__always_inline__, __nodebug__)) _mm256_blendv_pd(__m256d __a, __m256d __b, __m256d __c) Index: lib/Headers/smmintrin.h =================================================================== --- lib/Headers/smmintrin.h +++ lib/Headers/smmintrin.h @@ -79,12 +79,18 @@ #define _mm_blend_pd(V1, V2, M) __extension__ ({ \ __m128d __V1 = (V1); \ __m128d __V2 = (V2); \ - (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, (M)); }) + (__m128d)__builtin_shufflevector((__v2df)__V1, (__v2df)__V2, \ + (((M) & 0x01) ? 2 : 0), \ + (((M) & 0x02) ? 3 : 1)); }) #define _mm_blend_ps(V1, V2, M) __extension__ ({ \ __m128 __V1 = (V1); \ __m128 __V2 = (V2); \ - (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, (M)); }) + (__m128)__builtin_shufflevector((__v4sf)__V1, (__v4sf)__V2, \ + (((M) & 0x01) ? 4 : 0), \ + (((M) & 0x02) ? 5 : 1), \ + (((M) & 0x04) ? 6 : 2), \ + (((M) & 0x08) ? 7 : 3)); }) static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) _mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M) @@ -110,7 +116,15 @@ #define _mm_blend_epi16(V1, V2, M) __extension__ ({ \ __m128i __V1 = (V1); \ __m128i __V2 = (V2); \ - (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, (M)); }) + (__m128i)__builtin_shufflevector((__v8hi)__V1, (__v8hi)__V2, \ + (((M) & 0x01) ? 8 : 0), \ + (((M) & 0x02) ? 9 : 1), \ + (((M) & 0x04) ? 10 : 2), \ + (((M) & 0x08) ? 11 : 3), \ + (((M) & 0x10) ? 12 : 4), \ + (((M) & 0x20) ? 13 : 5), \ + (((M) & 0x40) ? 14 : 6), \ + (((M) & 0x80) ? 15 : 7)); }) /* SSE4 Dword Multiply Instructions. */ static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) Index: test/CodeGen/avx-builtins.c =================================================================== --- test/CodeGen/avx-builtins.c +++ test/CodeGen/avx-builtins.c @@ -111,3 +111,15 @@ // CHECK: extractelement <32 x i8> %{{.*}}, i32 0 return _mm256_extract_epi8(__a, 32); } + +__m256d test_256_blend_pd(__m256d __a, __m256d __b) { + // CHECK-LABEL: @test_256_blend_pd + // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> + return _mm256_blend_pd(__a, __b, 57); +} + +__m256 test_256_blend_ps(__m256 __a, __m256 __b) { + // CHECK-LABEL: @test_256_blend_ps + // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> + return _mm256_blend_ps(__a, __b, 57); +} Index: test/CodeGen/avx2-builtins.c =================================================================== --- test/CodeGen/avx2-builtins.c +++ test/CodeGen/avx2-builtins.c @@ -177,7 +177,8 @@ } __m256i test_mm256_blend_epi16(__m256i a, __m256i b) { - // CHECK: @llvm.x86.avx2.pblendw(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, i32 2) + // CHECK-LABEL: test_mm256_blend_epi16 + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> return _mm256_blend_epi16(a, b, 2); } @@ -612,12 +613,12 @@ } __m128i test_mm_blend_epi32(__m128i a, __m128i b) { - // CHECK: @llvm.x86.avx2.pblendd.128 + // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> return _mm_blend_epi32(a, b, 57); } __m256i test_mm256_blend_epi32(__m256i a, __m256i b) { - // CHECK: @llvm.x86.avx2.pblendd.256 + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> return _mm256_blend_epi32(a, b, 57); } Index: test/CodeGen/sse-builtins.c =================================================================== --- test/CodeGen/sse-builtins.c +++ test/CodeGen/sse-builtins.c @@ -237,3 +237,21 @@ // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 0 _mm_insert_epi32(__a, b, 4); } + +__m128d test_blend_pd(__m128d V1, __m128d V2) { + // CHECK-LABEL: @test_blend_pd + // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> + return _mm_blend_pd(V1, V2, 1); +} + +__m128 test_blend_ps(__m128 V1, __m128 V2) { + // CHECK-LABEL: @test_blend_ps + // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x i32> + return _mm_blend_ps(V1, V2, 5); +} + +__m128i test_blend_epi16(__m128i V1, __m128i V2) { + // CHECK-LABEL: @test_blend_epi16 + // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> + return _mm_blend_epi16(V1, V2, 42); +}