[llvm-commits] [llvm] r173452 - in /llvm/trunk: lib/Transforms/Instrumentation/MemorySanitizer.cpp test/Instrumentation/MemorySanitizer/msan_basic.ll

Evgeniy Stepanov eugeni.stepanov at gmail.com
Fri Jan 25 07:31:10 PST 2013


Author: eugenis
Date: Fri Jan 25 09:31:10 2013
New Revision: 173452

URL: http://llvm.org/viewvc/llvm-project?rev=173452&view=rev
Log:
[msan] Implement exact shadow propagation for relational ICmp.

Only for integers, pointers, and vectors of those. No floats.
Instrumentation seems very heavy, and may need to be replaced
with some approximation in the future.

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
    llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=173452&r1=173451&r2=173452&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Fri Jan 25 09:31:10 2013
@@ -127,6 +127,10 @@
        cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
        cl::Hidden, cl::init(true));
 
+static cl::opt<bool> ClHandleICmpExact("msan-handle-icmp-exact",
+       cl::desc("exact handling of relational integer ICmp"),
+       cl::Hidden, cl::init(true));
+
 static cl::opt<bool> ClStoreCleanOrigin("msan-store-clean-origin",
        cl::desc("store origin for clean (fully initialized) values"),
        cl::Hidden, cl::init(false));
@@ -1155,6 +1159,70 @@
     setOriginForNaryOp(I);
   }
 
+  /// \brief Build the lowest possible value of V, taking into account V's
+  ///        uninitialized bits.
+  Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
+                                bool isSigned) {
+    if (isSigned) {
+      // Split shadow into sign bit and other bits.
+      Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
+      Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
+      // Maximise the undefined shadow bit, minimize other undefined bits.
+      return
+        IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)), SaSignBit);
+    } else {
+      // Minimize undefined bits.
+      return IRB.CreateAnd(A, IRB.CreateNot(Sa));
+    }
+  }
+
+  /// \brief Build the highest possible value of V, taking into account V's
+  ///        uninitialized bits.
+  Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
+                                bool isSigned) {
+    if (isSigned) {
+      // Split shadow into sign bit and other bits.
+      Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
+      Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
+      // Minimise the undefined shadow bit, maximise other undefined bits.
+      return
+        IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)), SaOtherBits);
+    } else {
+      // Maximize undefined bits.
+      return IRB.CreateOr(A, Sa);
+    }
+  }
+
+  /// \brief Instrument relational comparisons.
+  ///
+  /// This function does exact shadow propagation for all relational
+  /// comparisons of integers, pointers and vectors of those.
+  /// FIXME: output seems suboptimal when one of the operands is a constant
+  void handleRelationalComparisonExact(ICmpInst &I) {
+    IRBuilder<> IRB(&I);
+    Value *A = I.getOperand(0);
+    Value *B = I.getOperand(1);
+    Value *Sa = getShadow(A);
+    Value *Sb = getShadow(B);
+
+    // Get rid of pointers and vectors of pointers.
+    // For ints (and vectors of ints), types of A and Sa match,
+    // and this is a no-op.
+    A = IRB.CreatePointerCast(A, Sa->getType());
+    B = IRB.CreatePointerCast(B, Sb->getType());
+
+    bool IsSigned = I.isSigned();
+    Value *S1 = IRB.CreateICmp(I.getPredicate(),
+                               getLowestPossibleValue(IRB, A, Sa, IsSigned),
+                               getHighestPossibleValue(IRB, B, Sb, IsSigned));
+    Value *S2 = IRB.CreateICmp(I.getPredicate(),
+                               getHighestPossibleValue(IRB, A, Sa, IsSigned),
+                               getLowestPossibleValue(IRB, B, Sb, IsSigned));
+    Value *Si = IRB.CreateXor(S1, S2);
+    setShadow(&I, Si);
+    setOriginForNaryOp(I);
+  }
+
   /// \brief Instrument signed relational comparisons.
   ///
   /// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by
@@ -1186,6 +1254,8 @@
   void visitICmpInst(ICmpInst &I) {
     if (ClHandleICmp && I.isEquality())
       handleEqualityComparison(I);
+    else if (ClHandleICmp && ClHandleICmpExact && I.isRelational())
+      handleRelationalComparisonExact(I);
     else if (ClHandleICmp && I.isSigned() && I.isRelational())
       handleSignedRelationalComparison(I);
     else

Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll?rev=173452&r1=173451&r2=173452&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll Fri Jan 25 09:31:10 2013
@@ -323,6 +323,8 @@
 ; CHECK-NOT: call void @__msan_warning
 ; CHECK: icmp slt
 ; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp slt
+; CHECK-NOT: call void @__msan_warning
 ; CHECK: ret i1
 
 define zeroext i1 @ICmpSGE(i32 %x) nounwind uwtable readnone {
@@ -331,7 +333,9 @@
 }
 
 ; CHECK: @ICmpSGE
-; CHECK: icmp slt
+; CHECK: icmp sge
+; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp sge
 ; CHECK-NOT: call void @__msan_warning
 ; CHECK: icmp sge
 ; CHECK-NOT: call void @__msan_warning
@@ -343,7 +347,9 @@
 }
 
 ; CHECK: @ICmpSGT
-; CHECK: icmp slt
+; CHECK: icmp sgt
+; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp sgt
 ; CHECK-NOT: call void @__msan_warning
 ; CHECK: icmp sgt
 ; CHECK-NOT: call void @__msan_warning
@@ -355,7 +361,9 @@
 }
 
 ; CHECK: @ICmpSLE
-; CHECK: icmp slt
+; CHECK: icmp sle
+; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp sle
 ; CHECK-NOT: call void @__msan_warning
 ; CHECK: icmp sle
 ; CHECK-NOT: call void @__msan_warning
@@ -373,11 +381,31 @@
 ; CHECK: @ICmpSLT_vector
 ; CHECK: icmp slt <2 x i64>
 ; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp slt <2 x i64>
+; CHECK-NOT: call void @__msan_warning
 ; CHECK: icmp slt <2 x i32*>
 ; CHECK-NOT: call void @__msan_warning
 ; CHECK: ret <2 x i1>
 
 
+; Check that we propagate shadow for arbitrary relational comparisons
+
+define zeroext i1 @ICmpSLENonZero(i32 %x, i32 %y) nounwind uwtable readnone {
+entry:
+  %cmp = icmp sle i32 %x, %y
+  ret i1 %cmp
+}
+
+; CHECK: @ICmpSLENonZero
+; CHECK: icmp sle i32
+; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp sle i32
+; CHECK-NOT: call void @__msan_warning
+; CHECK: icmp sle i32
+; CHECK-NOT: call void @__msan_warning
+; CHECK: ret i1
+
+
 ; Check that loads of shadow have the same aligment as the original loads.
 ; Check that loads of origin have the aligment of max(4, original alignment).
 





More information about the llvm-commits mailing list