[llvm] r267966 - [msan] Handle vector compare x86 intrinsics.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 28 18:19:53 PDT 2016
Author: eugenis
Date: Thu Apr 28 20:19:52 2016
New Revision: 267966
URL: http://llvm.org/viewvc/llvm-project?rev=267966&view=rev
Log:
[msan] Handle vector compare x86 intrinsics.
This handles SSE and SSE2 cmp_* and comiXX_* intrinsics.
Modified:
llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=267966&r1=267965&r2=267966&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Thu Apr 28 20:19:52 2016
@@ -2134,6 +2134,14 @@ struct MemorySanitizerVisitor : public I
return CreateShadowCast(IRB, S2, T, /* Signed */ true);
}
+ // Given a vector, extract its first element, and return all
+ // zeroes if it is zero, and all ones otherwise.
+ Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
+ Value *S1 = IRB.CreateExtractElement(S, (int)0);
+ Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
+ return CreateShadowCast(IRB, S2, T, /* Signed */ true);
+ }
+
Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
Type *T = S->getType();
assert(T->isVectorTy());
@@ -2281,6 +2289,30 @@ struct MemorySanitizerVisitor : public I
setOriginForNaryOp(I);
}
+ // \brief Instrument compare-packed intrinsic.
+ // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
+ // all-ones shadow.
+ void handleVectorComparePackedIntrinsic(IntrinsicInst &I) {
+ IRBuilder<> IRB(&I);
+ Type *ResTy = getShadowTy(&I);
+ Value *S0 = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
+ Value *S = IRB.CreateSExt(
+ IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
+ setShadow(&I, S);
+ setOriginForNaryOp(I);
+ }
+
+ // \brief Instrument compare-scalar intrinsic.
+ // This handles both cmp* intrinsics which return the result in the first
+ // element of a vector, and comi* which return the result as i32.
+ void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
+ IRBuilder<> IRB(&I);
+ Value *S0 = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
+ Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
+ setShadow(&I, S);
+ setOriginForNaryOp(I);
+ }
+
void visitIntrinsicInst(IntrinsicInst &I) {
switch (I.getIntrinsicID()) {
case llvm::Intrinsic::bswap:
@@ -2424,6 +2456,43 @@ struct MemorySanitizerVisitor : public I
handleVectorPmaddIntrinsic(I, 16);
break;
+ case llvm::Intrinsic::x86_sse_cmp_ss:
+ case llvm::Intrinsic::x86_sse2_cmp_sd:
+ case llvm::Intrinsic::x86_sse_comieq_ss:
+ case llvm::Intrinsic::x86_sse_comilt_ss:
+ case llvm::Intrinsic::x86_sse_comile_ss:
+ case llvm::Intrinsic::x86_sse_comigt_ss:
+ case llvm::Intrinsic::x86_sse_comige_ss:
+ case llvm::Intrinsic::x86_sse_comineq_ss:
+ case llvm::Intrinsic::x86_sse_ucomieq_ss:
+ case llvm::Intrinsic::x86_sse_ucomilt_ss:
+ case llvm::Intrinsic::x86_sse_ucomile_ss:
+ case llvm::Intrinsic::x86_sse_ucomigt_ss:
+ case llvm::Intrinsic::x86_sse_ucomige_ss:
+ case llvm::Intrinsic::x86_sse_ucomineq_ss:
+ case llvm::Intrinsic::x86_sse2_comieq_sd:
+ case llvm::Intrinsic::x86_sse2_comilt_sd:
+ case llvm::Intrinsic::x86_sse2_comile_sd:
+ case llvm::Intrinsic::x86_sse2_comigt_sd:
+ case llvm::Intrinsic::x86_sse2_comige_sd:
+ case llvm::Intrinsic::x86_sse2_comineq_sd:
+ case llvm::Intrinsic::x86_sse2_ucomieq_sd:
+ case llvm::Intrinsic::x86_sse2_ucomilt_sd:
+ case llvm::Intrinsic::x86_sse2_ucomile_sd:
+ case llvm::Intrinsic::x86_sse2_ucomigt_sd:
+ case llvm::Intrinsic::x86_sse2_ucomige_sd:
+ case llvm::Intrinsic::x86_sse2_ucomineq_sd:
+ handleVectorCompareScalarIntrinsic(I);
+ break;
+
+ case llvm::Intrinsic::x86_sse_cmp_ps:
+ case llvm::Intrinsic::x86_sse2_cmp_pd:
+ // FIXME: For x86_avx_cmp_pd_256 and x86_avx_cmp_ps_256 this function
+ // generates reasonably looking IR that fails in the backend with "Do not
+ // know how to split the result of this operator!".
+ handleVectorComparePackedIntrinsic(I);
+ break;
+
default:
if (!handleUnknownIntrinsic(I))
visitInstruction(I);
More information about the llvm-commits
mailing list