[llvm] bddc814 - [msan] Copy origin of byval arguments

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 27 16:24:20 PST 2022


Author: Vitaly Buka
Date: 2022-01-27T16:24:07-08:00
New Revision: bddc814b442ae9f30d62e2f881274d6255411225

URL: https://github.com/llvm/llvm-project/commit/bddc814b442ae9f30d62e2f881274d6255411225
DIFF: https://github.com/llvm/llvm-project/commit/bddc814b442ae9f30d62e2f881274d6255411225.diff

LOG: [msan] Copy origin of byval arguments

Depends on D117278

Reviewed By: kda, eugenis

Differential Revision: https://reviews.llvm.org/D117285

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index cfe993dedbc2e..c51acdf52f14d 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -182,6 +182,7 @@
 #include "llvm/IR/ValueMap.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/Alignment.h"
 #include "llvm/Support/AtomicOrdering.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
@@ -1718,11 +1719,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
             // Figure out maximal valid memcpy alignment.
             const Align ArgAlign = DL.getValueOrABITypeAlignment(
                 MaybeAlign(FArg.getParamAlignment()), FArg.getParamByValType());
-            Value *CpShadowPtr =
+            Value *CpShadowPtr, *CpOriginPtr;
+            std::tie(CpShadowPtr, CpOriginPtr) =
                 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
-                                   /*isStore*/ true)
-                    .first;
-            // TODO(glider): need to copy origins.
+                                   /*isStore*/ true);
             if (!PropagateShadow || Overflow) {
               // ParamTLS overflow.
               EntryIRB.CreateMemSet(
@@ -1735,6 +1735,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
                                                  CopyAlign, Size);
               LLVM_DEBUG(dbgs() << "  ByValCpy: " << *Cpy << "\n");
               (void)Cpy;
+
+              if (MS.TrackOrigins) {
+                Value *OriginPtr =
+                    getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset);
+                // FIXME: OriginSize should be:
+                // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
+                unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
+                EntryIRB.CreateMemCpy(
+                    CpOriginPtr,
+                    /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
+                    /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
+                    OriginSize);
+              }
             }
           }
 
@@ -3701,7 +3714,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
         insertShadowCheck(A, &CB);
         Size = DL.getTypeAllocSize(A->getType());
       } else {
-        bool ArgIsInitialized = false;
         Value *Store = nullptr;
         // Compute the Shadow for arg even if it is ByVal, because
         // in that case getShadow() will copy the actual arg shadow to
@@ -3722,10 +3734,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
           MaybeAlign Alignment = llvm::None;
           if (ParamAlignment)
             Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
-          Value *AShadowPtr =
+          Value *AShadowPtr, *AOriginPtr;
+          std::tie(AShadowPtr, AOriginPtr) =
               getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
-                                 /*isStore*/ false)
-                  .first;
+                                 /*isStore*/ false);
           if (!PropagateShadow) {
             Store = IRB.CreateMemSet(ArgShadowBase,
                                      Constant::getNullValue(IRB.getInt8Ty()),
@@ -3733,6 +3745,17 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
           } else {
             Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
                                      Alignment, Size);
+            if (MS.TrackOrigins) {
+              Value *ArgOriginBase = getOriginPtrForArgument(A, IRB, ArgOffset);
+              // FIXME: OriginSize should be:
+              // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
+              unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
+              IRB.CreateMemCpy(
+                  ArgOriginBase,
+                  /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
+                  AOriginPtr,
+                  /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
+            }
           }
         } else {
           // Any other parameters mean we need bit-grained tracking of uninit
@@ -3743,12 +3766,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
           Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
                                          kShadowTLSAlignment);
           Constant *Cst = dyn_cast<Constant>(ArgShadow);
-          if (Cst && Cst->isNullValue())
-            ArgIsInitialized = true;
+          if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
+            IRB.CreateStore(getOrigin(A),
+                            getOriginPtrForArgument(A, IRB, ArgOffset));
+          }
         }
-        if (MS.TrackOrigins && !ArgIsInitialized)
-          IRB.CreateStore(getOrigin(A),
-                          getOriginPtrForArgument(A, IRB, ArgOffset));
         (void)Store;
         assert(Store != nullptr);
         LLVM_DEBUG(dbgs() << "  Param:" << *Store << "\n");

diff  --git a/llvm/test/Instrumentation/MemorySanitizer/byval.ll b/llvm/test/Instrumentation/MemorySanitizer/byval.ll
index efc03af25674c..8f150e9b1a6db 100644
--- a/llvm/test/Instrumentation/MemorySanitizer/byval.ll
+++ b/llvm/test/Instrumentation/MemorySanitizer/byval.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -S -passes="msan<track-origins=1>" 2>&1 | FileCheck %s --implicit-check-not "call void @llvm.mem" --implicit-check-not " load" --implicit-check-not " store"
 ; RUN: opt < %s -S -msan -msan-track-origins=1 | FileCheck %s --implicit-check-not "call void @llvm.mem" --implicit-check-not " load" --implicit-check-not " store"
 
@@ -12,6 +11,7 @@ define i128 @ByValArgument(i32, i128* byval(i128) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValArgument(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[#]], i8* align 8 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 16, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 16, i1 false)
 ; CHECK:         [[X:%.*]] = load i128, i128* %p, align 8
 ; CHECK:         [[_MSLD:%.*]] = load i128, i128* %[[#]], align 8
 ; CHECK:         %[[#]] = load i32, i32* %[[#]], align 8
@@ -38,11 +38,11 @@ entry:
   ret i128 %x
 }
 
-; FIXME: Origin of byval pointee is not propagated.
 define void @ByValForward(i32, i128* byval(i128) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValForward(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[#]], i8* align 8 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 16, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 16, i1 false)
 ; CHECK:         store i64 0, i64* getelementptr inbounds ([100 x i64], [100 x i64]* @__msan_param_tls, i32 0, i32 0), align 8
 ; CHECK:         call void @Fn(i128* %p)
 ; CHECK:         ret void
@@ -65,13 +65,13 @@ entry:
   ret void
 }
 
-; FIXME: Origin of %p byval pointee is not propagated.
 define void @ByValForwardByVal(i32, i128* byval(i128) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValForwardByVal(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %[[#]], i8* align 8 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 16, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 16, i1 false)
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8* %[[#]], i64 16, i1 false)
-; CHECK:         store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0), align 4
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 bitcast ([200 x i32]* @__msan_param_origin_tls to i8*), i8* align 4 %[[#]], i64 16, i1 false)
 ; CHECK:         call void @FnByVal(i128* byval(i128) %p)
 ; CHECK:         ret void
 ;
@@ -85,7 +85,6 @@ define void @ByValForwardByValNoSanitize(i32, i128* byval(i128) %p) {
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memset.p0i8.i64(i8* align 8 %[[#]], i8 0, i64 16, i1 false)
 ; CHECK:         call void @llvm.memset.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8 0, i64 16, i1 false)
-; CHECK:         store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0), align 4
 ; CHECK:         call void @FnByVal(i128* byval(i128) %p)
 ; CHECK:         ret void
 ;
@@ -101,6 +100,7 @@ define i8 @ByValArgument8(i32, i8* byval(i8) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValArgument8(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %[[#]], i8* align 1 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 1, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 4, i1 false)
 ; CHECK:         [[X:%.*]] = load i8, i8* %p, align 1
 ; CHECK:         [[_MSLD:%.*]] = load i8, i8* %[[#]], align 1
 ; CHECK:         %[[#]] = load i32, i32* %[[#]], align 4
@@ -131,6 +131,7 @@ define void @ByValForward8(i32, i8* byval(i8) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValForward8(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %[[#]], i8* align 1 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 1, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 4, i1 false)
 ; CHECK:         store i64 0, i64* getelementptr inbounds ([100 x i64], [100 x i64]* @__msan_param_tls, i32 0, i32 0), align 8
 ; CHECK:         call void @Fn8(i8* %p)
 ; CHECK:         ret void
@@ -157,8 +158,9 @@ define void @ByValForwardByVal8(i32, i8* byval(i8) %p) sanitize_memory {
 ; CHECK-LABEL: @ByValForwardByVal8(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %[[#]], i8* align 1 inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_param_tls to i64), i64 8) to i8*), i64 1, i1 false)
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %[[#]], i8* align 4 inttoptr (i64 add (i64 ptrtoint ([200 x i32]* @__msan_param_origin_tls to i64), i64 8) to i8*), i64 4, i1 false)
 ; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8* %[[#]], i64 1, i1 false)
-; CHECK:         store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0), align 4
+; CHECK:         call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 bitcast ([200 x i32]* @__msan_param_origin_tls to i8*), i8* align 4 %[[#]], i64 4, i1 false)
 ; CHECK:         call void @FnByVal8(i8* byval(i8) %p)
 ; CHECK:         ret void
 ;
@@ -167,13 +169,11 @@ entry:
   ret void
 }
 
-; FIXME: Shadow for byval should be reset not copied before the call.
 define void @ByValForwardByValNoSanitize8(i32, i8* byval(i8) %p) {
 ; CHECK-LABEL: @ByValForwardByValNoSanitize8(
 ; CHECK-NEXT:  entry:
 ; CHECK:         call void @llvm.memset.p0i8.i64(i8* align 1 %[[#]], i8 0, i64 1, i1 false)
 ; CHECK:         call void @llvm.memset.p0i8.i64(i8* bitcast ([100 x i64]* @__msan_param_tls to i8*), i8 0, i64 1, i1 false)
-; CHECK:         store i32 0, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__msan_param_origin_tls, i32 0, i32 0), align 4
 ; CHECK:         call void @FnByVal8(i8* byval(i8) %p)
 ; CHECK:         ret void
 ;


        


More information about the llvm-commits mailing list