Skip to content

Commit c901f03

Browse files
committed
[msan] Add struct support to CreateShadowCast
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).
1 parent c628e8e commit c901f03

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2562,6 +2562,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
25622562
Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
25632563
bool Signed = false) {
25642564
Type *srcTy = V->getType();
2565+
2566+
// Shadow types should never be floating-point.
2567+
assert(!srcTy->isFPOrFPVectorTy());
2568+
assert(!dstTy->isFPOrFPVectorTy());
2569+
2570+
// TODO (though never needed in practice)
2571+
assert(!srcTy->isArrayTy());
2572+
assert(!dstTy->isArrayTy());
2573+
25652574
if (srcTy == dstTy)
25662575
return V;
25672576
size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
@@ -2571,15 +2580,34 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
25712580

25722581
if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
25732582
return IRB.CreateIntCast(V, dstTy, Signed);
2583+
25742584
if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
25752585
cast<VectorType>(dstTy)->getElementCount() ==
25762586
cast<VectorType>(srcTy)->getElementCount())
2587+
// We rely on the assertion at the start of the function that neither
2588+
// type is a floating-point vector.
25772589
return IRB.CreateIntCast(V, dstTy, Signed);
2590+
2591+
if (dstTy->isStructTy() && srcTy->isStructTy() &&
2592+
cast<StructType>(dstTy)->getNumElements() ==
2593+
cast<StructType>(srcTy)->getNumElements()) {
2594+
Value *DStruct = llvm::UndefValue::get(dstTy);
2595+
2596+
for (unsigned i = 0, n = cast<StructType>(dstTy)->getNumElements(); i < n;
2597+
i++) {
2598+
Value *Elem = IRB.CreateExtractValue(V, i);
2599+
Type *ElemDstTy = cast<StructType>(dstTy)->getElementType(i);
2600+
Value *ElemDst = CreateShadowCast(IRB, Elem, ElemDstTy, Signed);
2601+
DStruct = IRB.CreateInsertValue(DStruct, ElemDst, i);
2602+
}
2603+
2604+
return DStruct;
2605+
}
2606+
25782607
Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
25792608
Value *V2 =
25802609
IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
25812610
return IRB.CreateBitCast(V2, dstTy);
2582-
// TODO: handle struct types.
25832611
}
25842612

25852613
/// Cast an application value to the type of its own shadow.

0 commit comments

Comments
 (0)