Skip to content

Commit bbde3f6

Browse files
authored
[msan] Support vst1x_{2,3,4} and vst_{2,3,4} with floating-point parameters (#100644)
Cloning the vst_ intrinsics 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 adapting the corresponding intrinsic. This also updates the tests.
1 parent 6bd5fd3 commit bbde3f6

File tree

4 files changed

+235
-280
lines changed

4 files changed

+235
-280
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3873,11 +3873,18 @@ 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+
/// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
3883+
/// abcdabcdabcdabcd... into *outP
3884+
/// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
3885+
/// writes aaaa...bbbb...cccc...dddd... into *outP
3886+
/// These instructions can all be instrumented with essentially the same
3887+
/// MSan logic, simply by applying the corresponding intrinsic to the shadow.
38813888
void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
38823889
IRBuilder<> IRB(&I);
38833890

@@ -3892,11 +3899,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
38923899
if (ClCheckAccessAddress)
38933900
insertShadowCheck(Addr, &I);
38943901

3902+
SmallVector<Value *, 8> Shadows;
38953903
// Every arg operand, other than the last one, is an input vector
3896-
IntrinsicInst *ShadowI = cast<IntrinsicInst>(I.clone());
38973904
for (int i = 0; i < numArgOperands - 1; i++) {
38983905
assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
3899-
ShadowI->setArgOperand(i, getShadow(&I, i));
3906+
Value *Shadow = getShadow(&I, i);
3907+
Shadows.append(1, Shadow);
39003908
}
39013909

39023910
// MSan's GetShadowTy assumes the LHS is the type we want the shadow for
@@ -3914,13 +3922,20 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39143922
cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
39153923
cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
39163924
(numArgOperands - 1));
3917-
Type *ShadowTy = getShadowTy(OutputVectorTy);
3918-
Value *ShadowPtr, *OriginPtr;
3925+
Type *OutputShadowTy = getShadowTy(OutputVectorTy);
3926+
3927+
Value *OutputShadowPtr, *OutputOriginPtr;
39193928
// 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);
3929+
std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
3930+
Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
3931+
Shadows.append(1, OutputShadowPtr);
3932+
3933+
// CreateIntrinsic will select the correct (integer) type for the
3934+
// intrinsic; the original instruction I may have either integer- or
3935+
// float-type inputs.
3936+
CallInst *CI =
3937+
IRB.CreateIntrinsic(IRB.getVoidTy(), I.getIntrinsicID(), Shadows);
3938+
setShadow(&I, CI);
39243939

39253940
if (MS.TrackOrigins) {
39263941
// TODO: if we modelled the vst* instruction more precisely, we could
@@ -3932,7 +3947,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39323947
OC.Add(I.getArgOperand(i));
39333948

39343949
const DataLayout &DL = F.getDataLayout();
3935-
OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy), OriginPtr);
3950+
OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
3951+
OutputOriginPtr);
39363952
}
39373953
}
39383954

@@ -4277,6 +4293,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
42774293
setOrigin(&I, getCleanOrigin());
42784294
break;
42794295

4296+
case Intrinsic::aarch64_neon_st1x2:
4297+
case Intrinsic::aarch64_neon_st1x3:
4298+
case Intrinsic::aarch64_neon_st1x4:
42804299
case Intrinsic::aarch64_neon_st2:
42814300
case Intrinsic::aarch64_neon_st3:
42824301
case Intrinsic::aarch64_neon_st4: {

0 commit comments

Comments
 (0)