@@ -1928,24 +1928,82 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1928
1928
setOriginForNaryOp (I);
1929
1929
}
1930
1930
1931
+ // \brief Get an X86_MMX-sized vector type.
1932
+ Type *getMMXVectorTy (unsigned EltSizeInBits) {
1933
+ const unsigned X86_MMXSizeInBits = 64 ;
1934
+ return VectorType::get (IntegerType::get (*MS.C , EltSizeInBits),
1935
+ X86_MMXSizeInBits / EltSizeInBits);
1936
+ }
1937
+
1938
+ // \brief Returns a signed counterpart for an (un)signed-saturate-and-pack
1939
+ // intrinsic.
1940
+ Intrinsic::ID getSignedPackIntrinsic (Intrinsic::ID id) {
1941
+ switch (id) {
1942
+ case llvm::Intrinsic::x86_sse2_packsswb_128:
1943
+ case llvm::Intrinsic::x86_sse2_packuswb_128:
1944
+ return llvm::Intrinsic::x86_sse2_packsswb_128;
1945
+
1946
+ case llvm::Intrinsic::x86_sse2_packssdw_128:
1947
+ case llvm::Intrinsic::x86_sse41_packusdw:
1948
+ return llvm::Intrinsic::x86_sse2_packssdw_128;
1949
+
1950
+ case llvm::Intrinsic::x86_avx2_packsswb:
1951
+ case llvm::Intrinsic::x86_avx2_packuswb:
1952
+ return llvm::Intrinsic::x86_avx2_packsswb;
1953
+
1954
+ case llvm::Intrinsic::x86_avx2_packssdw:
1955
+ case llvm::Intrinsic::x86_avx2_packusdw:
1956
+ return llvm::Intrinsic::x86_avx2_packssdw;
1957
+
1958
+ case llvm::Intrinsic::x86_mmx_packsswb:
1959
+ case llvm::Intrinsic::x86_mmx_packuswb:
1960
+ return llvm::Intrinsic::x86_mmx_packsswb;
1961
+
1962
+ case llvm::Intrinsic::x86_mmx_packssdw:
1963
+ return llvm::Intrinsic::x86_mmx_packssdw;
1964
+ default :
1965
+ llvm_unreachable (" unexpected intrinsic id" );
1966
+ }
1967
+ }
1968
+
1931
1969
// \brief Instrument vector shift instrinsic.
1932
1970
//
1933
1971
// This function instruments intrinsics like x86_mmx_packsswb, that
1934
1972
// packs elements of 2 input vectors into half as much bits with saturation.
1935
- // Shadow is propagated with the same intrinsic applied to
1936
- // sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
1937
- void handleVectorPackIntrinsic (IntrinsicInst &I) {
1973
+ // Shadow is propagated with the signed variant of the same intrinsic applied
1974
+ // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
1975
+ // EltSizeInBits is used only for x86mmx arguments.
1976
+ void handleVectorPackIntrinsic (IntrinsicInst &I, unsigned EltSizeInBits = 0 ) {
1938
1977
assert (I.getNumArgOperands () == 2 );
1978
+ bool isX86_MMX = I.getOperand (0 )->getType ()->isX86_MMXTy ();
1939
1979
IRBuilder<> IRB (&I);
1940
1980
Value *S1 = getShadow (&I, 0 );
1941
1981
Value *S2 = getShadow (&I, 1 );
1942
- Type *T = S1->getType ();
1982
+ assert (isX86_MMX || S1->getType ()->isVectorTy ());
1983
+
1984
+ // SExt and ICmpNE below must apply to individual elements of input vectors.
1985
+ // In case of x86mmx arguments, cast them to appropriate vector types and
1986
+ // back.
1987
+ Type *T = isX86_MMX ? getMMXVectorTy (EltSizeInBits) : S1->getType ();
1988
+ if (isX86_MMX) {
1989
+ S1 = IRB.CreateBitCast (S1, T);
1990
+ S2 = IRB.CreateBitCast (S2, T);
1991
+ }
1943
1992
Value *S1_ext = IRB.CreateSExt (
1944
1993
IRB.CreateICmpNE (S1, llvm::Constant::getNullValue (T)), T);
1945
1994
Value *S2_ext = IRB.CreateSExt (
1946
1995
IRB.CreateICmpNE (S2, llvm::Constant::getNullValue (T)), T);
1947
- Value *S = IRB.CreateCall2 (I.getCalledValue (), S1_ext, S2_ext,
1948
- " _msprop_vector_pack" );
1996
+ if (isX86_MMX) {
1997
+ Type *X86_MMXTy = Type::getX86_MMXTy (*MS.C );
1998
+ S1_ext = IRB.CreateBitCast (S1_ext, X86_MMXTy);
1999
+ S2_ext = IRB.CreateBitCast (S2_ext, X86_MMXTy);
2000
+ }
2001
+
2002
+ Function *ShadowFn = Intrinsic::getDeclaration (
2003
+ F.getParent (), getSignedPackIntrinsic (I.getIntrinsicID ()));
2004
+
2005
+ Value *S = IRB.CreateCall2 (ShadowFn, S1_ext, S2_ext, " _msprop_vector_pack" );
2006
+ if (isX86_MMX) S = IRB.CreateBitCast (S, getShadowTy (&I));
1949
2007
setShadow (&I, S);
1950
2008
setOriginForNaryOp (I);
1951
2009
}
@@ -2074,10 +2132,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
2074
2132
case llvm::Intrinsic::x86_avx2_packssdw:
2075
2133
case llvm::Intrinsic::x86_avx2_packuswb:
2076
2134
case llvm::Intrinsic::x86_avx2_packusdw:
2135
+ handleVectorPackIntrinsic (I);
2136
+ break ;
2137
+
2077
2138
case llvm::Intrinsic::x86_mmx_packsswb:
2078
- case llvm::Intrinsic::x86_mmx_packssdw:
2079
2139
case llvm::Intrinsic::x86_mmx_packuswb:
2080
- handleVectorPackIntrinsic (I);
2140
+ handleVectorPackIntrinsic (I, 16 );
2141
+ break ;
2142
+
2143
+ case llvm::Intrinsic::x86_mmx_packssdw:
2144
+ handleVectorPackIntrinsic (I, 32 );
2081
2145
break ;
2082
2146
2083
2147
default :
0 commit comments