Skip to content

Commit 648e84c

Browse files
committed
Fork handlePairwiseShadowOrIntrinsic
1 parent fd03942 commit 648e84c

File tree

1 file changed

+61
-21
lines changed

1 file changed

+61
-21
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,25 +2607,69 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26072607
///
26082608
/// e.g., <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>)
26092609
/// <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>)
2610-
///
2611-
/// Optionally, reinterpret the parameters to have elements of a specified
2610+
void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I) {
2611+
assert(I.arg_size() == 1 || I.arg_size() == 2);
2612+
2613+
assert(I.getType()->isVectorTy());
2614+
assert(I.getArgOperand(0)->getType()->isVectorTy());
2615+
2616+
FixedVectorType *ParamType =
2617+
cast<FixedVectorType>(I.getArgOperand(0)->getType());
2618+
assert((I.arg_size() != 2) || (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
2619+
[[maybe_unused]] FixedVectorType *ReturnType =
2620+
cast<FixedVectorType>(I.getType());
2621+
assert(ParamType->getNumElements() * I.arg_size() ==
2622+
2 * ReturnType->getNumElements());
2623+
2624+
IRBuilder<> IRB(&I);
2625+
unsigned Width = ParamType->getNumElements() * I.arg_size();
2626+
2627+
// Horizontal OR of shadow
2628+
SmallVector<int, 8> EvenMask;
2629+
SmallVector<int, 8> OddMask;
2630+
for (unsigned X = 0; X < Width; X += 2) {
2631+
EvenMask.push_back(X);
2632+
OddMask.push_back(X + 1);
2633+
}
2634+
2635+
Value *FirstArgShadow = getShadow(&I, 0);
2636+
Value *EvenShadow;
2637+
Value *OddShadow;
2638+
if (I.arg_size() == 2) {
2639+
Value *SecondArgShadow = getShadow(&I, 1);
2640+
EvenShadow =
2641+
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, EvenMask);
2642+
OddShadow =
2643+
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, OddMask);
2644+
} else {
2645+
EvenShadow = IRB.CreateShuffleVector(FirstArgShadow, EvenMask);
2646+
OddShadow = IRB.CreateShuffleVector(FirstArgShadow, OddMask);
2647+
}
2648+
2649+
Value *OrShadow = IRB.CreateOr(EvenShadow, OddShadow);
2650+
OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
2651+
2652+
setShadow(&I, OrShadow);
2653+
setOriginForNaryOp(I);
2654+
}
2655+
2656+
/// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2657+
/// fields, with the parameters reinterpreted to have elements of a specified
26122658
/// width. For example:
26132659
/// @llvm.x86.ssse3.phadd.w(<1 x i64> [[VAR1]], <1 x i64> [[VAR2]])
26142660
/// conceptually operates on
26152661
/// (<4 x i16> [[VAR1]], <4 x i16> [[VAR2]])
26162662
/// and can be handled with ReinterpretElemWidth == 16.
26172663
void
2618-
handlePairwiseShadowOrIntrinsic(IntrinsicInst &I,
2619-
std::optional<int> ReinterpretElemWidth) {
2664+
handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, int ReinterpretElemWidth) {
26202665
assert(I.arg_size() == 1 || I.arg_size() == 2);
26212666

26222667
assert(I.getType()->isVectorTy());
26232668
assert(I.getArgOperand(0)->getType()->isVectorTy());
26242669

26252670
FixedVectorType *ParamType =
26262671
cast<FixedVectorType>(I.getArgOperand(0)->getType());
2627-
if (I.arg_size() == 2)
2628-
assert(I.getArgOperand(0)->getType() == I.getArgOperand(1)->getType());
2672+
assert((I.arg_size() != 2) || (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
26292673

26302674
[[maybe_unused]] FixedVectorType *ReturnType =
26312675
cast<FixedVectorType>(I.getType());
@@ -2636,14 +2680,12 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26362680

26372681
unsigned TotalNumElems = ParamType->getNumElements() * I.arg_size();
26382682
FixedVectorType *ReinterpretShadowTy = nullptr;
2639-
if (ReinterpretElemWidth.has_value()) {
2640-
assert(isAligned(Align(*ReinterpretElemWidth),
2641-
ParamType->getPrimitiveSizeInBits()));
2642-
ReinterpretShadowTy = FixedVectorType::get(
2643-
IRB.getIntNTy(*ReinterpretElemWidth),
2644-
ParamType->getPrimitiveSizeInBits() / *ReinterpretElemWidth);
2645-
TotalNumElems = ReinterpretShadowTy->getNumElements() * I.arg_size();
2646-
}
2683+
assert(isAligned(Align(ReinterpretElemWidth),
2684+
ParamType->getPrimitiveSizeInBits()));
2685+
ReinterpretShadowTy = FixedVectorType::get(
2686+
IRB.getIntNTy(ReinterpretElemWidth),
2687+
ParamType->getPrimitiveSizeInBits() / ReinterpretElemWidth);
2688+
TotalNumElems = ReinterpretShadowTy->getNumElements() * I.arg_size();
26472689

26482690
// Horizontal OR of shadow
26492691
SmallVector<int, 8> EvenMask;
@@ -2654,8 +2696,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26542696
}
26552697

26562698
Value *FirstArgShadow = getShadow(&I, 0);
2657-
if (ReinterpretShadowTy)
2658-
FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2699+
FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
26592700

26602701
// If we had two parameters each with an odd number of elements, the total
26612702
// number of elements is even, but we have never seen this in extant
@@ -2669,9 +2710,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26692710
Value *OddShadow;
26702711
if (I.arg_size() == 2) {
26712712
Value *SecondArgShadow = getShadow(&I, 1);
2672-
if (ReinterpretShadowTy)
2673-
SecondArgShadow =
2674-
IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2713+
SecondArgShadow =
2714+
IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
26752715

26762716
EvenShadow =
26772717
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, EvenMask);
@@ -4777,7 +4817,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
47774817
case Intrinsic::x86_sse3_hsub_pd:
47784818
case Intrinsic::x86_avx_hsub_pd_256:
47794819
case Intrinsic::x86_avx_hsub_ps_256: {
4780-
handlePairwiseShadowOrIntrinsic(I, /*ReinterpretElemWidth=*/std::nullopt);
4820+
handlePairwiseShadowOrIntrinsic(I);
47814821
break;
47824822
}
47834823

@@ -4837,7 +4877,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
48374877
// Add Long Pairwise
48384878
case Intrinsic::aarch64_neon_saddlp:
48394879
case Intrinsic::aarch64_neon_uaddlp: {
4840-
handlePairwiseShadowOrIntrinsic(I, std::nullopt);
4880+
handlePairwiseShadowOrIntrinsic(I);
48414881
break;
48424882
}
48434883

0 commit comments

Comments
 (0)