[llvm] [msan] Generalize handleIntrinsicByApplyingToShadow to allow alternative intrinsic for shadows (PR #124831)
Thurston Dang via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 28 12:33:16 PST 2025
https://github.com/thurstond updated https://github.com/llvm/llvm-project/pull/124831
>From fa429558ffd95492eebe5a6578b962c948a18e50 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 28 Jan 2025 20:10:34 +0000
Subject: [PATCH 1/2] [msan] Generalize handleIntrinsicByApplyingToShadow to
allow alternative intrinsic for shadows
https://github.com/llvm/llvm-project/pull/124159 uses
handleIntrinsicByApplyingToShadow for horizontal add/sub, but Vitaly
recommends always using the add version to avoid false negatives for
fully uninitialized data (https://github.com/llvm/llvm-project/issues/124662).
This patch lays the groundwork by generalizing handleIntrinsicByApplyingToShadow to allow using
a different intrinsic (of the same type as the original intrinsic) for the shadow. Planned work will apply it to horizontal sub.
---
.../Instrumentation/MemorySanitizer.cpp | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 0d4be09846b604..d2d6a2391a686a 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -4049,7 +4049,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// consider this an acceptable tradeoff for performance.
// To make shadow propagation precise, we want the equivalent of
// "horizontal OR", but this is not available.
- return handleIntrinsicByApplyingToShadow(I, /* trailingVerbatimArgs */ 0);
+ return handleIntrinsicByApplyingToShadow(
+ I, /*trailingVerbatimArgs*/ 0, /*shadowIntrinsicID=*/std::nullopt);
}
/// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
@@ -4156,6 +4157,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// shadow[out] =
/// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
///
+ /// Optionally, the intrinsic for the shadow can be replaced with another
+ /// intrinsic of the same type.
+ ///
/// CAUTION: this assumes that the intrinsic will handle arbitrary
/// bit-patterns (for example, if the intrinsic accepts floats for
/// var1, we require that it doesn't care if inputs are NaNs).
@@ -4164,8 +4168,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// (tbl{1,2,3,4}).
///
/// The origin is approximated using setOriginForNaryOp.
- void handleIntrinsicByApplyingToShadow(IntrinsicInst &I,
- unsigned int trailingVerbatimArgs) {
+ void handleIntrinsicByApplyingToShadow(
+ IntrinsicInst &I, unsigned int trailingVerbatimArgs,
+ std::optional<Intrinsic::ID> shadowIntrinsicID) {
IRBuilder<> IRB(&I);
assert(trailingVerbatimArgs < I.arg_size());
@@ -4187,8 +4192,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
ShadowArgs.push_back(Arg);
}
- CallInst *CI =
- IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(), ShadowArgs);
+ CallInst *CI = IRB.CreateIntrinsic(
+ I.getType(), shadowIntrinsicID.value_or(I.getIntrinsicID()),
+ ShadowArgs);
Value *CombinedShadow = CI;
// Combine the computed shadow with the shadow of trailing args
@@ -4664,7 +4670,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::aarch64_neon_tbx3:
case Intrinsic::aarch64_neon_tbx4: {
// The last trailing argument (index register) should be handled verbatim
- handleIntrinsicByApplyingToShadow(I, 1);
+ handleIntrinsicByApplyingToShadow(I, /*trailingVerbatimArgs*/ 1,
+ /*shadowIntrinsicID=*/std::nullopt);
break;
}
>From e15c1f19b4375e3e0a33a1179ae044fb0e58f14a Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Tue, 28 Jan 2025 20:32:43 +0000
Subject: [PATCH 2/2] Make shadowIntrinsicID mandatory
---
.../Instrumentation/MemorySanitizer.cpp | 22 ++++++++++---------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index d2d6a2391a686a..fadebc3ae42660 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -4050,7 +4050,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// To make shadow propagation precise, we want the equivalent of
// "horizontal OR", but this is not available.
return handleIntrinsicByApplyingToShadow(
- I, /*trailingVerbatimArgs*/ 0, /*shadowIntrinsicID=*/std::nullopt);
+ I, /*shadowIntrinsicID=*/I.getIntrinsicID(),
+ /*trailingVerbatimArgs*/ 0);
}
/// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
@@ -4157,7 +4158,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// shadow[out] =
/// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
///
- /// Optionally, the intrinsic for the shadow can be replaced with another
+ /// Typically, shadowIntrinsicID will be specified by the caller to be
+ /// I.getIntrinsicID(), but the caller can choose to replace it with another
/// intrinsic of the same type.
///
/// CAUTION: this assumes that the intrinsic will handle arbitrary
@@ -4168,9 +4170,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// (tbl{1,2,3,4}).
///
/// The origin is approximated using setOriginForNaryOp.
- void handleIntrinsicByApplyingToShadow(
- IntrinsicInst &I, unsigned int trailingVerbatimArgs,
- std::optional<Intrinsic::ID> shadowIntrinsicID) {
+ void handleIntrinsicByApplyingToShadow(IntrinsicInst &I,
+ Intrinsic::ID shadowIntrinsicID,
+ unsigned int trailingVerbatimArgs) {
IRBuilder<> IRB(&I);
assert(trailingVerbatimArgs < I.arg_size());
@@ -4192,9 +4194,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
ShadowArgs.push_back(Arg);
}
- CallInst *CI = IRB.CreateIntrinsic(
- I.getType(), shadowIntrinsicID.value_or(I.getIntrinsicID()),
- ShadowArgs);
+ CallInst *CI =
+ IRB.CreateIntrinsic(I.getType(), shadowIntrinsicID, ShadowArgs);
Value *CombinedShadow = CI;
// Combine the computed shadow with the shadow of trailing args
@@ -4670,8 +4671,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
case Intrinsic::aarch64_neon_tbx3:
case Intrinsic::aarch64_neon_tbx4: {
// The last trailing argument (index register) should be handled verbatim
- handleIntrinsicByApplyingToShadow(I, /*trailingVerbatimArgs*/ 1,
- /*shadowIntrinsicID=*/std::nullopt);
+ handleIntrinsicByApplyingToShadow(
+ I, /*shadowIntrinsicID=*/I.getIntrinsicID(),
+ /*trailingVerbatimArgs*/ 1);
break;
}
More information about the llvm-commits
mailing list