-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[msan] Add struct support to CreateShadowCast #130440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This fixes a TODO in CreateShadowCast, which could be useful for applying handleIntrinsicByApplyingToShadow to intrinsics that return a struct type. Note that getShadowTy already supports structs, hence struct support in CreateShadowCast is the last missing piece. Additionally, this adds assertions to prevent misuse of CreateShadowCast with floating-point types (which is not currently used, and was never fully supported).
|
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-transforms Author: Thurston Dang (thurstond) ChangesThis fixes a TODO in CreateShadowCast, which could be useful for applying handleIntrinsicByApplyingToShadow to intrinsics that return a struct type. Note that getShadowTy already supports structs, hence struct support in CreateShadowCast is the last missing piece. Additionally, this adds assertions to make it easier to know when CreateShadowCast is being used with unsupported types. Full diff: https://github.com/llvm/llvm-project/pull/130440.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index ba925275faba6..54e34bf9a0b85 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -2562,6 +2562,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
bool Signed = false) {
Type *srcTy = V->getType();
+
+ // Shadow types should never be floating-point.
+ assert(!srcTy->isFPOrFPVectorTy());
+ assert(!dstTy->isFPOrFPVectorTy());
+
+ // TODO (though never needed in practice)
+ assert(!srcTy->isArrayTy());
+ assert(!dstTy->isArrayTy());
+
if (srcTy == dstTy)
return V;
size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
@@ -2571,15 +2580,34 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
return IRB.CreateIntCast(V, dstTy, Signed);
+
if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
cast<VectorType>(dstTy)->getElementCount() ==
cast<VectorType>(srcTy)->getElementCount())
+ // We rely on the assertion at the start of the function that neither
+ // type is a floating-point vector.
return IRB.CreateIntCast(V, dstTy, Signed);
+
+ if (dstTy->isStructTy() && srcTy->isStructTy() &&
+ cast<StructType>(dstTy)->getNumElements() ==
+ cast<StructType>(srcTy)->getNumElements()) {
+ Value *DStruct = llvm::UndefValue::get(dstTy);
+
+ for (unsigned i = 0, n = cast<StructType>(dstTy)->getNumElements(); i < n;
+ i++) {
+ Value *Elem = IRB.CreateExtractValue(V, i);
+ Type *ElemDstTy = cast<StructType>(dstTy)->getElementType(i);
+ Value *ElemDst = CreateShadowCast(IRB, Elem, ElemDstTy, Signed);
+ DStruct = IRB.CreateInsertValue(DStruct, ElemDst, i);
+ }
+
+ return DStruct;
+ }
+
Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
Value *V2 =
IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
return IRB.CreateBitCast(V2, dstTy);
- // TODO: handle struct types.
}
/// Cast an application value to the type of its own shadow.
|
|
✅ With the latest revision this PR passed the undef deprecator. |
|
Do you have example PR where it's used? |
This fixes a TODO in CreateShadowCast, which could be useful for applying handleIntrinsicByApplyingToShadow to intrinsics that return a struct type. Note that getShadowTy already supports structs.
Additionally, this adds assertions to make it easier to know when CreateShadowCast is being used with unsupported types.