diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2012-11-29 14:25:47 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2012-11-29 14:25:47 +0000 |
| commit | 857d9d2a59cdbd9038b14a3d1a682a295cf57b6b (patch) | |
| tree | abb896c5e6fe7aea92ee7cdaed3612fe7e4380dc /llvm/lib/Transforms | |
| parent | eeb8b7c391d6d770f787da7da97b0fcd87945c0c (diff) | |
| download | bcm5719-llvm-857d9d2a59cdbd9038b14a3d1a682a295cf57b6b.tar.gz bcm5719-llvm-857d9d2a59cdbd9038b14a3d1a682a295cf57b6b.zip | |
[msan] Propagate shadow through (x<0) and (x>=0) comparisons.
This is a special case of signed relational comparison where result
only depends on the sign of x.
llvm-svn: 168881
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 30652378bf7..46d22aacf95 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -949,9 +949,39 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { setOriginForNaryOp(I); } + /// \brief Instrument signed relational comparisons. + /// + /// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by + /// propagating the highest bit of the shadow. Everything else is delegated + /// to handleShadowOr(). + void handleSignedRelationalComparison(ICmpInst &I) { + Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0)); + Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1)); + Value* op = NULL; + CmpInst::Predicate pre = I.getPredicate(); + if (constOp0 && constOp0->isNullValue() && + (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE)) { + op = I.getOperand(1); + } else if (constOp1 && constOp1->isNullValue() && + (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) { + op = I.getOperand(0); + } + if (op) { + IRBuilder<> IRB(&I); + Value* Shadow = + IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op), "_msprop_icmpslt"); + setShadow(&I, Shadow); + setOrigin(&I, getOrigin(op)); + } else { + handleShadowOr(I); + } + } + void visitICmpInst(ICmpInst &I) { if (ClHandleICmp && I.isEquality()) handleEqualityComparison(I); + else if (ClHandleICmp && I.isSigned() && I.isRelational()) + handleSignedRelationalComparison(I); else handleShadowOr(I); } |

