Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 544c895

Browse files
committed
[msan] Fix vector pack intrinsic handling.
This fixes a crash on MMX intrinsics, as well as a corner case in handling of all unsigned pack intrinsics. PR19953. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210454 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6959336 commit 544c895

File tree

2 files changed

+95
-9
lines changed

2 files changed

+95
-9
lines changed

lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,24 +1928,82 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
19281928
setOriginForNaryOp(I);
19291929
}
19301930

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+
19311969
// \brief Instrument vector shift instrinsic.
19321970
//
19331971
// This function instruments intrinsics like x86_mmx_packsswb, that
19341972
// 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) {
19381977
assert(I.getNumArgOperands() == 2);
1978+
bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
19391979
IRBuilder<> IRB(&I);
19401980
Value *S1 = getShadow(&I, 0);
19411981
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+
}
19431992
Value *S1_ext = IRB.CreateSExt(
19441993
IRB.CreateICmpNE(S1, llvm::Constant::getNullValue(T)), T);
19451994
Value *S2_ext = IRB.CreateSExt(
19461995
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));
19492007
setShadow(&I, S);
19502008
setOriginForNaryOp(I);
19512009
}
@@ -2074,10 +2132,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
20742132
case llvm::Intrinsic::x86_avx2_packssdw:
20752133
case llvm::Intrinsic::x86_avx2_packuswb:
20762134
case llvm::Intrinsic::x86_avx2_packusdw:
2135+
handleVectorPackIntrinsic(I);
2136+
break;
2137+
20772138
case llvm::Intrinsic::x86_mmx_packsswb:
2078-
case llvm::Intrinsic::x86_mmx_packssdw:
20792139
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);
20812145
break;
20822146

20832147
default:

test/Instrumentation/MemorySanitizer/vector_pack.ll

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ target triple = "x86_64-unknown-linux-gnu"
55

66
declare <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32>, <4 x i32>) nounwind readnone
77
declare <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> %a, <16 x i16> %b) nounwind readnone
8+
declare x86_mmx @llvm.x86.mmx.packuswb(x86_mmx, x86_mmx) nounwind readnone
89

910
define <8 x i16> @Test_packssdw_128(<4 x i32> %a, <4 x i32> %b) sanitize_memory {
1011
entry:
@@ -33,6 +34,27 @@ entry:
3334
; CHECK-DAG: sext <16 x i1> {{.*}} to <16 x i16>
3435
; CHECK-DAG: icmp ne <16 x i16> {{.*}}, zeroinitializer
3536
; CHECK-DAG: sext <16 x i1> {{.*}} to <16 x i16>
36-
; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packuswb(
37+
; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packsswb(
3738
; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packuswb(
3839
; CHECK: ret <32 x i8>
40+
41+
42+
define x86_mmx @Test_mmx_packuswb(x86_mmx %a, x86_mmx %b) sanitize_memory {
43+
entry:
44+
%c = tail call x86_mmx @llvm.x86.mmx.packuswb(x86_mmx %a, x86_mmx %b) nounwind
45+
ret x86_mmx %c
46+
}
47+
48+
; CHECK-LABEL: @Test_mmx_packuswb(
49+
; CHECK-DAG: bitcast i64 {{.*}} to <4 x i16>
50+
; CHECK-DAG: bitcast i64 {{.*}} to <4 x i16>
51+
; CHECK-DAG: icmp ne <4 x i16> {{.*}}, zeroinitializer
52+
; CHECK-DAG: sext <4 x i1> {{.*}} to <4 x i16>
53+
; CHECK-DAG: icmp ne <4 x i16> {{.*}}, zeroinitializer
54+
; CHECK-DAG: sext <4 x i1> {{.*}} to <4 x i16>
55+
; CHECK-DAG: bitcast <4 x i16> {{.*}} to x86_mmx
56+
; CHECK-DAG: bitcast <4 x i16> {{.*}} to x86_mmx
57+
; CHECK-DAG: call x86_mmx @llvm.x86.mmx.packsswb({{.*}}
58+
; CHECK-DAG: bitcast x86_mmx {{.*}} to i64
59+
; CHECK-DAG: call x86_mmx @llvm.x86.mmx.packuswb({{.*}}
60+
; CHECK: ret x86_mmx

0 commit comments

Comments
 (0)