llvm.org GIT mirror llvm / 544c895
[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 Evgeniy Stepanov 5 years ago
2 changed file(s) with 95 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
19271927 setOriginForNaryOp(I);
19281928 }
19291929
1930 // \brief Get an X86_MMX-sized vector type.
1931 Type *getMMXVectorTy(unsigned EltSizeInBits) {
1932 const unsigned X86_MMXSizeInBits = 64;
1933 return VectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
1934 X86_MMXSizeInBits / EltSizeInBits);
1935 }
1936
1937 // \brief Returns a signed counterpart for an (un)signed-saturate-and-pack
1938 // intrinsic.
1939 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
1940 switch (id) {
1941 case llvm::Intrinsic::x86_sse2_packsswb_128:
1942 case llvm::Intrinsic::x86_sse2_packuswb_128:
1943 return llvm::Intrinsic::x86_sse2_packsswb_128;
1944
1945 case llvm::Intrinsic::x86_sse2_packssdw_128:
1946 case llvm::Intrinsic::x86_sse41_packusdw:
1947 return llvm::Intrinsic::x86_sse2_packssdw_128;
1948
1949 case llvm::Intrinsic::x86_avx2_packsswb:
1950 case llvm::Intrinsic::x86_avx2_packuswb:
1951 return llvm::Intrinsic::x86_avx2_packsswb;
1952
1953 case llvm::Intrinsic::x86_avx2_packssdw:
1954 case llvm::Intrinsic::x86_avx2_packusdw:
1955 return llvm::Intrinsic::x86_avx2_packssdw;
1956
1957 case llvm::Intrinsic::x86_mmx_packsswb:
1958 case llvm::Intrinsic::x86_mmx_packuswb:
1959 return llvm::Intrinsic::x86_mmx_packsswb;
1960
1961 case llvm::Intrinsic::x86_mmx_packssdw:
1962 return llvm::Intrinsic::x86_mmx_packssdw;
1963 default:
1964 llvm_unreachable("unexpected intrinsic id");
1965 }
1966 }
1967
19301968 // \brief Instrument vector shift instrinsic.
19311969 //
19321970 // This function instruments intrinsics like x86_mmx_packsswb, that
19331971 // packs elements of 2 input vectors into half as much bits with saturation.
1934 // Shadow is propagated with the same intrinsic applied to
1935 // sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
1936 void handleVectorPackIntrinsic(IntrinsicInst &I) {
1972 // Shadow is propagated with the signed variant of the same intrinsic applied
1973 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
1974 // EltSizeInBits is used only for x86mmx arguments.
1975 void handleVectorPackIntrinsic(IntrinsicInst &I, unsigned EltSizeInBits = 0) {
19371976 assert(I.getNumArgOperands() == 2);
1977 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
19381978 IRBuilder<> IRB(&I);
19391979 Value *S1 = getShadow(&I, 0);
19401980 Value *S2 = getShadow(&I, 1);
1941 Type *T = S1->getType();
1981 assert(isX86_MMX || S1->getType()->isVectorTy());
1982
1983 // SExt and ICmpNE below must apply to individual elements of input vectors.
1984 // In case of x86mmx arguments, cast them to appropriate vector types and
1985 // back.
1986 Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->getType();
1987 if (isX86_MMX) {
1988 S1 = IRB.CreateBitCast(S1, T);
1989 S2 = IRB.CreateBitCast(S2, T);
1990 }
19421991 Value *S1_ext = IRB.CreateSExt(
19431992 IRB.CreateICmpNE(S1, llvm::Constant::getNullValue(T)), T);
19441993 Value *S2_ext = IRB.CreateSExt(
19451994 IRB.CreateICmpNE(S2, llvm::Constant::getNullValue(T)), T);
1946 Value *S = IRB.CreateCall2(I.getCalledValue(), S1_ext, S2_ext,
1947 "_msprop_vector_pack");
1995 if (isX86_MMX) {
1996 Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C);
1997 S1_ext = IRB.CreateBitCast(S1_ext, X86_MMXTy);
1998 S2_ext = IRB.CreateBitCast(S2_ext, X86_MMXTy);
1999 }
2000
2001 Function *ShadowFn = Intrinsic::getDeclaration(
2002 F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID()));
2003
2004 Value *S = IRB.CreateCall2(ShadowFn, S1_ext, S2_ext, "_msprop_vector_pack");
2005 if (isX86_MMX) S = IRB.CreateBitCast(S, getShadowTy(&I));
19482006 setShadow(&I, S);
19492007 setOriginForNaryOp(I);
19502008 }
20732131 case llvm::Intrinsic::x86_avx2_packssdw:
20742132 case llvm::Intrinsic::x86_avx2_packuswb:
20752133 case llvm::Intrinsic::x86_avx2_packusdw:
2134 handleVectorPackIntrinsic(I);
2135 break;
2136
20762137 case llvm::Intrinsic::x86_mmx_packsswb:
2138 case llvm::Intrinsic::x86_mmx_packuswb:
2139 handleVectorPackIntrinsic(I, 16);
2140 break;
2141
20772142 case llvm::Intrinsic::x86_mmx_packssdw:
2078 case llvm::Intrinsic::x86_mmx_packuswb:
2079 handleVectorPackIntrinsic(I);
2143 handleVectorPackIntrinsic(I, 32);
20802144 break;
20812145
20822146 default:
44
55 declare <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32>, <4 x i32>) nounwind readnone
66 declare <32 x i8> @llvm.x86.avx2.packuswb(<16 x i16> %a, <16 x i16> %b) nounwind readnone
7 declare x86_mmx @llvm.x86.mmx.packuswb(x86_mmx, x86_mmx) nounwind readnone
78
89 define <8 x i16> @Test_packssdw_128(<4 x i32> %a, <4 x i32> %b) sanitize_memory {
910 entry:
3233 ; CHECK-DAG: sext <16 x i1> {{.*}} to <16 x i16>
3334 ; CHECK-DAG: icmp ne <16 x i16> {{.*}}, zeroinitializer
3435 ; CHECK-DAG: sext <16 x i1> {{.*}} to <16 x i16>
35 ; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packuswb(
36 ; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packsswb(
3637 ; CHECK-DAG: call <32 x i8> @llvm.x86.avx2.packuswb(
3738 ; CHECK: ret <32 x i8>
39
40
41 define x86_mmx @Test_mmx_packuswb(x86_mmx %a, x86_mmx %b) sanitize_memory {
42 entry:
43 %c = tail call x86_mmx @llvm.x86.mmx.packuswb(x86_mmx %a, x86_mmx %b) nounwind
44 ret x86_mmx %c
45 }
46
47 ; CHECK-LABEL: @Test_mmx_packuswb(
48 ; CHECK-DAG: bitcast i64 {{.*}} to <4 x i16>
49 ; CHECK-DAG: bitcast i64 {{.*}} to <4 x i16>
50 ; CHECK-DAG: icmp ne <4 x i16> {{.*}}, zeroinitializer
51 ; CHECK-DAG: sext <4 x i1> {{.*}} to <4 x i16>
52 ; CHECK-DAG: icmp ne <4 x i16> {{.*}}, zeroinitializer
53 ; CHECK-DAG: sext <4 x i1> {{.*}} to <4 x i16>
54 ; CHECK-DAG: bitcast <4 x i16> {{.*}} to x86_mmx
55 ; CHECK-DAG: bitcast <4 x i16> {{.*}} to x86_mmx
56 ; CHECK-DAG: call x86_mmx @llvm.x86.mmx.packsswb({{.*}}
57 ; CHECK-DAG: bitcast x86_mmx {{.*}} to i64
58 ; CHECK-DAG: call x86_mmx @llvm.x86.mmx.packuswb({{.*}}
59 ; CHECK: ret x86_mmx