mike.dvoretsky updated this revision to Diff 142914.
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> undef, <2 x i32> <i32 0, i32 8>
+  // CHECK: %{{.*}} = zext <2 x i8> %{{.*}} to <2 x i64>
+  // CHECK: %{{.*}} = shufflevector <16 x i8> %{{.*}}, <16 x i8> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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> undef, <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,39 @@
   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);
+  llvm::Type *BTy = llvm::VectorType::get(CGF.Builder.getInt8Ty(), N * 8);
+  SmallVector<uint32_t, 8> ShuffleMask;
+  for (unsigned i = 0; i < N; ++i)
+    ShuffleMask.push_back(i * 8);
+  Value *Res =
+      CGF.Builder.CreateZExt(CGF.Builder.CreateShuffleVector(
+                                 AD, llvm::UndefValue::get(BTy), ShuffleMask),
+                             VTy);
+  for (unsigned i = 1; i < 8; ++i) {
+    ShuffleMask.clear();
+    for (unsigned j = 0; j < N; ++j)
+      ShuffleMask.push_back(i + j * 8);
+    Value *Sum = CGF.Builder.CreateShuffleVector(AD, llvm::UndefValue::get(BTy),
+                                                 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 +9085,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

Reply via email to