[PATCH] D82398: [MSAN] Handle x86 {round,min,max}sd intrinsics

Gui Andrade via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 23 11:15:55 PDT 2020


guiand created this revision.
guiand added a reviewer: eugenis.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.
guiand updated this revision to Diff 272776.
guiand added a comment.

Ran clang-format


These need special handling over the simple vector intrinsics as they behave more like a shuffle operation: taking the top half of the vector from one input, and the bottom half separately. Previously, these were being handled as though all bits of all operands were combined.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82398

Files:
  clang/test/CodeGen/msan-intrinsics.c
  llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp


Index: llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3054,6 +3054,32 @@
     SOC.Done(&I);
   }
 
+  // Instrument _mm_*_sd intrinsics
+  void handleUnarySdIntrinsic(IntrinsicInst &I) {
+    IRBuilder<> IRB(&I);
+    Value *First = getShadow(&I, 0);
+    Value *Second = getShadow(&I, 1);
+    Value *LowShadow =
+        IRB.CreateExtractElement(Second, IRB.getInt32(0), "_lo_a");
+    Value *Shadow = IRB.CreateInsertElement(First, LowShadow, IRB.getInt32(0));
+
+    setShadow(&I, Shadow);
+    setOriginForNaryOp(I);
+  }
+
+  void handleBinarySdIntrinsic(IntrinsicInst &I) {
+    IRBuilder<> IRB(&I);
+    Value *First = getShadow(&I, 0);
+    Value *Second = getShadow(&I, 1);
+    Value *LowA = IRB.CreateExtractElement(First, IRB.getInt32(0), "_lo_a");
+    Value *LowB = IRB.CreateExtractElement(Second, IRB.getInt32(0), "_lo_b");
+    Value *LowShadow = IRB.CreateOr(LowA, LowB);
+    Value *Shadow = IRB.CreateInsertElement(Second, LowShadow, IRB.getInt32(0));
+
+    setShadow(&I, Shadow);
+    setOriginForNaryOp(I);
+  }
+
   void visitIntrinsicInst(IntrinsicInst &I) {
     switch (I.getIntrinsicID()) {
     case Intrinsic::lifetime_start:
@@ -3293,6 +3319,13 @@
       handlePclmulIntrinsic(I);
       break;
 
+    case Intrinsic::x86_sse41_round_sd:
+      handleUnarySdIntrinsic(I);
+      break;
+    case Intrinsic::x86_sse2_max_sd:
+    case Intrinsic::x86_sse2_min_sd:
+      handleBinarySdIntrinsic(I);
+      break;
     case Intrinsic::is_constant:
       // The result of llvm.is.constant() is always defined.
       setShadow(&I, getCleanShadow(&I));
Index: clang/test/CodeGen/msan-intrinsics.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/msan-intrinsics.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsanitize=memory -triple x86_64-linux-gnu -emit-llvm %s -O3 -o - | FileCheck %s
+
+typedef double double2 __attribute__((vector_size(16)));
+
+__attribute__((target("sse4.1")))
+double2
+RoundSD(double theta, double top) {
+  // CHECK: [[IN_SHADOW1:%[0-9]+]] = load {{.*}} @__msan_param_tls
+  // CHECK: [[IN_SHADOW2:%[0-9]+]] = load {{.*}} @__msan_param_tls
+  double2 vec;
+  double2 unused;
+  unused[1] = top;
+  vec[0] = theta;
+  return __builtin_ia32_roundsd(unused, vec, 1);
+  // CHECK: [[TMP_SHADOW:%.+]] = insertelement <2 x i64> undef, i64 [[IN_SHADOW2]], i32 1
+  // CHECK: [[OUT_SHADOW:%.+]] = insertelement <2 x i64> [[TMP_SHADOW]], i64 [[IN_SHADOW1]], i32 0
+
+  // CHECK-NOT: call void @msan_warning
+  // CHECK: call <2 x double> @llvm.x86.sse41.round.sd
+  // CHECK: store <2 x i64> [[OUT_SHADOW]], {{.*}} @__msan_retval_tls
+  // CHECK: ret <2 x double>
+}
+
+__attribute__((target("sse2"))) double MinSD(double t1, double t2) {
+  // CHECK: [[IN_SHADOW1:%[0-9]+]] = load {{.*}} @__msan_param_tls
+  // CHECK: [[IN_SHADOW2:%[0-9]+]] = load {{.*}} @__msan_param_tls
+  // CHECK: [[COMB_SHADOW:%[0-9]+]] = or i64 [[IN_SHADOW2]], [[IN_SHADOW1]]
+  double2 first;
+  double2 second;
+  first[0] = t1;
+  second[0] = t2;
+  double min = __builtin_ia32_minsd(first, second)[0];
+  // CHECK-NOT: call void @msan_warning
+  // CHECK: call <2 x double> @llvm.x86.sse2.min.sd
+  return min;
+  // CHECK: store i64 [[COMB_SHADOW]], {{.*}} @__msan_retval_tls
+  // CHECK: ret double
+}
\ No newline at end of file


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82398.272776.patch
Type: text/x-patch
Size: 3509 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200623/564e9d4e/attachment-0001.bin>


More information about the cfe-commits mailing list