llvm.org GIT mirror llvm / a0d7719
[msan] Fix PR32842 It turned out that MSan was incorrectly calculating the shadow for int comparisons: it was done by truncating the result of (Shadow1 OR Shadow2) to i1, effectively rendering all bits except LSB useless. This approach doesn't work e.g. in the case where the values being compared are even (i.e. have the LSB of the shadow equal to zero). Instead, if CreateShadowCast() has to cast a bigger int to i1, we replace the truncation with an ICMP to 0. This patch doesn't affect the code generated for SPEC 2006 binaries, i.e. there's no performance impact. For the test case reported in PR32842 MSan with the patch generates a slightly more efficient code: orq %rcx, %rax jne .LBB0_6 , instead of: orl %ecx, %eax testb $1, %al jne .LBB0_6 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302787 91177308-0d34-0410-b5e6-96231b3b80d8 Alexander Potapenko 3 years ago
2 changed file(s) with 25 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
15751575 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
15761576 bool Signed = false) {
15771577 Type *srcTy = V->getType();
1578 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
1579 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
1580 if (srcSizeInBits > 1 && dstSizeInBits == 1)
1581 return IRB.CreateICmpNE(V, getCleanShadow(V));
1582
15781583 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
15791584 return IRB.CreateIntCast(V, dstTy, Signed);
15801585 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
15811586 dstTy->getVectorNumElements() == srcTy->getVectorNumElements())
15821587 return IRB.CreateIntCast(V, dstTy, Signed);
1583 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
1584 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
15851588 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
15861589 Value *V2 =
15871590 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
0 ; Regression test for https://bugs.llvm.org/show_bug.cgi?id=32842
1 ;
2 ; RUN: opt < %s -msan -S | FileCheck %s
3 ;target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
5
6 define zeroext i1 @_Z1fii(i32 %x, i32 %y) sanitize_memory {
7 entry:
8 %cmp = icmp slt i32 %x, %y
9 ret i1 %cmp
10 }
11
12 ; CHECK: [[X:[^ ]+]] = load{{.*}}__msan_param_tls{{.*}}
13 ; CHECK: [[Y:[^ ]+]] = load{{.*}}__msan_param_tls{{.*}}
14 ; CHECK: [[OR:[^ ]+]] = or i32 [[Y]], [[X]]
15
16 ; Make sure the shadow of the (x < y) comparison isn't truncated to i1.
17 ; CHECK-NOT: trunc i32 [[OR]] to i1
18 ; CHECK: [[CMP:[^ ]+]] = icmp ne i32 [[OR]], 0
19 ; CHECK: store i1 [[CMP]],{{.*}}__msan_retval_tls