Skip to content

Commit ef50227

Browse files
authored
[NFCI][msan] Refactor into 'horizontalReduce' (#152961)
The functionality is used by two helper functions, and will be used even more in the future (e.g., #152941).
1 parent e36bd61 commit ef50227

File tree

1 file changed

+60
-43
lines changed

1 file changed

+60
-43
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,6 +2690,54 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
26902690
SC.Done(&I);
26912691
}
26922692

2693+
// Perform a bitwise OR on the horizontal pairs (or other specified grouping)
2694+
// of elements.
2695+
//
2696+
// For example, suppose we have:
2697+
// VectorA: <a1, a2, a3, a4, a5, a6>
2698+
// VectorB: <b1, b2, b3, b4, b5, b6>
2699+
// ReductionFactor: 3.
2700+
// The output would be:
2701+
// <a1|a2|a3, a4|a5|a6, b1|b2|b3, b4|b5|b6>
2702+
//
2703+
// This is convenient for instrumenting horizontal add/sub.
2704+
// For bitwise OR on "vertical" pairs, see maybeHandleSimpleNomemIntrinsic().
2705+
Value *horizontalReduce(IntrinsicInst &I, unsigned ReductionFactor,
2706+
Value *VectorA, Value *VectorB) {
2707+
assert(isa<FixedVectorType>(VectorA->getType()));
2708+
unsigned TotalNumElems =
2709+
cast<FixedVectorType>(VectorA->getType())->getNumElements();
2710+
2711+
if (VectorB) {
2712+
assert(VectorA->getType() == VectorB->getType());
2713+
TotalNumElems = TotalNumElems * 2;
2714+
}
2715+
2716+
assert(TotalNumElems % ReductionFactor == 0);
2717+
2718+
Value *Or = nullptr;
2719+
2720+
IRBuilder<> IRB(&I);
2721+
for (unsigned i = 0; i < ReductionFactor; i++) {
2722+
SmallVector<int, 16> Mask;
2723+
for (unsigned X = 0; X < TotalNumElems; X += ReductionFactor)
2724+
Mask.push_back(X + i);
2725+
2726+
Value *Masked;
2727+
if (VectorB)
2728+
Masked = IRB.CreateShuffleVector(VectorA, VectorB, Mask);
2729+
else
2730+
Masked = IRB.CreateShuffleVector(VectorA, Mask);
2731+
2732+
if (Or)
2733+
Or = IRB.CreateOr(Or, Masked);
2734+
else
2735+
Or = Masked;
2736+
}
2737+
2738+
return Or;
2739+
}
2740+
26932741
/// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
26942742
/// fields.
26952743
///
@@ -2711,31 +2759,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27112759
2 * ReturnType->getNumElements());
27122760

27132761
IRBuilder<> IRB(&I);
2714-
unsigned Width = ParamType->getNumElements() * I.arg_size();
27152762

27162763
// Horizontal OR of shadow
2717-
SmallVector<int, 8> EvenMask;
2718-
SmallVector<int, 8> OddMask;
2719-
for (unsigned X = 0; X < Width; X += 2) {
2720-
EvenMask.push_back(X);
2721-
OddMask.push_back(X + 1);
2722-
}
2723-
27242764
Value *FirstArgShadow = getShadow(&I, 0);
2725-
Value *EvenShadow;
2726-
Value *OddShadow;
2727-
if (I.arg_size() == 2) {
2728-
Value *SecondArgShadow = getShadow(&I, 1);
2729-
EvenShadow =
2730-
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, EvenMask);
2731-
OddShadow =
2732-
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, OddMask);
2733-
} else {
2734-
EvenShadow = IRB.CreateShuffleVector(FirstArgShadow, EvenMask);
2735-
OddShadow = IRB.CreateShuffleVector(FirstArgShadow, OddMask);
2736-
}
2765+
Value *SecondArgShadow = nullptr;
2766+
if (I.arg_size() == 2)
2767+
SecondArgShadow = getShadow(&I, 1);
2768+
2769+
Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, FirstArgShadow,
2770+
SecondArgShadow);
27372771

2738-
Value *OrShadow = IRB.CreateOr(EvenShadow, OddShadow);
27392772
OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
27402773

27412774
setShadow(&I, OrShadow);
@@ -2768,23 +2801,14 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27682801

27692802
IRBuilder<> IRB(&I);
27702803

2771-
unsigned TotalNumElems = ParamType->getNumElements() * I.arg_size();
27722804
FixedVectorType *ReinterpretShadowTy = nullptr;
27732805
assert(isAligned(Align(ReinterpretElemWidth),
27742806
ParamType->getPrimitiveSizeInBits()));
27752807
ReinterpretShadowTy = FixedVectorType::get(
27762808
IRB.getIntNTy(ReinterpretElemWidth),
27772809
ParamType->getPrimitiveSizeInBits() / ReinterpretElemWidth);
2778-
TotalNumElems = ReinterpretShadowTy->getNumElements() * I.arg_size();
27792810

27802811
// Horizontal OR of shadow
2781-
SmallVector<int, 8> EvenMask;
2782-
SmallVector<int, 8> OddMask;
2783-
for (unsigned X = 0; X < TotalNumElems - 1; X += 2) {
2784-
EvenMask.push_back(X);
2785-
OddMask.push_back(X + 1);
2786-
}
2787-
27882812
Value *FirstArgShadow = getShadow(&I, 0);
27892813
FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
27902814

@@ -2796,22 +2820,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
27962820
Align(2),
27972821
cast<FixedVectorType>(FirstArgShadow->getType())->getNumElements()));
27982822

2799-
Value *EvenShadow;
2800-
Value *OddShadow;
2823+
Value *SecondArgShadow = nullptr;
28012824
if (I.arg_size() == 2) {
2802-
Value *SecondArgShadow = getShadow(&I, 1);
2825+
SecondArgShadow = getShadow(&I, 1);
28032826
SecondArgShadow = IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2804-
2805-
EvenShadow =
2806-
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, EvenMask);
2807-
OddShadow =
2808-
IRB.CreateShuffleVector(FirstArgShadow, SecondArgShadow, OddMask);
2809-
} else {
2810-
EvenShadow = IRB.CreateShuffleVector(FirstArgShadow, EvenMask);
2811-
OddShadow = IRB.CreateShuffleVector(FirstArgShadow, OddMask);
28122827
}
28132828

2814-
Value *OrShadow = IRB.CreateOr(EvenShadow, OddShadow);
2829+
Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, FirstArgShadow,
2830+
SecondArgShadow);
2831+
28152832
OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
28162833

28172834
setShadow(&I, OrShadow);
@@ -3219,7 +3236,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
32193236
/// Caller guarantees that this intrinsic does not access memory.
32203237
///
32213238
/// TODO: "horizontal"/"pairwise" intrinsics are often incorrectly matched by
3222-
/// by this handler.
3239+
/// by this handler. See horizontalReduce().
32233240
[[maybe_unused]] bool
32243241
maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I,
32253242
unsigned int trailingFlags) {

0 commit comments

Comments
 (0)