Skip to content

Commit 8289e7f

Browse files
committed
[msan] Handle x86_avx512_(min|max)_p[sd]_512 intrinsics
The AVX/SSE variants are already handled heuristically (maybeHandleSimpleNomemIntrinsic via handleUnknownIntrinsic), but the AVX512 variants contain an additional parameter (the rounding method) which fails to match heuristically. We generalize maybeHandleSimpleNomemIntrinsic to allow additional flags (ignored by MSan) and explicitly call it to handle AVX512 min/max ps/pd intrinsics.
1 parent 14b4417 commit 8289e7f

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,17 +2989,22 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
29892989

29902990
/// Handle (SIMD arithmetic)-like intrinsics.
29912991
///
2992-
/// Instrument intrinsics with any number of arguments of the same type,
2993-
/// equal to the return type. The type should be simple (no aggregates or
2994-
/// pointers; vectors are fine).
2992+
/// Instrument intrinsics with any number of arguments of the same type [*],
2993+
/// equal to the return type, plus a specified number of trailing flags of
2994+
/// any type.
2995+
///
2996+
/// [*} The type should be simple (no aggregates or pointers; vectors are
2997+
/// fine).
2998+
///
29952999
/// Caller guarantees that this intrinsic does not access memory.
2996-
bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) {
3000+
bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I, unsigned int trailingFlags) {
29973001
Type *RetTy = I.getType();
29983002
if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy()))
29993003
return false;
30003004

30013005
unsigned NumArgOperands = I.arg_size();
3002-
for (unsigned i = 0; i < NumArgOperands; ++i) {
3006+
assert(NumArgOperands >= trailingFlags);
3007+
for (unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
30033008
Type *Ty = I.getArgOperand(i)->getType();
30043009
if (Ty != RetTy)
30053010
return false;
@@ -3043,7 +3048,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
30433048
}
30443049

30453050
if (I.doesNotAccessMemory())
3046-
if (maybeHandleSimpleNomemIntrinsic(I))
3051+
if (maybeHandleSimpleNomemIntrinsic(I, /* trailingFlags */ 0))
30473052
return true;
30483053

30493054
// FIXME: detect and handle SSE maskstore/maskload
@@ -4466,6 +4471,20 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
44664471
break;
44674472
}
44684473

4474+
// Packed
4475+
case Intrinsic::x86_avx512_min_ps_512:
4476+
case Intrinsic::x86_avx512_min_pd_512:
4477+
case Intrinsic::x86_avx512_max_ps_512:
4478+
case Intrinsic::x86_avx512_max_pd_512: {
4479+
// These AVX512 variants contain the rounding mode as a trailing flag.
4480+
// Earlier variants do not have a trailing flag and are already handled
4481+
// by maybeHandleSimpleNomemIntrinsic(I, 0) via handleUnknownIntrinsic.
4482+
bool success = maybeHandleSimpleNomemIntrinsic(I, /* trailingFlags */ 1);
4483+
(void)success;
4484+
assert(success);
4485+
break;
4486+
}
4487+
44694488
case Intrinsic::fshl:
44704489
case Intrinsic::fshr:
44714490
handleFunnelShift(I);

0 commit comments

Comments
 (0)