mike.dvoretsky updated this revision to Diff 143893. mike.dvoretsky marked 4 inline comments as done. mike.dvoretsky added a subscriber: ashlykov. mike.dvoretsky added a comment.
Updated per comments. https://reviews.llvm.org/D45722 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/avx2-builtins.c clang/test/CodeGen/avx512bw-builtins.c clang/test/CodeGen/sse2-builtins.c
Index: clang/test/CodeGen/sse2-builtins.c =================================================================== --- clang/test/CodeGen/sse2-builtins.c +++ clang/test/CodeGen/sse2-builtins.c @@ -893,7 +893,33 @@ __m128i test_mm_sad_epu8(__m128i A, __m128i B) { // CHECK-LABEL: test_mm_sad_epu8 - // CHECK: call <2 x i64> @llvm.x86.sse2.psad.bw(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: %{{.*}} = icmp ugt <16 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <16 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <16 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 0, i32 8> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 1, i32 9> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 2, i32 10> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 3, i32 11> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 4, i32 12> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 5, i32 13> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 6, i32 14> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <2 x i32> <i32 7, i32 15> + // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64> + // CHECK: %{{.*}} = add <2 x i64> %{{.*}}, %{{.*}} return _mm_sad_epu8(A, B); } Index: clang/test/CodeGen/avx512bw-builtins.c =================================================================== --- clang/test/CodeGen/avx512bw-builtins.c +++ clang/test/CodeGen/avx512bw-builtins.c @@ -1945,7 +1945,33 @@ __m512i test_mm512_sad_epu8(__m512i __A, __m512i __B) { // CHECK-LABEL: @test_mm512_sad_epu8 - // CHECK: @llvm.x86.avx512.psad.bw.512 + // CHECK: %{{.*}} = icmp ugt <64 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <64 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <64 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 0, i32 8, i32 16, i32 24, i32 32, i32 40, i32 48, i32 56> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 1, i32 9, i32 17, i32 25, i32 33, i32 41, i32 49, i32 57> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 2, i32 10, i32 18, i32 26, i32 34, i32 42, i32 50, i32 58> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 3, i32 11, i32 19, i32 27, i32 35, i32 43, i32 51, i32 59> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 4, i32 12, i32 20, i32 28, i32 36, i32 44, i32 52, i32 60> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 5, i32 13, i32 21, i32 29, i32 37, i32 45, i32 53, i32 61> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 6, i32 14, i32 22, i32 30, i32 38, i32 46, i32 54, i32 62> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <64 x i8> %{{.*}}, <64 x i8> %{{.*}}, <8 x i32> <i32 7, i32 15, i32 23, i32 31, i32 39, i32 47, i32 55, i32 63> + // CHECK: %{{.*}} = zext <8 x i8> %{{.*}} to <8 x i64> + // CHECK: %{{.*}} = add <8 x i64> %{{.*}}, %{{.*}} return _mm512_sad_epu8(__A, __B); } Index: clang/test/CodeGen/avx2-builtins.c =================================================================== --- clang/test/CodeGen/avx2-builtins.c +++ clang/test/CodeGen/avx2-builtins.c @@ -943,7 +943,33 @@ __m256i test_mm256_sad_epu8(__m256i x, __m256i y) { // CHECK-LABEL: test_mm256_sad_epu8 - // CHECK: call <4 x i64> @llvm.x86.avx2.psad.bw(<32 x i8> %{{.*}}, <32 x i8> %{{.*}}) + // CHECK: %{{.*}} = icmp ugt <32 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <32 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = sub <32 x i8> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 0, i32 8, i32 16, i32 24> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 1, i32 9, i32 17, i32 25> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 2, i32 10, i32 18, i32 26> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 3, i32 11, i32 19, i32 27> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 4, i32 12, i32 20, i32 28> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 5, i32 13, i32 21, i32 29> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 6, i32 14, i32 22, i32 30> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} + // CHECK: %{{.*}} = shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <4 x i32> <i32 7, i32 15, i32 23, i32 31> + // CHECK: %{{.*}} = zext <4 x i8> %{{.*}} to <4 x i64> + // CHECK: %{{.*}} = add <4 x i64> %{{.*}}, %{{.*}} return _mm256_sad_epu8(x, y); } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -8408,6 +8408,34 @@ return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); } +// Lowers PSAD intrinsics to native IR. +static Value *EmitX86SAD(CodeGenFunction &CGF, ArrayRef<Value *> Ops) { + // The operands arrive already bitcast to byte vectors. + Value *A = Ops[0]; + Value *B = Ops[1]; + // N shows the corresponding number of qwords. + unsigned N = (cast<llvm::VectorType>(A->getType()))->getBitWidth() / 64; + + Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGT, A, B); + Value *AD = CGF.Builder.CreateSelect(Cmp, CGF.Builder.CreateSub(A, B), + CGF.Builder.CreateSub(B, A)); + + llvm::Type *QTy = CGF.Builder.getInt64Ty(); + llvm::Type *VTy = llvm::VectorType::get(QTy, N); + SmallVector<uint32_t, 8> ShuffleMask(N); + for (unsigned i = 0; i < N; ++i) + ShuffleMask[i] = i * 8; + Value *Res = CGF.Builder.CreateZExt( + CGF.Builder.CreateShuffleVector(AD, AD, ShuffleMask), VTy); + for (unsigned i = 1; i < 8; ++i) { + for (unsigned j = 0; j < N; ++j) + ShuffleMask[j] = i + j * 8; + Value *Sum = CGF.Builder.CreateShuffleVector(AD, AD, ShuffleMask); + Res = CGF.Builder.CreateAdd(Res, CGF.Builder.CreateZExt(Sum, VTy)); + } + return Res; +} + Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString(); @@ -9052,6 +9080,11 @@ case X86::BI__builtin_ia32_pabsq512_mask: return EmitX86Abs(*this, Ops); + case X86::BI__builtin_ia32_psadbw128: + case X86::BI__builtin_ia32_psadbw256: + case X86::BI__builtin_ia32_psadbw512: + return EmitX86SAD(*this, Ops); + case X86::BI__builtin_ia32_pmaxsb128: case X86::BI__builtin_ia32_pmaxsw128: case X86::BI__builtin_ia32_pmaxsd128:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits