Skip to content

Commit ae1cc1b

Browse files
committed
[msan] Support vst1x_{2,3,4} and vst_{2,3,4} with floating-point parameters
Cloning the vst_ functions to apply them to the shadows did not work if the arguments were floating-point, since the shadows are integers. This patch changes MSan to create an intrinsic of the correct integer types. Additionally, this patch adds support for vst1x_{2,3,4}; these can be handled similarly to vst_{2,3,4}, since in all cases we are cloning/adapting the corresponding function. This also updates and enables the test introduced in llvm#100189
1 parent db8c84f commit ae1cc1b

File tree

2 files changed

+158
-205
lines changed

2 files changed

+158
-205
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3873,11 +3873,17 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
38733873
setOriginForNaryOp(I);
38743874
}
38753875

3876-
/// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
3876+
/// Handle Arm NEON vector store intrinsics (vst{2,3,4} and vst1x_{2,3,4}).
38773877
///
38783878
/// Arm NEON vector store intrinsics have the output address (pointer) as the
38793879
/// last argument, with the initial arguments being the inputs. They return
38803880
/// void.
3881+
///
3882+
/// The difference between st1_x4 and st4 is that the latter interleaves the
3883+
/// output e.g., st4 (A, B, C, D, P) writes abcdabcdabcdabcd... into *P, while
3884+
/// st1_x4 (A, B, C, D, P) writes aaaa...bbbb...cccc...dddd... into *P.
3885+
/// Since we apply the cloned instruction to the shadow, we can reuse the same
3886+
/// logic.
38813887
void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
38823888
IRBuilder<> IRB(&I);
38833889

@@ -3892,11 +3898,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
38923898
if (ClCheckAccessAddress)
38933899
insertShadowCheck(Addr, &I);
38943900

3901+
SmallVector<Value *, 8> Shadows;
38953902
// Every arg operand, other than the last one, is an input vector
3896-
IntrinsicInst *ShadowI = cast<IntrinsicInst>(I.clone());
38973903
for (int i = 0; i < numArgOperands - 1; i++) {
38983904
assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
3899-
ShadowI->setArgOperand(i, getShadow(&I, i));
3905+
Value *Shadow = getShadow(&I, i);
3906+
Shadows.append(1, Shadow);
39003907
}
39013908

39023909
// MSan's GetShadowTy assumes the LHS is the type we want the shadow for
@@ -3914,13 +3921,17 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39143921
cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
39153922
cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
39163923
(numArgOperands - 1));
3917-
Type *ShadowTy = getShadowTy(OutputVectorTy);
3918-
Value *ShadowPtr, *OriginPtr;
3924+
Type *OutputShadowTy = getShadowTy(OutputVectorTy);
3925+
3926+
Value *OutputShadowPtr, *OutputOriginPtr;
39193927
// AArch64 NEON does not need alignment (unless OS requires it)
3920-
std::tie(ShadowPtr, OriginPtr) =
3921-
getShadowOriginPtr(Addr, IRB, ShadowTy, Align(1), /*isStore*/ true);
3922-
ShadowI->setArgOperand(numArgOperands - 1, ShadowPtr);
3923-
ShadowI->insertAfter(&I);
3928+
std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
3929+
Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
3930+
Shadows.append(1, OutputShadowPtr);
3931+
3932+
CallInst *CI =
3933+
IRB.CreateIntrinsic(IRB.getVoidTy(), I.getIntrinsicID(), Shadows);
3934+
setShadow(&I, CI);
39243935

39253936
if (MS.TrackOrigins) {
39263937
// TODO: if we modelled the vst* instruction more precisely, we could
@@ -3932,7 +3943,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39323943
OC.Add(I.getArgOperand(i));
39333944

39343945
const DataLayout &DL = F.getDataLayout();
3935-
OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy), OriginPtr);
3946+
OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
3947+
OutputOriginPtr);
39363948
}
39373949
}
39383950

@@ -4277,6 +4289,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
42774289
setOrigin(&I, getCleanOrigin());
42784290
break;
42794291

4292+
case Intrinsic::aarch64_neon_st1x2:
4293+
case Intrinsic::aarch64_neon_st1x3:
4294+
case Intrinsic::aarch64_neon_st1x4:
42804295
case Intrinsic::aarch64_neon_st2:
42814296
case Intrinsic::aarch64_neon_st3:
42824297
case Intrinsic::aarch64_neon_st4: {

0 commit comments

Comments
 (0)