Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4769,6 +4769,78 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOriginForNaryOp(I);
}

// Approximately handle AVX Galois Field Affine Transformation
//
// e.g.,
// <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
// <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8>, <32 x i8>, i8)
// <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8>, <64 x i8>, i8)
// Out A x b
// where Out = A * x + b in GF(2) (N.B. Out, A and x are packed)
//
// Multiplication in GF(2) is equivalent to bitwise AND. However, the matrix
// computation also includes a parity calculation.
//
// For the bitwise AND of bits V1 and V2, the exact shadow is:
// Out_Shadow = (V1_Shadow & V2_Shadow)
// | (V1 & V2_Shadow)
// | (V1_Shadow & V2_Shadow)
//
// We approximate the shadow of gf2p8affineqb using:
// Out_Shadow = gf2p8affineqb(x_Shadow, A_shadow, 0)
// | gf2p8affineqb(x, A_shadow, 0)
// | gf2p8affineqb(x_Shadow, A, 0)
// | set1_epi8(b_Shadow)
//
// This approximation has false negatives: if an intermediate dot-product
// contains an even number of 1's, the parity is 0.
// It has no false positives.
void handleAVXGF2P8Affine(IntrinsicInst &I) {
IRBuilder<> IRB(&I);

assert(I.arg_size() == 3);
Value *A = I.getOperand(0);
Value *x = I.getOperand(1);
Value *b = I.getOperand(2);

assert(isFixedIntVector(A));
assert(cast<VectorType>(A->getType())
->getElementType()
->getScalarSizeInBits() == 8);

assert(A->getType() == x->getType());

assert(b->getType()->isIntegerTy());
assert(b->getType()->getScalarSizeInBits() == 8);

assert(I.getType() == A->getType());

Value *AShadow = getShadow(A);
Value *xShadow = getShadow(x);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: variable naming

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalized to X (formerly known as Twitter).

Value *bZeroShadow = getCleanShadow(b);

CallInst *xShadowAShadow = IRB.CreateIntrinsic(
I.getType(), I.getIntrinsicID(), {xShadow, AShadow, bZeroShadow});
CallInst *xAShadow = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
{x, AShadow, bZeroShadow});
CallInst *xShadowA = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
{xShadow, A, bZeroShadow});

unsigned NumElements = cast<FixedVectorType>(I.getType())->getNumElements();
Value *bShadow = getShadow(b);
Value *bBroadcastShadow = getCleanShadow(AShadow);
// There is no LLVM IR intrinsic for _mm512_set1_epi8.
// This loop generates a lot of LLVM IR, which we expect that CodeGen will
// lower appropriately (e.g., VPBROADCASTB).
// Besides, b is often a constant, in which case it is fully initialized.
for (unsigned i = 0; i < NumElements; i++)
bBroadcastShadow = IRB.CreateInsertElement(bBroadcastShadow, bShadow, i);

setShadow(&I, IRB.CreateOr(
{xShadowAShadow, xAShadow, xShadowA, bBroadcastShadow}));
setOriginForNaryOp(I);
}

// Handle Arm NEON vector load intrinsics (vld*).
//
// The WithLane instructions (ld[234]lane) are similar to:
Expand Down Expand Up @@ -5604,6 +5676,14 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
break;
}

// AVX Galois Field New Instructions
case Intrinsic::x86_vgf2p8affineqb_128:
case Intrinsic::x86_vgf2p8affineqb_256:
case Intrinsic::x86_vgf2p8affineqb_512: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unnecessary braces

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

handleAVXGF2P8Affine(I);
break;
}

case Intrinsic::fshl:
case Intrinsic::fshr:
handleFunnelShift(I);
Expand Down
Loading