[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